1、方法重写
前提条件 :方法重写只能是子类重写父类中的方法
方法重写的目的: 当父类中的方法,无法满足子类的需求时,子类可以进行方法的扩展
方法重写就是,子类重写父类中的方法,必须和父类中的方法名,返回值类型,参数列 表完全一致,而且访问修饰符的范围不能缩小。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("======黑白打印机======");
}
}
2、多态
2.1、概述
多态是继封装、继承之后,面向对象的第三大特征。
生活中,比如跑的动作,小猫、小狗和大象,跑起来是不一样的。再比如,电脑上各个软件 都有快捷键,但是相同的按键,实现的效果不同。可见,同一行为,通过不同的事物,可以 体现出不同的形态。多态,描述的就是这样的状态。
定义:
多态:是指同一个行为,具有多个不同的表现形式。
什么是多态: 同一个对象,在不同时刻表现出来的不同形态
前提【重点】
●继承或者实现【二选一】
●方法重写【意义体现,不重写没意义】
●父类引用指向子类对象(格式体现)
多态的体现形式:
●编译时多态:方法重载
●运行时多态: Java 运行时系统根据调用该方法的实例(对象)的类型来决定调用哪个方法。
2.2、多态的体现
多态体现格式:
父类类型 对象名 = 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("彩色打印机---打印");
}
}
2.3、多态的好处
实际开发过程中,父类类型作为方法中的形式参数,传递子类对象给方法,进行方法的调用, 更能体现出多态的扩展性与便利性。
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("彩色打印机---打印");
}
}
2.4、引用类型转换
多态的转型分为向上转型和向下转型两种。
向上转型
●向上转型:多态本身是子类类型向父类类型向上转换的过程,这个过程是默认的。
●当父类引用指向一个子类对象时,便是向上转型。
●使用格式:
父类类型 对象名=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;
}
发生多态的条件
● 继承
● 重写
● 向上转型
● 用向上转型的对象,调用被子类重写的方法
动态(延迟)绑定机制
当有多态发生时,一定会发生动态绑定机制。
动态绑定机制,就是程序在运行期间,会判断对象的真正的创建者是谁,就调用谁里面的方法。