面向对象高级
static关键字
-
特点
- 被static修饰的成员会被该类所有对象共享
- 被static修饰的成员,会随着类的加载而加载,优先于对象存在
- 被static修饰的成员,可以通过类名.的方式进行调用
static修饰的成员会被存储于静态存储位置,创建的对象中只会对这个静态存储位置中成员的地址进行记录
-
注意事项
-
静态随着类的加载而加载,优先于对象存在
- 静态方法中,只能访问静态成员(所以如果想在Public static void main(String[] args)方法中调用类中的其他方法,其他方法必须是静态方法)
- 静态方法中没有this关键字
- 非静态方法中,可以使用静态成员也可以不使用
-
非静态需要在对象创建之后使用
-
final关键字
-
修饰类:表示这个类中所有的方法子类都不能进行重写
-
修饰变量:final修饰成员变量时必须在创建的时候赋值,或者在构造方法中进行赋值;局部变量必须使用之前被赋值一次才能使用
-
基本数据类型变量:final修饰的变量等同于常量,所以需要遵守常量的命名规则。如果是一个单词,所有的字母大写,如果是多个单词,所有字母大写并且中间用_进行分割
-
引用数据类型变量: 地址值不能被修改,但是对象的属性可以被修改
-
-
修饰方法:方法不能被子类重写
继承
重写
注意事项
- 父类的私有方法不能被重写
- 父类的静态方法,子类必须通过静态方法进行重写;父类的非静态方法,子类也必须通过非静态方法进行重写(其实静态方法并不能被重写,如果子类中有一个和父类一模一样的方法,可以理解为子类将父类中同名的方法隐藏,而不是重写)
- 子类重写父类,访问权限必须大于等于父类
权限修饰符
构造方法
子类在初始化之前,一定会完成父类的初始化,也就是说在子类初始化之前,一定会执行父类的构造方法,这一点是通过在每一个子类的构造方法中默认隐藏了一句super()即父类的构造方法来实现的
super()和this()方法在构造器中不能同时存在
对于private成员变量的理解
对于父类中用private修饰的成员变量,子类中并不是不能继承,只是不能直接调用,但是可以通过继承自父类的get,set方法来赋值或获取数据。
下图所示,student继承自person类,person中的成员变量是私有的,但是可以通过在子类构造器中调用父类构造器来赋值,并通过继承的getName()方法来访问父类私有的成员变量
抽象
定义
- 抽象方法:将共性的行为抽取到父类之后,发现该方法的实现逻辑无法在父类中给出具体明确的实现,该方法就可以定义为抽象方法
- 抽象类:如果一个类中存在抽象方法,那么这个类必须声明为抽象类
注意事项
- 抽象类不能创建对象
- 抽象类中有构造方法
- 抽象类的子类必须重写父类的抽象方法(或者不重写,自己成为一个抽象类)
- 抽象类中可以没有抽象方法,但是有抽象方法的类一定是抽象类
模板设计模式
抽象类整体可以看作一个模板,把模板中不能决定的东西定义成抽象方法,让使用模板的类(继承抽象类的类)去重写抽象方法实现需求
代码块
-
局部代码块
- 位置:方法中
- 作用:限定变量的生命周期,及早释放,提高内存利用率
-
构造代码块
- 位置:类中方法外
- 特点:每次构造方法执行时,都会执行该代码块中的代码,并且在构造方法执行前执行
- 作用:将多个构造方法中相同的代码,抽取到构造代码块中,提高代码的复用性
-
静态代码块
- 位置:类中方法外
- 特点:需要通过static关键字修饰,随着类的加载而加载,只执行一次
- 作用:在类加载的时候做一些数据初始化的操作
接口
定义
当一个类中的所有方法都是抽象方法的时候,我们就可以将其定义为接口。
接口也是一种引用数据类型它比抽象类还要抽象。
特点
- 定义格式:
public interface 接口名{} - 接口不能实例化
- 接口和类之间是实现关系,
public class 类名 implements 接口名{} - 接口的实现类要么重写接口中的所有抽象方法,要么是抽象类
接口的成员
接口成员的public都可以省略,因为会被自动加上
成员常量
**接口没有成员变量,但是可以定义成员常量 ** 接口的成员变量在其实现类中也可以使用,但是接口的成员变量默认是final修饰,不能被修改
并且,实现类可以通过类名.的方式直接调用成员变量,因为interface成员变量还被static修饰
并且,接口的成员变量默认被public修饰,不能更改
构造方法
接口没有构造方法
成员方法
抽象方法
- JDK7之前,接口中只能是,用public abstrict修饰的抽象方法。(public abstrict可省略)p/
默认方法
-
但是这样存在一个问题,如果后期我们希望对接口的功能进行扩展,必须在接口中添加抽象方法的话,那么其他所有实现了这个接口的类都必须实现这个新的抽象方法,可能就必须修改大量的代码。
于是JDK8允许在接口中定义拥有方法体的非抽象方法,但是需要使用关键字default修饰,这些方法就是默认方法(注意关键字default不是权限修饰符)
- 默认方法不是抽象方法,可以不被重写,如果需要重写,方法名去掉default
- 默认方法的定义中,public可以省略,default不能被省略(因为public省略也会被默认加上)
- 如果实现了多个接口,并且多个接口有相同的默认方法声明,子类就必须重写此方法
静态方法
- 只能通过接口类来调用,不可以通过接口类的子类调用,而且只能通过类名.的方式进行调用,通过对象来调用不正确
- 如果希望默认方法调用更简洁,可以考虑设计为static静态方法
私有方法
- 如果默认方法中出现了重复代码,可以考虑抽取出一个私有方法,在不同的默认方法中共用
类和接口的关系
-
类和类的关系
- 单继承,可以多层继承
-
类和接口的关系
- 实现关系(如果一个类继承的父类和实现的接口中有同名同参数的方法,那么这个类的对象实际上会执行父类中的方法)
-
接口和接口的关系
- 继承关系,可以单继承也可以多继承
多态
多态的成员访问特点
- 成员变量:编译看左边(父类),执行看左边(父类)
- 成员方法:编译看左边(父类),执行看右边(子类) 因为成员方法存在重写,所以编译和执行不同
多态优缺点
优点:提高程序扩展性 缺点:不能使用子类特有功能
多态中的转型
-
向上转型:父类引用指向子类对象
-
向下转型:父类引用转为子类对象
- 使用instanceof来判断左边的实例是不是右边的类型
Dog d = new Dog(),d instanceof Dogd是Dog的实例