python 天生支持多态
一、概念
一个事物的多种形态,如即可以是工人也可以是学生
二、目的(作用)
调用一个事物(类)的方法或变量时,不用关心该类的具体形态是什么
三、语法
1、继承
父类名 对象名 = new 子类名();
2、接口
接口名 对象名 = new 接口类();
四、用法
1、成员变量
a、口诀
编译看左,运行看左
解释:编译的时候,看赋值符号左边的类中是否有这个变量名,若没编译出错;运行的时候,去赋值符号左边的类中取结果
b、例子
package cn.wt.day10; public class Animal { int num = 10; }
1 package cn.wt.day10; 2 3 public class Dog extends Animal { 4 int num = 20; 5 }
1 package cn.wt.day10; 2 3 public class Demon { 4 public static void main(String[] args) { 5 Animal dog = new Dog(); 6 System.out.println(dog.num); // 10 7 } 8 }
2、成员方法
a、口诀
编译看左,运用看右
解释:编译时,看"="左边的类是否有这个方法名称;运行时,去"="右边的类找该方法并运行
b、例子
1 package cn.wt.day10; 2 3 public abstract class Animal { 4 int num = 10; 5 6 public abstract void eat(); 7 8 public void show(){ 9 System.out.println("我是一条狗"); 10 } 11 }
1 package cn.wt.day10; 2 3 public class Dog extends Animal { 4 int num = 20; 5 6 @Override 7 public void eat() { 8 System.out.println("狗吃骨头"); 9 } 10 11 public void watchHouse(){ 12 System.out.println("狗看家"); 13 } 14 }
1 package cn.wt.day10; 2 3 public class Demon { 4 public static void main(String[] args) { 5 Animal dog = new Dog(); 6 System.out.println(dog.num); // 10 7 // dog 无法使用 Dog()中的watchHouse(), 原因:编译不通过 8 dog.eat(); 9 // show() 方法编译通过,在Dog类中找不到该方法,就向父类Animal中找 10 dog.show(); 11 } 12 }
五、种类
1、向上转型
就是上面的例子,可以看成变量的隐式类型转换
2、向下转型(可以看成变量的显示转换)
a、出现原因
上面的例子中,使用多态后,对象无法调用子类中有而父类中没有的成员方法
b、语法
父类名 对象名A = new 子类名(); 子类名 对象名B = (子类名) 对象名A;
c、例子
1 package cn.wt.day10; 2 3 public abstract class Animal { 4 int num = 10; 5 6 public abstract void eat(); 7 8 public void show(){ 9 System.out.println("我是动物"); 10 } 11 }
1 package cn.wt.day10; 2 3 public class Dog extends Animal { 4 int num = 20; 5 6 @Override 7 public void eat() { 8 System.out.println("狗吃骨头"); 9 } 10 11 public void watchHouse(){ 12 System.out.println("狗看家"); 13 } 14 }
1 package cn.wt.day10; 2 3 public class Demon { 4 public static void main(String[] args) { 5 Animal dog = new Dog(); 6 System.out.println(dog.num); // 10 7 // dog 无法使用 Dog()中的watchHouse(), 原因:编译不通过 8 dog.eat(); 9 // show() 方法编译通过,在Dog类中找不到该方法,就向父类Animal中找 10 dog.show(); 11 // 对象向下转型 12 Dog isDog = (Dog)dog; 13 isDog.watchHouse(); 14 } 15 }
d、问题
数据类型的强制类型转换会出现溢出的现象,对象的向下转型也会出现类似这种情况
狗->动物->狗
向上 向下
狗->动物->猫(错误),在不知道动物类型的情况下
六、instanceof
与pyhon中isinstance()函数用法相似
1、作用
解决上面的问题:不知道多态对象对应的子类是谁时,引起的错误
2、语法
对象 instanceof 类;
3、返回值类型
boolean
4、例子
1 package cn.wt.day10; 2 3 public abstract class Animal { 4 int num = 10; 5 6 public abstract void eat(); 7 8 public void show(){ 9 System.out.println("我是动物"); 10 } 11 }
1 package cn.wt.day10; 2 3 public class Dog extends Animal { 4 int num = 20; 5 6 @Override 7 public void eat() { 8 System.out.println("狗吃骨头"); 9 } 10 11 public void watchHouse(){ 12 System.out.println("狗看家"); 13 } 14 }
1 package cn.wt.day10; 2 3 public class Cat extends Animal { 4 @Override 5 public void eat() { 6 System.out.println("猫吃鱼"); 7 } 8 9 public void playMouse(){ 10 System.out.println("猫玩老鼠"); 11 } 12 }
1 package cn.wt.day10; 2 3 public class Demon { 4 public static void main(String[] args) { 5 Animal dog = new Dog(); 6 System.out.println(dog.num); // 10 7 // dog 无法使用 Dog()中的watchHouse(), 原因:编译不通过 8 dog.eat(); 9 // show() 方法编译通过,在Dog类中找不到该方法,就向父类Animal中找 10 dog.show(); 11 12 System.out.println("====================================="); 13 // 狗 14 showMessage(dog); 15 // 猫 16 Animal cat = new Cat(); 17 showMessage(cat); 18 } 19 20 public static void showMessage(Animal animal){ 21 if(animal instanceof Dog){ 22 ((Dog) animal).watchHouse(); 23 }else if (animal instanceof Cat){ 24 ((Cat) animal).playMouse(); 25 } 26 } 27 }
七、综合实例
1、电脑类 开启关闭电源、使用设备(符合)
2、USB接口 打开接口、关闭接口
3、鼠标类 实现接口、点击鼠标
4、键盘类 实现接口、写入文字
注意:向上转型可以自动完成,与变量的隐式转换相似
1 package cn.wt.day10.demon; 2 3 public class Computer { 4 public void PowerOn(){ 5 System.out.println("打开电脑"); 6 } 7 8 public void PowerOff(){ 9 System.out.println("关闭电源"); 10 } 11 12 public void useDevice(USB usb){ 13 usb.open(); 14 if(usb instanceof Mouse){ 15 ((Mouse) usb).click(); 16 }else if(usb instanceof KeyWord){ 17 ((KeyWord) usb).type(); 18 } 19 usb.close(); 20 } 21 22 }
1 package cn.wt.day10.demon; 2 3 public interface USB { 4 public abstract void open(); 5 public abstract void close(); 6 }
1 package cn.wt.day10.demon; 2 3 public class Mouse implements USB { 4 @Override 5 public void open() { 6 System.out.println("打开鼠标连接"); 7 } 8 9 @Override 10 public void close() { 11 System.out.println("关闭鼠标连接"); 12 } 13 14 public void click(){ 15 System.out.println("点击鼠标"); 16 } 17 }
1 package cn.wt.day10.demon; 2 3 public class KeyWord implements USB { 4 @Override 5 public void open() { 6 System.out.println("打开键盘连接"); 7 } 8 9 @Override 10 public void close() { 11 System.out.println("关闭键盘连接"); 12 } 13 14 public void type(){ 15 System.out.println("输入文字"); 16 } 17 }
1 package cn.wt.day10.demon; 2 3 public class Demon { 4 public static void main(String[] args) { 5 Computer computer = new Computer(); 6 computer.PowerOn(); 7 // 鼠标 8 USB useMouse = new Mouse(); 9 computer.useDevice(useMouse); 10 // 键盘, 使用匿名对象, 向上转型 自动转 11 computer.useDevice(new KeyWord()); 12 computer.PowerOn(); 13 } 14 }