定义:
相同的方法可以表现出多种形态,这样的现象就叫多态。
前提:
- 继承
- 重写
- 父类引用指向子类对象
向上转型和向下转型:
- 向上转型:隐式的,创建对象时父类引用指向子类对象,实参为子类对象形参为父类引用
- 向下转型:显式的,创建对象时必须是父类引用指向子类对象,才可以向下转型成对应的子类对象。instanceof可以判断父类引用所指的对象是否可以向下转型为指定的类
优点:
- 提高扩展性
- 便于实现替换
- 提高代码可维护性
- 允许父类引用指向子类对象,解除了引用和对象的耦合
注意事项:
- 多态只和方法有关,和属性无关
- 构造方法和private方法由于不能被重写所以无法使用多态
- 父类引用指向子类对象,使用父类引用只能调用父类中定义过的方法,不能调用子类特有的方法。
下面用打印机来说明多态:
/**
* 打印机(父类)
*/
public class Printer {
private String name;
public Printer() {
super();
}
public Printer(String name) {
super();
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Printer [name=" + name + "]";
}
//有一个自身的打印方法
public void print() {
System.out.println("打印");
}
}
/**
* 黑白打印机(子类)
*/
public class BlackAndWhitePrinter extends Printer {
public BlackAndWhitePrinter() {
super();
}
public BlackAndWhitePrinter(String name) {
super(name);
}
@Override
public void print() {
System.out.println("打印黑白文档");
}
}
/**
* 彩色打印机(子类)
*/
public class ColorsPrinter extends Printer {
public ColorsPrinter() {
super();
}
public ColorsPrinter(String name) {
super(name);
}
@Override
public void print() {
System.out.println("打印彩色文档");
}
}
下面建一个打印工人类来使用打印机:
/**
* 打印工人类
*
* @author junki
* @date 2019年11月26日
*/
public class Worker {
private String name;
public Worker() {
super();
}
public Worker(String name) {
super();
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Worker [name=" + name + "]";
}
//使用打印机的方法
public void usePrinter(Printer p) {
if (p instanceof BlackAndWhitePrinter) {
p.print();
} else {
System.out.println("这个打印机我不会用");
}
}
}
在主方法中我们可以使用多态:
public static void main(String[] args) {
BlackAndWhitePrinter bawp = new BlackAndWhitePrinter();
bawp.print();
ColorsPrinter cp = new ColorsPrinter();
cp.print();
Printer p1 = new BlackAndWhitePrinter();// 向上转型
Printer p2 = new ColorsPrinter();
p1.print();
p2.print();
Worker worker = new Worker();
ColorsPrinter printer1 = new ColorsPrinter();
BlackAndWhitePrinter printer2 = new BlackAndWhitePrinter();
//在这里可以看到,工人中我们只使用了父类对象作为参数,而在调用中,
//我们往参数里面传进子类对象,调用的是子类重写的方法,这就是多态。
worker.usePrinter(printer1);// 向上转型
// 向下转型错误演示
// ClassCastException
Printer p3 = new Printer();
//ColorsPrinter cp3 = (ColorsPrinter) p3;
Printer p4 = new ColorsPrinter();
ColorsPrinter cp4 = (ColorsPrinter) p4;
cp4.print();
}
总结:
是方法的多态,父类定义一个方法,子类可以有不同的重写,然后只需要在形参放入父类对象,子类可以随意往形参中放入自己的对象,又称叫做向上转型