一、多态的概述以及使用 啥叫多态?左父右子,就叫多态。此处联想css中的子绝父相。
代码当中提现多态性,其实就是一句话:父类引用指向子类对象
格式:
或者
Fu.java
1 2 3 4 5 6 7 8 public class Fu { public void method () { System.out.println ("父类方法" ); } public void methodFu () { System.out.println ("这是父类特有的方法" ); } }
Zi.java
1 2 3 4 5 6 public class Zi extends Fu { @Override public void method() { System .out.println("子类方法" ); } }
Demo01Multi.java
1 2 3 4 5 6 7 8 9 10 11 public class Demo01Multi { public static void main (String [] args) { Fu obj=new Zi(); obj.method(); obj.methodFu(); } }
二、多态中成员变量使用特点 访问成员变量的两种方式:
直接通过对象名称访问成员变量:看等号左边是谁,优先用谁,没有则向上找 间接通过成员方法访问成员变量:看该方法属于谁,优先用谁,没有则向上找 Fu1.java
1 2 3 4 5 6 public class Fu1 { int num=10 ; public void method() { System.out .println("父类" +num); } }
Zi1.java
1 2 3 4 5 6 7 public class Zi1 extends Fu1 { int num=20 ; @Override public void method() { System .out.println("子类" +num); } }
Demo02MultiField.java
1 2 3 4 5 6 7 8 9 10 11 12 public class Demo02MultiField { public static void main (String [] args) { Fu1 obj=new Zi1(); System.out.println (obj.num); obj.method(); Zi1 zi=new Zi1(); System.out.println (zi.num); zi.method(); } }
三、多态中成员方法的使用特点 在多态的代码当中,成员方法的访问规则:
看new的是谁,就优先用谁,没有则向上找
口诀:编译看左边,运行看右边
对比:
成员变量:编译看左边,运行还看左边
成员方法:编译看左边,运行看右边
Fu2.java
1 2 3 4 5 6 7 8 9 public class Fu2 { public void method () { System.out.println ("父类方法" ); } public void methodFu () { System.out.println ("父类特有的方法" ); } }
Zi2.java
1 2 3 4 5 6 7 8 9 10 public class Zi2 extends Fu2 { @Override public void method() { System .out.println("子类方法" ); } public void methodZi() { System .out.println("子类特有方法" ); } }
Demo03MultiMethod.java
1 2 3 4 5 6 7 8 9 10 11 12 public class Demo03MultiMethod { public static void main (String [] args) { Fu2 obj=new Zi2(); obj.method(); obj.methodFu(); Zi2 zi=new Zi2(); zi.methodZi(); } }
四、使用多态的好处 如果不用多态,只用子类,那么写法是:
1 2 3 4 Teacher one = new Teacher (); one.work(); Assistant two = new Assistant (); two.work();
我现在唯一要做的事情,就是调用work方法,其他的功能不关心。
如果使用多态的写法,对比一下:
1 2 3 4 Employee one = new Teacher (); one.work(); Employee two = new Assistant (); two.work();
好处:
无论右边new的时候换成哪个子类对象,等号左边调用方法不会发生变化
五、对象的向上转型与向下转型 向上转型 对象的向上转型,其实就是多态写法:
1 2 3 4 父类名称 对象名 = new 子类名称();
含义:右侧创建一个子类对象,把它当做父类来看待使用。
注意事项:向上转型一定是安全的。 从小范围转向了大范围,从小范围的猫,转向了更大范围的动物。
类似于:
向下转型 对象的向下转型,其实是一个【还原】的动作
格式:
1 2 3 4 子类名称 对象名 = (子类名称) 父类对象;// 其实类似于 int a = (double) 10.0 ; // Animal animal = new Cat();// 本来是猫,向上转型为动物// Cat cat = (Cat) animal;// 本来是猫,已经被当做动物了,还原为本来的猫
含义:将父类对象,【还原】成为本来的子类对象。
注意事项:
必须保证对象本来创建的时候,就是猫,才能向下转型成为猫 如果对象创建的时候本来不是猫,现在非要向下转型为猫,就会报错。java.lang.ClassCastException 类似于:
1 2 int num = (int ) 10.0 ;int num = (int ) 10.5 ;
Animal.java
1 2 3 4 public abstract class Animal { public abstract void eat ( ) ; }
Cat.java
1 2 3 4 5 6 7 8 9 10 11 12 13 public class Cat extends Animal { @Override public void eat() { System .out.println("猫吃鱼" ); } public void catchMouse() { System .out.println("猫抓老鼠" ); } }
Demo04Main.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 public class Demo04Main { public static void main (String [] args) { Animal animal = new Cat(); animal.eat(); Cat cat = (Cat) animal; cat.catchMouse(); } }
六、instanceof判断类型 如何才能知道一个父类引用的对象,本来是什么子类?
格式:
这将会得到一个boolean值结果,也就是判断前面的对象能不能做后面类型的实例
向下转型,一定要进行instanceof判断,否则,可能会出现转换异常
Animal.java跟Cat.java跟上面那个是一个类,直接看Instanceof类
Demo02Instanceof.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 public class Demo02Instanceof { public static void main (String[] args) { Animal animal = new Cat(); animal.eat(); giveMeAPat(animal); } public static void giveMeAPat (Animal animal) { if (animal instanceof Dog) { Dog dog = (Dog) animal; dog.watchHouse(); } if (animal instanceof Cat) { Cat cat = (Cat) animal; cat.catchMouse(); } } }
七、接口多态综合案例 USB.java
1 2 3 4 5 6 7 public interface USB { public abstract void open ( ) ; public abstract void close ( ) ; }
Mouse.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 public class Mouse implements USB { @Override public void open () { System.out.println("打开鼠标" ); } @Override public void close () { System.out.println("关闭鼠标" ); } public void click () { System.out.println("鼠标点击" ); } }
Keyboard.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 public class Keyboard implements USB { @Override public void open () { System.out.println("打开键盘" ); } @Override public void close () { System.out.println("关闭键盘" ); } public void type () { System.out.println("键盘输入" ); } }
Computer.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 public class Computer { public void powerOn () { System.out.println ("笔记本电脑开机" ); } public void powerOff () { System.out.println ("笔记本电脑关机" ); } public void useDevice (USB usb) { usb.open (); if (usb instanceof Mouse ) { Mouse mouse = (Mouse ) usb; mouse.click (); } else if (usb instanceof Keyboard ) { Keyboard keyboard = (Keyboard ) usb; keyboard.type(); } usb.close (); } }
DemoMain.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 public class DemoMain { public static void main (String [] args) { Computer computer = new Computer(); computer.powerOn(); USB usbMouse = new Mouse (); computer.useDevice(usbMouse); Keyboard keyboard = new Keyboard (); computer.useDevice(keyboard); computer.powerOff(); System.out.println ("==================" ); method(10.0 ); method(20 ); int a = 30 ; method(a); } public static void method (double num) { System.out.println (num); } }
八、多态的练习题 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 package homework;class A { public String f (D obj) { return ("A and D" ); } public String f (A obj) { return ("A and A" ); } } class B extends A { public String f (B obj) { return ("B and B" ); } public String f (A obj) { return ("B and A" ); } } class C extends B { } class D extends B { } public class Homework02 { public static void main (String[] args) { A a1=new A(); A a2=new B(); B b=new B(); C c=new C(); D d=new D(); System.out.println(a1.f(a1)); System.out.println(a1.f(b)); System.out.println(a1.f(c)); System.out.println(a1.f(d)); System.out.println(a2.f(a1)); System.out.println(a2.f(b)); System.out.println(a2.f(c)); System.out.println(a2.f(d)); System.out.println(b.f(a1)); System.out.println(b.f(b)); System.out.println(b.f(c)); System.out.println(b.f(d)); } }