1.面向对象编程
特点:封装、继承、多态(、抽象)
(1)类
类是创建对象的模板。
2.预定义类
Java提前定义好的类
(1)构造器Constructor
构造器就是构造方法,构造方法是在new 的时候调用的。
构造器分为无参构造和有参构造器。
(2)LocalDate方法
(3)访问器和更改器(getter&&setter)
公开的时候
java
Public int age;
Person p1=new Person();
P1.age=10;
私有的时候
java
Private int age;
外边访问不到,需要提供方法返回值的形式来获取值或更改值
java
public int run(){
return age;
}
public void jump(int num){
age=num;
}
只有上边的方法只能读,只有下边的方法只能写,所以要两个都有才能实现读写。
如果我们直接进行.属性来赋值会导致一些不合理性,比如.age=-10可以实现,但是并不合理。就可以在setter方法里来添加判断逻辑来限制更改。
引用类型数据
java
private int[] flag={1,2,3,4,5};
public int[] getFlag(){
return flag;
}
因为引用类型数据flag存的是地址,所以getFlag返回flag使得地址暴露了,不需要提供set方法就可以进行更改,也就不安全了。
所以对于引用类型数据直接浅拷贝地址不合适,我们改用深拷贝。
java
Public int[] getFlag(){
Int[] arr=new int[flag.length];
for(int i=0;i<flag.length;i++){
Arr[i]=flag[i];
}
return arr;
}
此时返回的时候拿到的是新创建的数组地址,保证了被拷贝数组的安全性。
**Private String name;**是安全的,因为不可变字符串,改的话只能修改指向,而不可以改变字符串的内容,对外暴露name的地址没有影响。
数据私有化,提供get set方法,按照这种思想定义的类就是Java bean类
3.用户自定义类
(1)this
this代之当前对象 ,可以指向属性、方法、构造器
this()只能在第一行 ,表示调用构造器
相似的super代指的是父类,和this的用法没区别,super.属性表示父类属性,super.方法()表示调用父类方法
Super()和this()不能同时存在
(2)封装
只研究如何去调用方法,不用研究方法的具体实现
(3)Final实例域
被final修饰的变量叫做常量,赋值后不可修改、提供getset方法也不可以。
对于被final修饰的引用类型来说,比如数组arr,不可以修改指向,但是可以更改数组的元素。
4.静态域与静态方法
有static修饰的属性属于静态属性,所有对象共享static属性的值,没有static修饰的属性创建多少个对象就有多少不同的属性。
被static修饰的方法属于静态方法,直接用**类名.方法名()**来调用就可以。
对于静态属性来说进入内存就可以直接加载,所以静态方法中可以直接访问静态属性,而不可以直接访问非静态属性,后者只能通过new 对象的方法来实现。
·工厂方法
一种设计思想。
·Main方法
Main方法不对任何对象进行操作。在启动程序还没有任何一个对象。静态的main方法将执行并创建程序所需要的对象。
两个类写在同一个文件中,会被编译成两个独立的.class文件,具体执行会调用不同的文件。
·方法参数
java
public static void main(String[] args) {
int a = 10;
int b = 20;
System.out.println("a="+a+" b="+b);
change(a,b);
System.out.println("a="+a+" b="+b);
}
public static void change(int a,int b){
int temp = a;
a = b;
b = temp;
}
只有方法内的变化,并不会返回到原来的数据上。

如果想要改变值,就要用引用类型.属性直接给属性赋值
·方法重载
方法名相同,方法签名(类型、顺序、个数)不同
java
public static void main(String[] args){
add(1,2);
add(1.1f,2.2f);
add('a','b');
}
public static void add(int a,int b){
System.out.println("整数相加");
}
public static void add(float a,float b){
System.out.println("浮点数相加");
}
public static void add(char a,char b){
System.out.println("字符相加");
}

·默认域初始化
引用类默认null,int默认0,float默认0.0......
·调用另一个构造器
可以在其中一个构造器里边调用其他构造器。
java
public class Person {
String name;
int age;
public Person(){
this("有参构造器",18);
System.out.println("无参构造器");
}
public Person(String name,int age){
this.name=name;
this.age=age;
}
public String toString(){
return "姓名:"+name+",年龄:"+age;
}
public static void main(String[] args) {
Person person = new Person();
System.out.println(person);
}
}

java
public static void main(String[] args) {
Person p1=new Person("张三",18);
Person p2=new Person("王五",20);
System.out.println(p1.age+"---"+p2.age);
change(p1,p2);
System.out.println(p1.age+"---"+p2.age);
}
public static void change(Person p1, Person p2){
int temp=p1.age;
p1.age=p2.age;
p2.age=temp;
}

5.初始化块
初始化赋值的方法:构造器、声明赋值、代码块赋值
代码块赋值
java
{
name="zhangsan";
age=18;
}
新开辟空间的时候会默认赋值,说明在调用构造方法之前做了很多处理,代码块执行先于构造方法
对于一个类的执行顺序
静态属性=静态代码块 > 普通属性=普通代码块 > 构造方法
因为调用构造方法的时候相当于去开辟空间了,所以刚进入内存的时候要做好准备工作,做好准备工作(静态代码块和代码块)之后才去调用构造方法。

对于静态的,只把静态数据加载到静态常量池里,初始化一次,每个对象共享静态数据。
对于非静态的,属于对象级别的,初始化几次取决于有几个对象,每个对象独享自己的非静态属性。
面试可能会问到的问题
1.构造器的无限调用问题
在Person类里新建Person属性的b:
java
Class Person{
Public Person b=new Person();
{
System.out.println("普通代码块");
}
static{
System.out.println("静态代码块");
}
public Person(){
System.out.println("构造方法");
}
}
Class Test{
Person p1=new Person();
Person p2=new Person();
Person p3=new Person();
}
会导致不断调用Person()的构造方法,导致栈溢出,死循环。
java
Class Person{
Public static Person b=new Person();
{
System.out.println("普通代码块");
}
static{
System.out.println("静态代码块");
}
public Person(){
System.out.println("构造方法");
}
}
此时不会导致死循环,因为static属性只需要被第一个对象初始化一次,之后的对象只需要执行非静态代码块,执行完之后调用构造方法。
2.初始化顺序问题
初始化顺序:父类>子类,静态>非静态
即父类静态>子类静态>父类非静态>父类构造方法>子类非静态>子类构造方法