查看: 161|回复: 0

Java学习笔记(十一)面向对象---多态

[复制链接]
发表于 2020-2-16 09:54:28 | 显示全部楼层 |阅读模式
多态的体现

父类的引用指向了本身的子类对象。
父类的引用也可以接受本身的子类对象。
代码体现
  1. abstract class Animal {    public abstract void eat();}class Cat extends Animal {    @Override    public void eat() {        System.out.println("eat fish");    }}class Dog extends Animal {    @Override    public void eat() {        System.out.println("eat bone");    }}class Monkey extends Animal {    @Override    public void eat() {        System.out.println("eat banana");    }}public class Demo {    public static void main(String[] args) {        /*        Animal c = new Cat();        function(c);         */        function(new Cat());        /*        Animal d = new Dog();        function(d);        */        function(new Dog());        /*        Animal m = new Monkey();        function(m);        */        function(new Monkey());    }    public static void function(Animal a) {        a.eat();     }}
复制代码
运行结果
  1. eat fisheat boneeat banana
复制代码
多态的前提

必须是类与类之间有关系。要么是继续关系,要么实现。
存在复写关系。
多态利弊

利处

多态的出现大大地提高了程序的拓展性。
弊端

提高了拓展性,但是只能使用父类的引用访问父类中的成员,不能预先访问子类的成员(因为子类这时还不存在)。
多态-示例
  1. abstract class Student {    public void eat() {        System.out.println("eat rice");    }    public abstract void study();}class StudentToDo {    public void Do(Student s) {        s.eat();        s.study();    }}class StudentClass1 extends Student {    @Override    public void eat() {        System.out.println("eat steak");    }    @Override    public void study() {        System.out.println("study English");    }}class StudentClass2 extends Student {    @Override    public void study() {        System.out.println("study Chinese");    }}class StudentClass3 extends Student {    @Override    public void study() {        System.out.println("study Japanese");    }}public class Demo2 {    public static void main(String[] args) {        StudentToDo std =  new StudentToDo();        std.Do(new StudentClass1());        std.Do(new StudentClass2());        std.Do(new StudentClass3());    }}
复制代码
运行结果:
  1. eat steakstudy Englisheat ricestudy Chineseeat ricestudy Japanese
复制代码
多态的出现 代码中的特点(多态使用的注意事项

多态中成员函数的特点

在编译时期,参阅引用范例变量所属的类中是否有调用的方法,如果有编译通过,如果没有编译失败。
在运行时期,参阅对象所属的类中是否有调用的方法。
简单总结:成员函数在多态调用时,编译看左边,运行看右边。
  1. class Fu {    void method1() {        System.out.println("Fu_Method_1");    }    void method2() {        System.out.println("Fu_Method_2");    }}class Zi extends Fu {    @Override    void method1() {        System.out.println("Zi_Method_1");    }    void method3() {        System.out.println("Zi_Method_3");    }}public class Demo3 {    public static void main(String[] args) {        Fu f =new Zi();        f.method1();        f.method2();        //f.method3(); 对于引用范例f所属的类Fu中没有method3()方法,所以编译会不通过。    }}
复制代码
运行结果:
  1. Zi_Method_1Fu_Method_2
复制代码
多态中成员变量的特点

无论编译还是运行,都参考左边(引用型变量所属的类)
  1. class Fu {    int num = 1;}class Zi extends Fu {    int num = 2;}public class Demo4 {    public static void main(String[] args) {        Fu f = new Zi();        System.out.println(f.num);   //参考左边        Zi z= new Zi();        System.out.println(z.num);    }}
复制代码
运行结果:
  1. 12
复制代码
多态中静态成员函数(变量)的特点

无论编译还是运行,都参考左边。
静态范例,静态绑定。
非静态范例,动态绑定。
  1. class Fu {    static void method1() {        System.out.println("Fu_Method_1");    }}class Zi extends Fu {    static void method1() {        System.out.println("Zi_Method_1");    }}public class Demo5 {    public static void main(String[] args) {        Fu f = new Zi();        f.method1();        Zi z = new Zi();        z.method1();    }}
复制代码
运行结果:
  1. Fu_Method_1Zi_Method_1
复制代码
多态-转型
  1. abstract class Animal {    public abstract void eat();}class Cat extends Animal {    @Override    public void eat() {        System.out.println("eat fish");    }    public void CatchMouse() {        System.out.println("CatchMouse");    }}class Dog extends Animal {    @Override    public void eat() {        System.out.println("eat bone");    }    public void GuardHouse() {        System.out.println("GuardHouse");    }}class Monkey extends Animal {    @Override    public void eat() {        System.out.println("eat banana");    }    public void PlayBall() {        System.out.println("Play Ball");    }}public class Demo1 {    public static void main(String[] args) {        function(new Cat());        function(new Dog());        function(new Monkey());    }    public static void function(Animal a) {        a.eat();        if (a instanceof Cat) { //instanceof关键字用于判断所属范例            Cat c = (Cat)a;     //向下转型            c.CatchMouse();        } else if (a instanceof Dog) {            Dog d = (Dog)a;     //向下转型            d.GuardHouse();        } else {            Monkey m = (Monkey)a;//向下转型            m.PlayBall();        }    }}
复制代码
运行结果:
  1. eat fishCatchMouseeat boneGuardHouseeat bananaPlay Ball
复制代码
多态的应用

电脑主板为例的示例
分析电脑主板要思量到拓展性,使用了pci接口,板卡(声卡,网卡等)和主板都遵照pci接口。
  1. interface Pci {    public void open();    public void close();}class MainBoard {    public void run() {        System.out.println("Main Board run");    }    public void usePci(Pci p){ //接口范例指向本身的子类对象        if(p != null){    //加入判断防止空指针        p.open();        p.close();        }    }}class Netcard implements Pci {    @Override    public void open() {        System.out.println("Netcard open");    }    @Override    public void close() {        System.out.println("Netcard close");    }}class Soundcard implements Pci {    @Override    public void open() {        System.out.println("Soundcard open");    }    @Override    public void close() {        System.out.println("Soundcard close");    }}public class Demo6 {    public static void main(String[] args) {        MainBoard mb = new MainBoard();        mb.run();        mb.usePci(null);        mb.usePci(new Netcard());        mb.usePci(new Soundcard());    }}
复制代码
运行结果
  1. Main Board runNetcard openNetcard closeSoundcard openSoundcard close
复制代码

相关技术服务需求,请联系管理员和客服QQ:2753533861或QQ:619920289
您需要登录后才可以回帖 登录 | 用户注册

本版积分规则

帖子推荐:
客服咨询

QQ:2753533861

服务时间 9:00-22:00

快速回复 返回顶部 返回列表