封装、继承和多态是面向对象编程的三大特性。
封装
将数据和操作数据的方法进行有机结合,隐藏对象的属性和实现细节,进对外公开接口来和对象进行交互
访问限定符
Java中主要通过类和访问权限来实现封装:类可以将数据以及封装数据的方法结合在一起,更符合人类对事物的认知,而访问权限用来控制方法或者字段能否直接在类外使用。
| No | 范围 | private | defaul | protected | public |
|---|---|---|---|---|---|
| 1 | 同一包中的同一类 | 🍉 | 🍉 | 🍉 | 🍉 |
| 2 | 同一包中的不同类 | 🍉 | 🍉 | 🍉 | |
| 3 | 不同包中的子类 | 🍉 | 🍉 | ||
| 4 | 不同包的非子类 | 🍉 |
继承
面向对象思想中提出了继承的概念,专门用来进行共性的抽取,实现代码的复用。
继承属于非常重要的内容,在定义不同类的时候存在一些相同属性,为了方便使用可以将这些共同属性抽象成一个父类,在定义其他子类时可以继承自该父类,减少代码的重复定义,子类可以使用父类中非私有的成员。
在子类方法中 或者 通过子类对象访问成员时:
- 如果访问的成员变量子类中有,优先访问自己的成员变量
- 如果访问的成员变量子类中没有,则访问父类继承下来的,如果父类中也没有定义,那么就编译报错
- 如果访问的成员变量与父类中成员变量同名,则优先访问自己的,即:子类将父类同名成员隐藏了。
成员变量访问遵循就近原则,自己如果有的话就访问自己的,如果没有则向父类中找。
在子类中访问父类的成员方法:
- 通过子类对象访问父类与子类中不同名方法时,优先在子类中找,找到则访问,否则在父类中找,找到则访问,否则编译会报错
- 通过派生类对象访问父类与子类同名方法时,如果父类和子类同名方法的参数列表不同,构成重载,根据调用方法中传递的参数来选择合适的方法来访问,如果没有则报错;如果父类和子类同名方法的原型一致,构成重写,那么就只能访问到子类的,父类的无法通过派生类对象直接访问到。
super关键字
在子类方法中访问父类的成员。
每一个子类必须定义一个实现父类构造方法的构造方法,也就是需要在构造方法开始使用super(),如果父类使用的是默认构造方法,那么子类不用手动指明。
super和this
- this是对当前对象的引用,当前对象即调用方法的对象,super相当于是子类对象中从父类继承下来部分成员的引用
- 在非静态成员方法中,this用来访问本类的方法和属性,super用来访问父类继承下来的方法和属性 this是非静态成员方法的一个隐藏参数,而super不是隐藏的参数
- 成员方法中直接访问本类成员时,编译之后会将this添上去还原,即本类非静态成员都是通过this来访问的;在子类中如果通过super访问父类成员,编译之后在字节码层面super实际上是不存在在字节码文件中的
- 在构造方法中:this(…);用于调用本类的构造方法,super(…)用于调用父类的构造方法,两种调用不能同时在构造方法中出现
- 构造方法中一定会存在super(…)的调用,用户没有写编译器也会自动添加,但是this(…)用户不写的话编译器不会自动添加
- 在构造方法中调用时,必须是构造方法中的额第一条语句,并且不能同时存在
初始化
- 父类静态代码块优先于子类静态代码块执行,而且时最早执行得
- 父类实例代码块和父类构造方法紧接着执行
- 子类得实例代码块和子类得构造方法紧接着依次进行
- 第二次实例化子类对象时,父类和子类的静态代码块都将不会再执行
多态
多态是同一个行为具有多个不同表现形式或形态的能力。
多态就是同一个接口,使用不同的实例而执行不同操作。
多态的必要条件:
1.子类继承父类并重写父类的方法。
2.父类的引用指向子类对象。
定义格式:父类类型 变量名=new 子类类型();
方法的重写
重写(override):也称为覆盖。重写是子类对父类非静态、非private修饰,非final修饰,非构造方法等进行重新编写的一个过程,返回值和形参都不能改变。即外壳不改变,核心重写。
方法重写的规则
- 子类在重写父类的方法时,一般必须与父类方法原型一致:修饰符 返回值类型 方法名(参数列表)要完全一致
- 访问权限不能比父类中被重写的方法的访问权限更低。例如:如果父类方法被public修饰,则子类中重写该方法就不能声明为protected
- 父类被static、private修饰的方法都不能被重写
- 子类和父类在同一个包中,那么子类可以重写父类中的所有方法,除了声明为private和final的方法
- 子类和父类不在同一个包中,那么子类只能够重写父类的 声明为public 和protected的非final方法
- 重写的方法,可以使用 @Override 注解来显式指定。
类型转换
向上转型
实际上就是创建一个子类对象,将其当成父类对象来使用
Fu f=new Zi();
将子类对象转化为父类引用时合理的,大范围可以囊括小范围,是安全的。
向下转型
把已经明确是由哪个类实现的父类引用,强制转换为对应的类型。不安全。
Fu f = new Fu();
Zi zi = (Zi)f;
Java中为了提高向下转型的安全性,引入了instanceof,如果该表达式为true,则可以安全转换
Fu f = new Fu();
if(f instanceof Zi){
Zi zi = (Zi)f;
}
多态的好处:
- 可替换性:多态对已存在代码具有可替换性。例如,多态对圆Circle类工作,对其他任何圆形几何体,如圆环,也同样工作。
- 可扩充性:多态对代码具有可扩充性。增加新的子类不影响已存在类的多态性、继承性,以及其他特性的运行和操作。实际上新加子类更容易获得多态功能。
- 接口性:多态是超类通过方法签名,向子类提供了一个共同接口,由子类来完善或者覆盖它而实现的。
- 灵活性:它在应用中体现了灵活多样的操作,提高了使用效率。
- 简化性:多态简化对应用软件的代码编写和修改过程,尤其在处理大量对象的运算和操作时,这个特点尤为突出和重要。