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

    多态又称Polymophism,poly意思为多,polymophism即多种形态的意思。一种类型引用因为指向不同的子类,表现出不同的形态,使用不同的方法。

    什么是多态

    多态建议我们编码时使用common interface(公共接口)而不是concrete implementation(具体实现)。如果我们依赖具体实现来编码,则当我们需要增加common interface的新的实现时,我们需要复制和改变已有代码。程序的可扩展性大大降低。

    StackOverflow上关于什么是多态的一个例子很容易记忆。

    public abstract class Human{
          ...
          public abstract void goPee();
    }
    /* 抽象方法goPee()对于Human没有实现,它只对男女这两个子类有具体的不同的实现。
    Human也是一个抽象类,因为人只有男或女这两个类,不能创建一个既不是男也不是女的Human。 所以我们通过使用抽象类延迟了实现。
    */ public class Female extends Human{ ... @Override public void goPee(){ System.out.println("Sit Down"); } } public class Female extends Human{ ... @Override public void goPee(){ System.out.println("Sit Down"); } } //创建一组人要去尿尿 public static void main(String[] args){ ArrayList<Human> group = new ArrayList<Human>(); group.add(new Male()); group.add(new Female()); // ... add more... // tell the class to take a pee break for (Human person : group) person.goPee(); }


    运行结果:

    Stand Up
    Sit Down
    ...

    Java如何实现多态

    Java支持实现多态的三个必要条件:继承(inheritance),重写(override),向上转型(upcasting)

    继承:

    java只支持单继承,即子类和超类之间的关系是“Is-a”的关系。

    重写:

    父类中的方法会原封不动地被子类继承拥有,但如果子类想做一定的修改,就需要采用方法的重写。父类中的某方法如果与子类中的方法有相同的名称和参数,则该方法被重写。

    如果需要在子类中使用被覆盖的父类方法,则可使用super()关键字。子类函数的访问修饰权限不能少于父类。(试想如果一个父类中的方法为public,而在子类中重写为private,则父类类型的引用变量不能调用子类实例对象的方法,导致出错。)

    向上转型:

    形象化理解即为超类实际上是子类的子集,因为超类的成员都是子类的成员,所以类似Animal cat = new Cat();这样的向上转型是安全的,因为父类引用变量可以操作的成员一定在子类中。与此相反的向下转型则需要使用Instanceof来判断是否安全。

    动态绑定:

    动态绑定又称后期绑定,是指编译器在编译期间不知道要调用哪个方法,直到运行时才能确定。方法的动态绑定是基于实例对象类型,而不是对象引用的类型。基本上实例方法都在运行时绑定,而private方法,static方法,final方法都在编译时期绑定,称为静态绑定或后期绑定。这也是为什么private, static, final方法不允许重写。

    当超类对象引用变量引用子类的对象时,被引用对象的类型而不是引用变量的类型决定了调用谁的成员方法,但是这个被调用的成员方法必须在超类中定义过,也就是说被子类覆盖的方法。

    总结:

    以上机制允许java运行期间执行某个类的成员方法,而不是编码时期声明类型决定。(Method overriding allows java invoke method based on a perticular object at run-time instead of declared type while coding.)

    例子:

    public class TradingSystem{
       public String getDescription(){
          return "electronic trading system";
       }
    }
    
    public class DirectMarketAccessSystem extends TradingSystem{
       public String getDescription(){
         return "direct market access system";
       }
    }
    
    public class CommodityTradingSystem extends TradingSystem{
       public String getDescription(){
         return "Futures trading system";
       }
    }

    何时使用多态:

    1. 使用超类作为方法参数,可以在方法内调用不同类的成员方法。
      public void showDescription(TradingSystem tradingSystem){
         tradingSystem.description();
      }
    2. 使用超类声明变量,可以接收Factory method的返回值。
      String systemName = Configuration.getSystemName();
      TradingSystem system = TradingSystemFactory.getSystem(systemName);
    3. 使用超类作为返回值
      public TradingSystem getSystem(String name){
         //code to return appropriate implementation
      }

    这篇文章提供了一个很好的例子

    对于Java实现讲解的好文章

    参考文章:

      What is polymorphism in Java? Method overloading or overriding?

      动态绑定vs静态绑定

      Java中重载与重写的区别

      Java 重写(Override)与重载(Overload)

      Java多态性详解--父类引用子类对象

     

  • 相关阅读:
    Element-UI饿了么时间组件控件按月份周日期,开始时间结束时间范围限制参数
    揭秘(爱奇艺、优酷、腾讯)在线视频网站视频2倍速、多倍速快速播放的前端实现方法
    提高敲代码的效率:程序员同扭曲时间的事儿抗争
    原生JS在网页上复制的所有文字后面自动加上一段版权声明
    .net core kafka 入门实例 一篇看懂
    聊聊Grpc使用中的坑以及怎么填
    MongoDB 上手开发实践(入门上手就这一篇)
    聊聊redis实际运用及骚操作
    .NET Core 微服务之Polly熔断策略
    .NET Core 微服务之Polly重试策略
  • 原文地址:https://www.cnblogs.com/jxzheng/p/5198495.html
Copyright © 2011-2022 走看看