zoukankan      html  css  js  c++  java
  • Java多态性理解

    什么是多态

    1. 面向对象的三大特性:封装、继承、多态。从一定角度来看,封装和继承几乎都是为多态而准备的。这是我们最后一个概念,也是最重要的知识点。
    2. 多态的定义指允许不同类的对象对同一消息做出响应。即同一消息可以根据发送对象的不同而采用多种不同的行为方式。(发送消息就是函数调用)
    3. 实现多态的技术称为:动态绑定(dynamic binding),是指在执行期间判断所引用对象的实际类型,根据其实际的类型调用其相应的方法。
    4. 多态的作用消除类型之间的耦合关系。
    5. 现实中,关于多态的例子不胜枚举。比方说按下 F1 键这个动作,如果当前在 Flash 界面下弹出的就是 AS 3 的帮助文档;如果当前在 Word 下弹出的就是 Word 帮助;在 Windows 下弹出的就是 Windows 帮助和支持。同一个事件发生在不同的对象上会产生不同的结果。

    下面是多态存在的三个必要条件,要求大家做梦时都能背出来!

    多态存在的三个必要条件 一、要有继承; 二、要有重写; 三、父类引用指向子类对象。

     多态的好处

    1.可替换性(substitutability)。多态对已存在代码具有可替换性。例如,多态对圆Circle类工作,对其他任何圆形几何体,如圆环,也同样工作。

    2.可扩充性(extensibility)。多态对代码具有可扩充性。增加新的子类不影响已存在类的多态性、继承性,以及其他特性的运行和操作。实际上新加子类更容易获得多态功能。例如,在实现了圆锥、半圆锥以及半球体的多态基础上,很容易增添球体类的多态性。

    3.接口性(interface-ability)。多态是超类通过方法签名,向子类提供了一个共同接口,由子类来完善或者覆盖它而实现的。如图8.3 所示。图中超类Shape规定了两个实现多态的接口方法,computeArea()以及computeVolume()。子类,如Circle和Sphere为了实现多态,完善或者覆盖这两个接口方法。

    4.灵活性(flexibility)。它在应用中体现了灵活多样的操作,提高了使用效率。

    5.简化性(simplicity)。多态简化对应用软件的代码编写和修改过程,尤其在处理大量对象的运算和操作时,这个特点尤为突出和重要。

    Java中多态的实现方式:接口实现,继承父类进行方法重写,同一个类中进行方法重载。

    一个小题目:继承父类进行方法重写的例子。

    (一)相关类

    复制代码
    class A ...{  
             public String show(D obj)...{  
                    return ("A and D");  
             }   
             public String show(A obj)...{  
                    return ("A and A");  
             }   
    }   
    class B extends A...{  
             public String show(B obj)...{  
                    return ("B and B");  
             }  
             public String show(A obj)...{  
                    return ("B and A");  
             }   
    }  
    class C extends B...{}   
    class D extends B...{}  
    复制代码

    (二)问题:以下输出结果是什么?

    复制代码
    A a1 = new A();  
            A a2 = new B();  
            B b = new B();  
            C c = new C();   
            D d = new D();   
            System.out.println(a1.show(b));   ①  //a1指向的类时A
            System.out.println(a1.show(c));   ②  
            System.out.println(a1.show(d));   ③  
            System.out.println(a2.show(b));   ④  //a2指向的类时B,B类直接超类是A而且重写了show(A OBJ)。所以当传入的参数是B对象的时候,调用B类从写的方法。
            System.out.println(a2.show(c));   ⑤  
            System.out.println(a2.show(d));   ⑥  
            System.out.println(b.show(b));    ⑦  
            System.out.println(b.show(c));    ⑧  //b指向的类是B,而C,D类的直接超类是B所以调用的是show(B OBJ)。
            System.out.println(b.show(d));    ⑨     
    复制代码

    (三)答案

    复制代码
    ①   A and A
    ②   A and A
    ③   A and D
    ④   B and A
    ⑤   B and A
    ⑥   A and D
    ⑦   B and B
    ⑧   B and B
    ⑨   A and D
    复制代码

    接口和抽象类的例子:

    对于抽象类和接口,有许多类实现这个接口(或者继承这个抽象类)。 在调用的时候,用父类引用指向子类对象的方法。然后,调用对象的方法,编译器就会自动根据这个对象实际属于哪个实现类, 来调出这个类对于接口或者抽象类的具体实现。
    例:

     public class Address {
     private String name; 
     public Address(String name){ this.name = name; }
     public String getName() { return name; }
     public void setName(String name) { this.name = name; }
     }


    定义基类(抽象类):

    public abstract class Vehicle { 
    abstract void go(Address address); 
    }
    //Car对于基类的实现: 
    public class Car extends Vehicle{ 
    @Override 
    public void go(Address address){ 
    System.out.println("Car to " + address.getName());
     }
     }


    Plane对于基类的实现: 

    public class Plane extends Vehicle{
     @Override 
    void go(Address address) 
    { System.out.println("Plane to " + address.getName());
     }
     }


     Driver中多态:

     public void drive(Vehicle v){                  
    ///多态,父类引用指向子类对象,实际传过来的是抽象类Vehicle的子类,或者实现类,然后编译器会根据具体实现类,来找实现方法。 
    v.go(new Address("杭州(abstract)"));    ///此方法在具体的实现中被重写 
    }
    Test: 
    public static void main(String[] args) { 
    Driver d = new Driver();
     d.drive(new Plane());   //实际是Plane对象,则编译器就会找到Plane中,对go的实现 d.drive(new Car());       //实际是Car对象,则编译器就会找到Plane中,对go的实现
     }


    输出结果: Plane to 杭州(abstract) Car to 杭州(abstract)
    事实上,这就是多态所起的作用,可以实现控制反转这在大量的J2EE轻量级框架中被用到,比如Spring的依赖注射机制。 (通过注入不同的bean,来得到不同的实现类)
    接口与抽象类的区别:
    有个概念,但还没有想到具体实现。 对于一些共用的,已经有实现了,可以设计成接口。
    上面是抽象类,下面把它转化为接口:
    IVehicle.java public interface IVehicle { public void go(Address address); }
    CarImpl.java public class CarImpl implements IVehicle{ public void go(Address address) { System.out.println("CarImpl to " +address.getName()); } }
    PlameImpl.java public class PlaneImpl implements IVehicle{ public void go(Address address) { System.out.println("PlaneImpl to " + address.getName()); } }
    Driver.java ////多态之接口 public void driveI(IVehicle v){ v.go(new Address("杭州(interface)")); }
    Test.java ////用接口实现 d.driveI(new PlaneImpl()); d.driveI(new PlaneImpl());
    打印结果: PlaneImpl to 杭州(interface) PlaneImpl to 杭州(interface)

    多态的三要素:1.继承  2.重写  3.父类引用指向子类对象

    以上就是我目前学习中的总结,如有不足之处,还望多多赐教。

  • 相关阅读:
    unity-TextAsset
    unity-热更-InjectFix
    进程和线程的区别
    StringBuffer 和 StringBuilder 的区别
    List、Set、Map 三者区别
    竞态条件是什么?
    多线程安全(synchronized、三大特性、生命周期以及优缺点)
    集合的同步与非同步
    List、Set、Map的了解及区别
    java面试题
  • 原文地址:https://www.cnblogs.com/hupp/p/4854918.html
Copyright © 2011-2022 走看看