什么是多态?
同类型的对象,执行同一个行为,会表现出不同的行为特征。
多态的常见形式
父类类型 对象名称 = new 子类构造器;
接口 对象名称 = new 实现类构造器;
多态(侧重行为多态)中成员访问特点:
1.方法调用:编译看左边,运行看右边。
2.变量调用:编译看左边,运行也看左边。
多态的前提
有继承/实现关系;有父类引用指向子类对象;有方法重写。
多态的优势
1.在多态形式下,右边对象可以实现解耦合,便于扩展和维护。
Animal a = new Dog(); // = new Tortoise();
a.run(); //后续业务行为随对象而变,后续代码无需修改
2.定义方法的时候,使用父类型作为参数,该方法就可以接收这个父类的一切子类对象,体现出多态的扩展性与便利。
package snow.d1_polymonbic;
public class Test {
public static void main(String[] args) {
// 多态的形式 父类类型 对象名 = new 子类构造器
Animal a = new dog();
go(a);
Animal a2 = new Tortoiss();
go(a2);
}
// 所有动物进行比赛
public static void go(Animal a){
System.out.println("开始~~~");
a.run();
System.out.println("结束~~~");
}
}
多态下会产生的一个问题:多态下不能使用子类的独有功能。
为了解决这个问题我们可以多态下的引用数据类型的类型转换可以实现多态下使用子类的独有功能。
多态下引用数据类型的类型转换
自动类型转换(从子到父类):子类对象赋值给父类类型的变量指向。
强制类型转换(从父到子类):
1.此时必须进行强制类型转换:子类 对象变量 = (子类)父类类型的变量
2.作用:可以解决多态下的劣势,可以实现调用子类独有的功能。
注意:如果转型后的类型和对象真实类型不是同一种类型,那么在转换的时候就会出现ClassCastException。
Animal a2 = new Tortoiss();
dog d = (dog)a2; // 出现异常ClassCastException
Java建议强转转换前使用instanceof判断当前对象的真实类型,再进行强制转换。
变量名 instanceof 真实类型
判断关键字左边的变量指向的对象的真实类型,是否是右边的类型或者是其子类类型,是则返回true,反之。
代码:
多态的案例
需求:
1.使用面向对象编程模拟:设计一个电脑对象,可以安装2个USB设备
2.鼠标:被安装时可以完成接入、调用点击功能、拔出功能。
3.键盘:被安装时可以完成接入、调用打字功能、拔出功能。
分析:
1.定义一个USB的接口(申明USB设备的规范必须是:可以接入和拔出)。
2.提供2个USB实现类代表鼠标和键盘,让其实现USB接口,并分别定义独有的功能。
3.创建电脑对象,创建2个USB实现类对象,分别安装到电脑中并触发功能的执行。
电脑类Computer.java:
package snow.d2_polymorphic_test;
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.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接口USB.java:
package snow.d2_polymorphic_test;
public interface USB {
//接入 拔出
void connect();
void unconnect();
}
键盘类KeyBoard.java:
package snow.d2_polymorphic_test;
// 实现类
public class KeyBoard implements USB{
private String name;
public KeyBoard(String name) {
this.name = name;
}
@Override
public void connect() {
System.out.println(name + "成功链接了电脑~");
}
@Override
public void unconnect() {
System.out.println(name + "成功从电脑拔出~");
}
// 独有功能
public void keyDown(){
System.out.println(name + "输入了。");
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
鼠标类Mouse.java:
package snow.d2_polymorphic_test;
// 实现类
public class Mouse implements USB{
private String name;
public Mouse(String name) {
this.name = name;
}
@Override
public void connect() {
System.out.println(name + "成功链接了电脑~");
}
@Override
public void unconnect() {
System.out.println(name + "成功从电脑拔出~");
}
// 独有功能
public void dbClick(){
System.out.println(name + "点击了。");
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
测试类Test.java:
package snow.d2_polymorphic_test;
public class Test {
public static void main(String[] args) {
// 创建电脑对象
Computer computer = new Computer("外星人");
computer.start();
// 创建鼠标对象。键盘对象。
USB k = new KeyBoard("雷柏键盘");
computer.installUSB(k);
USB m = new Mouse("双飞燕鼠标");
computer.installUSB(m);
}
}