面向对象(OOP)
面向对象的三大特性:封装、继承、多态
修饰符static修饰方法时,当类被加载的时候,这个方法也会被加载;不用static时,对象被创建后,才会存在。所以,static修饰的方法不能调用非static方法。
构造方法:
- 类的构造方法有无参构造和有参构造,但是构造方法的返回值只能是void,修饰符为public。
- 如果有了有参构造,但没有声明无参构造函数,那么创建对象时就不能创建无参的对象。
- 构造函数和类名一样
- new一个对象时,其实就是调用这个类的构造函数。
创建一个对象时内存情况:
Person p = new Person();
p.name = "xiaoma";
p.age = 12;
当new一个对象时,会加载对应的Person类,而引用对象名p是出现在栈中,而实际的name、age数值会出现在堆中。
封装:(高内聚、低耦合)
属性私有,设置get/set方法
作用:
- 提高程序的安全性,保护数据
- 隐藏代码的实现细节
- 统一接口
- 增加系统可维护性
继承:extends
java类是单继承,没有多继承。
子类可以继承父类的属性和方法(private修饰的除外)
父类的引用可以指向子类
Fu fu = new Zi();
所有类都继承Object类
ctrl+H可以查看类的继承关系
super关键字:
super.方法名() 调用父类的对应方法,如果父类对应的方法是私有的,则不能调用。
super() 调用父类的无参构造方法,这个出现在子类无参构造的第一句,默认不写;如果有,一定处于第一句。
- 当用super()来调用父类的构造方法时,必须放在子类构造方法的第一句,无参时默认不写;
- super只能出现在子类的方法或者构造方法中;
- super和this不能同时调用构造方法。
方法重写与重载:
重载:在同一个类中,有多个方法名一样但参数不一样的方法(参数个数、顺序、类型);
重写:在继承中,子类重写父类的方法,方法名一样、参数一样、返回值(可以是返回值的子类)一样(父类中是static方法时,子类中也必须是static方法,其实这不是重写;private的方法不能重写;final的不能重写) 修饰符范围可以扩大但不能缩小(public>protected>default>private) 抛出的异常可以缩小但不能扩大
方法重写时,利用多态去调用方法时要注意:
类 类名 = new 对象();
如果方法是静态的static:那么方法的调用是等号左边类的方法,因为static内容是属于类的,不属于对象,等号左边是类,右边是new出来的对象;
如果方法时非静态的,那么调用的是等号右边的方法,没有static时,调用的是对象的方法,而等号右边是new出来的对象
Fu fu = new Zi();//多态
fu.test();//如果test方法是非静态且被子类重写的话,这调用的是Zi类的test()方法。
Zi zi = new Zi();
zi.test();//如果test方法是非静态且被子类重写的话,这调用的是Zi类的test方法。
多态:
Fu fu = new Zi();
父类的引用可以指向子类的对象。
注意:
①多态是方法的多态,没有属性的多态;
②父子关系;
③存在条件:继承关系中,方法需要重写,父类引用指向子类对象,非静态方法时,调用的是子类的方法。
父子类的转换中:遵从小范围转大范围是自动转换,从大范围转换为小范围,要强制转换; 在继承关系中,父类是小范围,子类是大范围,因为子类多了自己独特的方法。所有由父转子,自动转换,由子转父,强制转换。
Fu fu = new Zi();
Zi zi = (Zi)fu;//由父转子,强制转换
Zi zi1 = new Zi();
Fu fu1 = zi1;//由子转父,自动转换
静态代码块与匿名代码块
这个是Zi类的构造方法、匿名代码块、静态代码块
public class Zi extends Fu {
public Zi() {
System.out.println("构造方法");
}
{
System.out.println("匿名代码块");
}
static {
System.out.println("静态代码块");
}
}
下面这个是测试代码块的执行情况:
public static void main(String[] args) {
Zi zi = new Zi();
System.out.println("------------------------------------------");
Zi zi1 = new Zi();
}
输出结果是:
静态代码块
匿名代码块
构造方法
------------------------------------------
匿名代码块
构造方法
结论:静态代码块在类中执行一次,即类初始加载时被执行,后续不会再执行;匿名代码块在每次类被创建时都会执行。
原理:静态代码块是存储在堆的方法区中一个静态内容块中,当类初始加载时静态代码块会写入这个区内,后续这个类被创建时不会再加载,直接从这个区内拿数据。