前提条件 :方法重写只能是子类重写父类中的方法
方法重写的目的: 当父类中的方法,无法满足子类的需求时,子类可以进行方法的扩展
方法重写就是,子类重写父类中的方法,必须和父类中的方法名,返回值类型,参数列 表完全一致,而且访问修饰符的范围不能缩小。private<默认<protected<public
package com.bdit; public class Test8 { public static void main(String[] args) { ColorPrinter colorPrinter = new ColorPrinter(); colorPrinter.printer(); BWPrinter bwPrinter = new BWPrinter(); bwPrinter.printer(); Printer printer = new Printer(); printer.printer(); } } /** * 打印机 父类 */ class Printer { public void printer() { System.out.println("=====打印机======"); } } class ColorPrinter extends Printer { public void printer() { System.out.println("======彩色打印机======="); } } class BWPrinter extends Printer { public void printer() { System.out.println("======黑白打印机======"); } }多态是继封装、继承之后,面向对象的第三大特征。
生活中,比如跑的动作,小猫、小狗和大象,跑起来是不一样的。再比如,电脑上各个软件 都有快捷键,但是相同的按键,实现的效果不同。可见,同一行为,通过不同的事物,可以 体现出不同的形态。多态,描述的就是这样的状态。
定义: 多态:是指同一个行为,具有多个不同的表现形式。
什么是多态: 同一个对象,在不同时刻表现出来的不同形态
●继承或者实现【二选一】 ●方法重写【意义体现,不重写没意义】 ●父类引用指向子类对象(格式体现)
多态的体现形式: ●编译时多态:方法重载 ●运行时多态: Java 运行时系统根据调用该方法的实例(对象)的类型来决定调用哪个方法。
多态体现格式:
父类类型 对象名 = new 子类类型(); 对象名.方法名();父类类型:指子类对象继承的父类类型,或者实现的父接口类型。 当使用多态方式调用方法时,首先检查父类中是否有该方法,如果没有,则编译失败;如果 有,就执行子类重写后的方法。
package com.bdit; public class Test2 { public static void main(String[] args) { //多态 Printer printer = new BWPrinter(); printer.printer(); printer.test1(); Printer printer1 = new ColorPrinter(); printer1.printer(); } } //定义父类 打印机 class Printer { public void printer() { System.out.println("父类打印机---打印"); } public void test1() { System.out.println("父类中的普通方法"); } } //子类 黑白打印机 class BWPrinter extends Printer { public void printer() { System.out.println("黑白打印机---打印"); } //普通方法 public void t1() { System.out.println("黑白打印机类中---普通方法"); } } //子类 彩色打印机 class ColorPrinter extends Printer { public void printer() { System.out.println("彩色打印机---打印"); } }实际开发过程中,父类类型作为方法中的形式参数,传递子类对象给方法,进行方法的调用, 更能体现出多态的扩展性与便利性。
package com.bdit; public class Test3 { public static void main(String[] args) { Printer1 printer = new BWPrinter1(); Printer1 printer1 = new ColorPrinter1(); showInfo(printer1); } public static void showInfo(Printer1 printer) { printer.printer(); } } //定义父类 打印机 class Printer1 { public void printer() { System.out.println("父类打印机---打印"); } public void test1() { System.out.println("父类中的普通方法"); } } //子类 黑白打印机 class BWPrinter1 extends Printer1 { public void printer() { System.out.println("黑白打印机---打印"); } //普通方法 public void t1() { System.out.println("黑白打印机类中---普通方法"); } } //子类 彩色打印机 class ColorPrinter1 extends Printer1 { public void printer() { System.out.println("彩色打印机---打印"); } }多态的转型分为向上转型和向下转型两种。
●向上转型:多态本身是子类类型向父类类型向上转换的过程,这个过程是默认的。
●当父类引用指向一个子类对象时,便是向上转型。
●使用格式: 父类类型 对象名=new 子类类型();
●可以把向上转型的对象,看作是父类对象。
●向上转型的对象,可以调用父类中所有的普通方法和成员属性,但是只能调用子类中重 写的方法
●向下转型:父类类型向子类类型向下转换的过程,这个过程是强制的。 不能直接把一个父类对象,强制转换成一个子类对象 向下转型,一定是在向上转型的基础上,做类型的还原。
●一个已经向上转型的子类对象,将父类引用转为子类引用,可以使用强制类型转换 格式如下: 子类类型 对象名=(子类类型)经过向上转型的父类对象;
当使用多态方式调用方法时,首先检查父类中是否有该方法,如果没有,则编译错误,也就 说,不能调用子类拥有,而父类没有的方法。编译错误了,也就无法运行,这也是多态带来 的一点麻烦。所以,想调用子类特有的方法,必须做向下转型。
转型的过程中,容易出现类型转换异常:
public static void main(String[] args) { Printer1 printer=new BWPrinter1(); Printer1 printer1=new ColorPrinter1(); //向下转型 BWPrinter1 bwp=(BWPrinter1)printer; bwp.t1(); bwp.test1(); //向下转型,出现类型转换异常 BWPrinter1 bwp2=(BWPrinter1)printer1; }这段代码可以通过编译,但是运行时,出现 java.lang.ClassCastException,类型转换异常!这 是因为,两个对象类型不匹配,不能做类型转换。
【instanceof 关键字来判断某个对象是否属于类或接口,属于的情况下,再做向下转型,可以避免引发类型转换异常。 对象名 instanceof 类名/接口 如果对象属于该数据类型,返回 true 如果对象不属于该数据类型,返回 false 】 所以,向下转型,先判断,然后再转型。
if(printer1 instanceof ColorPrinter1){ ColorPrinter1 colorPrinter1=(ColorPrinter1)printer1; }● 继承 ● 重写 ● 向上转型 ● 用向上转型的对象,调用被子类重写的方法
当有多态发生时,一定会发生动态绑定机制。 动态绑定机制,就是程序在运行期间,会判断对象的真正的创建者是谁,就调用谁里面的方法。