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

2020-02-15 16:05:33来源:博客园 阅读 ()

新老客户大回馈,云服务器低至5折

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

多态的体现

父类的引用指向了自己的子类对象。
父类的引用也可以接受自己的子类对象。

代码体现

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();
     }
}

运行结果

eat fish
eat bone
eat banana

多态的前提

必须是类与类之间有关系。要么是继承关系,要么实现。
存在复写关系。

多态利弊

利处

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

弊端

提高了拓展性,但是只能使用父类的引用访问父类中的成员,不能预先访问子类的成员(因为子类这时还不存在)。

多态-示例

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());
    }
}

运行结果:

eat steak
study English
eat rice
study Chinese
eat rice
study Japanese

多态的出现 代码中的特点(多态使用的注意事项)

多态中成员函数的特点

在编译时期,参阅引用类型变量所属的类中是否有调用的方法,如果有编译通过,如果没有编译失败。
在运行时期,参阅对象所属的类中是否有调用的方法。
简单总结:成员函数在多态调用时,编译看左边,运行看右边。

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()方法,所以编译会不通过。
    }
}

运行结果:

Zi_Method_1
Fu_Method_2

多态中成员变量的特点

无论编译还是运行,都参考左边(引用型变量所属的类)

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
2

多态中静态成员函数(变量)的特点

无论编译还是运行,都参考左边。
静态类型,静态绑定。
非静态类型,动态绑定。

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();
    }
}

运行结果:

Fu_Method_1
Zi_Method_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();
        }
    }
}

运行结果:

eat fish
CatchMouse
eat bone
GuardHouse
eat banana
Play Ball

多态的应用

以电脑主板为例的示例
分析电脑主板要考虑到拓展性,使用了pci接口,板卡(声卡,网卡等)和主板都遵循pci接口。

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());
    }
}

运行结果

Main Board run
Netcard open
Netcard close
Soundcard open
Soundcard close

原文链接:https://www.cnblogs.com/liyuxin2/p/12313781.html
如有疑问请与原作者联系

标签:

版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有

上一篇:简单看看ThreadPoolExecutor原理

下一篇:面试题:HashSet、TreeSet 和HashMap 的实现与原理