目录
多态
指同一种事物表现出来的多种形态。 e.g. 饮料:可乐、雪碧、红牛、脉动、... 宠物:猫、狗、鸟、小强、鱼、... 人:学生、教师、工人、保安、... 图形:矩形、圆形、梯形、三角形、…
a)语法格式
父类类型 引用变量名 = new 子类类型();
即父类引用指向子类对象的形式
-
声明父类类型引用并指向父类类型对象,任何情况下都调用父类的show方法
-
声明子类类型引用并指向子类类型对象
当子类没有重写方法时,调用父类中的方法 当子类重写方法后,调用子类中的方法
-
声明父类类型引用并指向子类类型对象 当子类t没有重写方法时,调用父类中的方法 当子类重写方法后,在运行阶段调用子类中的方法
b)特点
当父类类型的引用指向子类类型的对象时: 可以直接调用父类独有的方法,但不可以直接调用子类独有的方法 间接调用子类独有的方法:将父类引用强转成子类引用
父子类都有的非静态方法: 运行阶段调用子类重写的版本 父子类都有的静态方法:编译和运行阶段都调用父类版本。
c)注意:
静态方法不可被重写,所谓子类中重写的静态方法的不是真正意义上的重写,只是同名的另一个方法,故子类中重写的静态方法不可用@Override标注,会出现@Override Error
d) 实际意义 屏蔽不同子类的差异性实现通用的编程带来不同的效果
引用数据类型之间的转换
引用数据类型之间的转换方式有两种:自动类型转换 和 强制类型转换。(同基本数据类型间的转换方式一样)
自动类型转换:小类型向大类型的转换,也就是子类转为父类,也叫做向上转型。
强制类型转换:大类型向小类型*的转换,也就是父类转为子类,也叫做向下转型或显式类型转换(加了小括号()才能转换为显式)。
注:
-
引用数据类型之间的转换必须发生在父子类之间(有继承关系),否则编译报错
-
若强转的目标类型并不是该引用真正指向的数据类型时则编译通过,运行阶段发生类型转换异常ClassCastException。
为了避免上述错误的发生,在强转之前应该使用instanceof进行类型判断,判断引用变量指向的对象是否为强转的目标数据类型
if(引用名 instanceof 数据类型)
抽象类
抽象方法
指不能具体实现的方法(没有方法体),使用abstract关键字修饰,具体格式如下:
访问权限 abstract 返回值类型 方法名(形参列表);
抽象类
不能具体实例化的类(即不能创建(new)对象),使用abstract关键字修饰。
a) 实际意义
-
抽象类的实际意义不在于创建对象而在于被继承。
抽象类本身不可以new对象,若想用只可以让它指向子类对象,成为多态
多态的使用场合之二: 直接在方法体中使用抽象类的引用指向子类类型的对象
-
当一个类继承非真正意义上的抽象类(无抽象方法)时,直接继承即可
当一个类继承真正意义上的抽象类(有抽象方法)时要么重写抽象方法,要么将该类也变成抽象类,也就是说抽象类对子类具有强制性和规范性,因此叫做模板设计模式(抽象类的所有子类都要重新写抽象类)。
强制性:强迫子类重写方法 规范性:重写要求方法名、返回值类型、形参列表都一致
抽象类和抽象方法的关系
-
抽象类中可以有成员变量、构造方法、成员方法;
-
抽象类中可以没有抽象方法,也可以有抽象方法;
-
拥有抽象方法的类必须是抽象类(即非抽象类中不可有抽象方法),因此真正意义上的抽象类应该是具有抽象方法并且使用abstract关键字修饰的类。
问:
1. 抽象类为什么不能new对象
抽象类中可能有抽象方法,而抽象方法没有方法体,因此调用它是没有意义的,为了避免程序员不小心调用抽象方法,则规定抽象类不能实例化(new)对象,故没有对象,无法通过引用.的方式调用方法。
2. 为什么没有抽象方法的类不是真正意义上的抽象类?
若抽象类中没有抽象方法,则抽象类不能new对象的意义将不复存在,因此没有抽象方法的类不是真正意义上的抽象类
接口
接口的基本概念
接口是一种比抽象类还抽象的类,体现在所有方法都为抽象方法。 定义接口的关键字interface。
e.g.public interface IRun{ }
注:
-
接口的实际意义为多实现,即一个类可以实现多个接口,弥补java中类只支持单继承的不足
-
接口的命名:接口以I开头,当子类实现一个接口时,命名尽量以相应的接口开头,以impl结尾
-
接口的应用:表示规范、准则 或者 表示具备一种行为能力
-
接口可以继承接口(使用 extends 关键字),但接口不可以继承类
-
当一个场景既可以用抽象类也可以用接口时,接口优先
应用:
Comparable 接口:当一个类实现了Comparable接口,这个类就具备了可比较能力(java.lang.Comparable)
Clonable 接口和深拷贝
Java 中内置了一些很有用的接口, Clonable 就是其中之一. Object 类中存在一个 clone 方法, 调用这个方法可以创建一个对象的 "拷贝". 但是要想合法调用 clone 方法, 必须要先 实现 Clonable 接口, 否则就会抛出CloneNotSupportedException 异常