1.多态的概念
1.1 多态的基本概念
多态:见名知意,就可以知道是多种状态、多种形态。也就是去完成某个行为的时候,当不同的对象去完成就会产生不同的状态
比如:打印机可以分为彩色打印机和黑白打印机,我们知道 Java 是面向对象思想的语言,面向对象的程序设计中一切皆为对象。那么彩色打印机是一个对象,黑白打印机又是一个对象,它们都属于打印机,所以打印机是它们的父类,它们是打印机的子类。它们同样是打印但是当用彩色打印机打印出来的一定是彩色的,当用黑白打印机打印出来的就是黑白色的,所以这就体现了当用不同的对象去完成同一个行为时会产生不同的状态
结论:同一件事情发生在不同的对象身上,就会产生不同的结果
1.2 多态实现的条件
如果想要实现多态必须满足以下条件:
必须在继承体系下
子类必须对父类的方法进行重写
通过父类的引用调用子类重写的方法
多态的体现:在代码运行时,当传递不同的类对象时,会调用对应类中的重写方法
class Printer { public String name; Printer(String name) { this.name = name; } public void print() { System.out.println(name+"打印"); } } class ColorPrinter extends Printer { ColorPrinter(String name) { super(name); } public void print() { System.out.println(name+"打印彩色的"); } } class BWPrinter extends Printer { BWPrinter(String name) { super(name); } public void print() { System.out.println(name+"打印黑白的"); } } public class Test { public static void main(String[] args) { ColorPrinter colorPrinter = new ColorPrinter("彩色"); Printer printer = colorPrinter; printer.print(); } }
Printer:打印机 ColorPrinter:彩色打印机 BWPrinter:黑白打印机
要实现多态第一步就是必须在继承体系下,彩色打印机和黑白打印机都是打印机的子类,也就说明它们是继承关系。第二步就是子类必须对父类的方法进行重写,父类里面写了一个print方法,两个子类里面也写了print方法,这些print方法结构都一样只是方法体的里面的实现不一样,说明它们的确是重写了父类的方法。第三步通过父类的引用调用子类重写的方法,我们实例化一个子类对象,然后将子类对象赋值给一个父类类型,然后通过父类的引用调用该子类的方法
2.重写
上述我们说了想要实现多态,子类必须对父类的方法进行重写。那我们接下来就一起学习重写
2.1 重写的概念
重写:也称为覆盖。重写是子类对父类非静态、非private修饰,非final修饰,非构造方法等的实现过程进行重新编写, 返回值和形参还有方法名都不能改变(即外壳不变,核心重写)。
重写的好处: 子类可以根据需要,定义特定于自己的行为。也就是说子类能够根据需要实现父类的方法。
2.2 方法重写的规则
子类在重写父类的方法时,一般必须与父类方法原型一致: 返回值类型 方法名 (参数列表) 要完全一致
被重写的方法返回值类型可以不同,但是必须是具有父子关系的
访问权限不能比父类中被重写的方法的访问权限更低。例如:如果父类方法被public修饰,则子类中重写该方法就不能声明为 protected
父类被static、private修饰的方法、构造方法都不能被重写
重写的方法,可以使用 @Override 注解来显式指定。有了这个注解能帮我们进行一些合法性校验。例如不小心将方法名字拼写错了 (比如写成 aet),那么此时编译器就会发现父类中没有 aet 方法,就会编译报错,提示无法成重写
2.3 重写和重载的区别
①重写
class Printer { public String name; Printer(String name) { this.name = name; } public void print() { System.out.println(name+"打印"); } } class ColorPrinter extends Printer { ColorPrinter(String name) { super(name); } @Override public void print() { System.out.println(name+"打印彩色的"); } }
上述代码 子类ColorPrinter 中的 print方法 就是对 父类Printer 里面的 print方法 进行了重写
重写:返回类型相同,方法名相同,形参列表一致
注:返回值还可以是父子关系
②重载
class Printer { public String name; Printer(String name) { this.name = name; } public void print() { System.out.println(name+"打印"); } public void print(int year) { System.out.println(name+year+"打印彩色的"); } }
此时 Printer类 里面的两个 print方法 进行了重载
重载:返回类型随便,方法名相同,参数列表一定不同
注:参数列表不同可以是形参顺序不同,形参类型不同...
方法重载是一个类的多态性表现,而方法重写是子类与父类的一种多态性表现
静态绑定:也称为前期绑定(早绑定),即在编译时,根据用户所传递实参类型就确定了具体调用那个方法。典型代表函数重载。
动态绑定:也称为后期绑定(晚绑定),即在编译时,不能确定方法的行为,需要等到程序运行时,才能够确定具体调用那个类的方法。