1. 多态的概述
1.1 什么是多态?
- 同类型的对象,执行同一个行为,会表现出不同的行为特征。
1.2 多态的常见形式
1.3 多态中成员访问特点
- 方法调用:编译看左边,运行看右边。
- 变量调用:编译看左边,运行也看左边。(多态侧重行为多态)
1.4 多态的前提
- 有继承/实现关系;有父类引用指向子类对象;有方法重写。
2. 多态的优势
- 在多态形式下,右边对象可以实现解耦合,便于扩展和维护。
- 定义方法的时候,使用父类型作为参数,该方法就可以接收这父类的一切子类对象,体现出多态的扩展性与便利。
3. 多态下引用数据类型的类型转换
自动类型转换(从子到父)
强制类型转换(从父到子)
- 此时必须进行强制类型转换:子类 对象变量 = (子类)父类类型的变量
- 作用:可以解决多态下的劣势,可以实现调用子类独有的功能。
- 注意:如果转型后的类型和对象真实类型不是同一种类型,那么在转换的时候就会出现ClassCastException
Java建议强制转换前使用instanceof判断当前对象的真实类型,再进行强制转换
public class Test {
public static void main(String[] args) {
// 自动类型转换:
Animal a = new Dog();
a.run();
// 强制类型转换:
Animal a2 = new Tortoise();
a2.run();
//Dog d = (Dog) a2; //强制类型转换:编译阶段不报错的(注意:有继承或实现关系编译阶段可以强转,没有毛病),运行时可能出错!
if(a2 instanceof Tortoise){
Tortoise t = (Tortoise) a2;// 从父类类型到子类类型:必须强制转换
t.layEggs();
}else if(a2 instanceof Dog){
Dog d = new Dog();
d.lookDoor();
}
System.out.println("--------------");
go(new Dog());
go(new Tortoise());
}
public static void go(Animal a){
a.run();
// a 到底是乌龟还是狗
if(a instanceof Tortoise){
Tortoise t = (Tortoise) a;// 从父类类型到子类类型:必须强制转换
t.layEggs();
}else if(a instanceof Dog){
Dog d = new Dog();
d.lookDoor();
}
}
}
4. 多态的案例
需求:
- 使用,面向对象编程模拟:设计一个电脑对象,可以安装2个USB设备
- 鼠标:被安装时可以完成接入、调用点击功能、拔出功能。
- 键盘:被安装时可以完成接入、调用打字功能、拔出功能。
分析:
- 定义一个USB接口(申明USB设备的规范必须是:可以接入和拔出)。
- 提供2个USB实现类代表鼠标和键盘,让其实现USB接口,并分别定义独有功能。
- 创建电脑对象,创建2个USB实现类对象,分别安装到电脑中并触发功能的执行。
代码:
/**
USB接口 == 规范
*/
public interface USB {
// 接入 拔出
void connect();
void unconnect();
}
/**
实现类
*/
public class KeyBoard implements USB{
private String name;
public KeyBoard(String name) {
this.name = name;
}
@Override
public void connect() {
System.out.println(name + "成功连接电脑~");
}
/**
独有功能
*/
public void keyDown(){
System.out.println(name + "敲击了:xxxxxxxxx");
}
@Override
public void unconnect() {
System.out.println(name + "成功从电脑中拔出~");
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
/**
实现类
*/
public class Mouse implements USB{
private String name;
public Mouse(String name) {
this.name = name;
}
@Override
public void connect() {
System.out.println(name + "成功连接电脑~");
}
/**
独有功能
*/
public void dbclick(){
System.out.println(name + "双击点亮小红心,一键三连~~");
}
@Override
public void unconnect() {
System.out.println(name + "成功从电脑中拔出~");
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
public class Computer {
private String name;
public Computer(String name) {
this.name = name;
}
public void start(){
System.out.println(name + "开机了~~");
}
/**
提供安装USB设备的入口
*/
public void installUSB(USB usb){
// 多态:usb == 可能是鼠标 也可能是键盘
usb.connect();
// 独有功能:先判断再强转
if(usb instanceof KeyBoard){
KeyBoard k = (KeyBoard) usb;
k.keyDown();
}else if(usb instanceof Mouse){
Mouse m = (Mouse) usb;
m.dbclick();
}
usb.unconnect();
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
/**
目标:USB设备模拟
1、定义USB接口:接入 拔出。
2、定义2个USB的实现类:鼠标、键盘。
3、创建一个电脑对象,创建USB设备对象,安装启动
*/
public class Test {
public static void main(String[] args) {
// a、创建电脑对象
Computer c = new Computer("MacBook Pro");
c.start();
// b、创建鼠标对象,键盘对象
USB u = new KeyBoard("大F");
c.installUSB(u);
USB u1 = new Mouse("罗技G304");
c.installUSB(u1);
}
}