三大特征
- 封装
- 继承
- 多态
封装
使用
- **为什么要引入封装性?**对于声明的类中的属性,其值仅受数据类型和存储范围的制约。实际中,我们给属性赋值时,往往需要加上额外的制约条件,这些限制条件在声明时不能被体现。于是,我们将属性”封装“起来(使用private修饰符),通过调用方法来对属性进行赋值和访问,并在方法中添加特定的限制条件,从而避免用户使用”对象.属性“的方式对属性进行直接赋值。
- 封装性的体现 :将类属性私有化(private修饰符),并提供公共的(public)get和set方法来获取和设置属性的值;不对外暴露的私有内部方法(逻辑代码);单例模式
IDEA中get和set方法的快捷键:Alt+Insert
四种权限修饰符
类的封装性,需要借助权限修饰符实现
由小到大,依次
- private
- protected
- default(默认)
- public
修饰符 | 当前类 | 同包类 | 其它包子类 | 其它包类 |
---|---|---|---|---|
public | 可以 | 可以 | 可以 | 可以 |
default | 可以 | 可以 | 可以 | 不可以 |
protected | 可以 | 可以 | 不可以 | 不可以 |
private | 可以 | 不可以 | 不可以 | 不可以 |
- 四种权限修饰符均可以用来修饰属性、方法、构造器、内部类(代码块只能用static修饰)
- 外部类只能用默认或public修饰
- 使用的较多的是public、默认、private
继承
语法:class A extends B{}
使用extends关键字声明继承
子类继承父类的属性和方法
- 子类继承父类后,子类就获取了父类声明所有的属性和方法
- 对于父类中私有的属性和方法,子类不能直接访问(可以间接访问),但仍认为子类获取了父类的私有结构
父类与子类的关系
- 父类与子类是is-a的关系(与接口的has-a区分)
- 一个子类只能有一个父类(单继承),但一个父类可以有多个子类
- 多个子类的公共方法可以定义在父类中
使用super关键字调用父类属性、方法、构造器
- super调用父类属性和方法
使用“super.属性“和”super.方法“调用父类属性和方法(参考this的用法) - super调用父类构造器
- 可以使用”super(参数列表)“的方式显式的调用父类的构造器
- ”super(参数列表)“必须放在子类构造器的第一行,既子类构造器第一行只能是”this(形参列表)“或”super(参数列表)“二选一
- 如果子类构造器第一行既没有”this(形参列表)“,也没有”super(参数列表)“,那么子类会隐式调用父类空参构造器,既”super()“
- 子类构造器均会直接或间接的调用父类的构造器,直到调用java.lang.Object类的空参构造器,形成构造器调用链
子类实例化过程
- 从结果上看,子类实例化后,堆空间加载了所有父类的属性和方法,既子类继承了所有父类的属性和方法(参考JVM的对象创建过程、类加载机制)
- 从过程上看,当子类实例化时,一定会直接或间接的调用父类的构造器,最终调用java.lang.Object类的空参构造器
- 虽然在创建子类对象时调用了父类的构造器,但并未创建父类对象,至始至终只创建了子类对象
方法的重载和重写
重写 | 重载 | |
---|---|---|
类 | 具有继承关系的不同类中 | 可以是同一类,也可以是具有继承关系的不同类中 |
标注 | @Override | 无 |
特点 | 父类私有方法、静态方法不能重写,重写的方法签名必须相同 | 重载的方法签名必须不同 |
多态
父类的引用指向子类的对象
动态绑定
编译时类型:声明该变量时使用的类型(声明类型)
运行时类型:实际赋值给变量的对象的类型(实际类型)
- 编译时,看左边;执行时,看右边。声明类型决定了编译时匹配哪个方法,实际类型决定了运行时动态绑定重写方法的哪个实现
- 可以使用父类引用调用子类中重写的同名方法,运行时实际执行的是子类中的重写方法
- 不能使用父类引用调用子类中特有的方法、属性,编译时报错
- 多态性不适用于属性,既子父类有同名的属性时,实际调用的是父类的属性
- 使用多态的前提:类的继承关系;方法重写
- 可以应用在抽象类和接口上(更常见)
注:在接口中定义子类的共有方法,并在子类中根据需要用不同的方式来实现接口中的方法。编译时,按照一定的顺序调用接口中定义的方法,规范完成特定功能方法步骤。运行时,实际赋值的子类对象决定方法的具体实现。虽然子类对象不同,方法实现不同,但完成的功能是相同的。
Connection conn = new MySQLConnection();//创建MySQL数据库连接
//Connection conn = new OracleConnection();//创建Oracle数据库连接
//对数据库进行操作的具体步骤是相同的
conn.method1();
conn.method2();
conn.method3();
对象转换
- 多态允许父类引用指向子类对象(隐式转换)。内存中实际上已经加载了子类特有的属性和方法,只是父类引用不能调用
- 把一个父类变量转换为一个子类变量时(用来调用子类特有的属性和方法),必须使用显式转换(强制类型转换),既”(子类名)对象“,且必须确保要转换的对象是子类的一个实例,否则会报异常(ClassCastException)。可以使用instanceof关键字来判断对象是否是某个类的实例
instanceof关键字
用法:boolean b = 对象 instanceof 类型,右边语句返回一个布尔值
如果a instancef A 返回true,那么a instanceof B 也返回true其中A是B的子类