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

    深入理解Java中的多态机制

    在面向对象的程序设计语言中,多态是继数据抽象和继承之后的第三种基本特征

    引言:

    多态通过分离做什么和怎么做,从还有一个角度将接口和实现分离开来。多态不但可以改善代码的组织结构和可读性。还可以创建可扩展的程序--即不管在项目最初创建时还是在须要时加入新功能时都可以“生长”的程序。


    本文文件夹大纲:

    一、什么是多态

    二、多态的类别

    三、多态的产生方式

    四、执行期多态必要条件

    五、向上转型

    六、向下转型

    七、动态多态的适用范围

    八、多态的优点



    1、什么是多态

    多态(Polymorphism),按字面的意思就是多种状态简单而通俗的说。就是一句话:同意将子类类型的指针赋值给父类类型的指针。


    2、多态的类别

    编译期多态(静态多态,早期绑定)和执行期多态(后期绑定);


    绑定:将一个方法调用同一个方法主体关联起来被称做绑定。


    前期绑定:在程序运行前绑定(由编译器和连接程序实现),称作前期绑定。它是面向过程的语言中不须要选择就默认的绑定方式。列入C仅仅有一种方法调用,那就是前期绑定。


    后期绑定:在执行时依据对象的类型进行绑定。

    后期绑定也称作动态绑定或执行时绑定。

    它通过某种特殊机制实现,即程序一直不知道对象的类型。可是方法调用机制调用机制能找到正确的方法体,并加以调用。


    Java中除了static 方法和final 方法(private 属于final 方法)之外,其它全部方法都是后期绑定。这意味着通常情况下,我们不必判定是否应该进行后期绑定--它会自己主动发生。


    3、多态产生的方式


    3.1、强制的:一种隐式做类型转换的方法。


            强制多态隐式的将參数按某种方法,转换成编译器觉得正确的类型以避免错误。

    在一下的表达式中,编译器必须决定二元运算符‘+’所应做的工作:        

    [java] view plain copy

    1.  int a = 1 + 2;  

    2.  double d = 2.0 + 2.0;  

    3.  String s = "abc" + "def";  

    跟据须要判定"+ " 运算符所要进行的运算,(1和(2行中进行加法运算,(3中进行字符串连接运算

     

    3.2、编译期多态(重载  overload):


    静态多态性:包含变量的隐藏、方法的重载(指同一个类中,方法名同样(方便记忆),可是方法的參数类型、个数、次序不同,本质上是多个不同的方法)

    举例:

    public class override{
          public void show( ){
          };
          public void show( int i){
               System.out.println("含參数的show方法 .");
          };
    }


    通过传入不同參数,让程序依据传入的參数来表现出不同的状态。进而实现多态。


    3.3、执行期多态(重写 override)


    动态多态性:是指子类在继承父类(或实现接口)时重写了父类(或接口)的方法,程序中用父类(或接口)引用去指向子类的详细实例,从代码形式上看是父类(或接口)引用去调用父类(接口)的方法,可是在实际执行时,JVM可以依据父类(或接口)引用所指的详细子类。去调用相应子类的方法,从而表现为不同子类对象有多种不同的形态。

    只是,程序代码在编译时还不能确定调用的哪一个类的方法。仅仅有在执行时才干确定,故又称为执行时的多态性。


    举例:

    public classsup {
       public void show(){
          System.out.println("show() in sup !");
       }
    }
    public classsub extendssup{
       public void show(){
          System.out.println("show() in sub !");
       }
    }
    public classClient {
     
       public static void main(String[] args) {
         
          supsp= new sup();
          subsb = new sub();
          sups = new sub();
         
          sp.show();
          sb.show();
          s.show();
       }
    }


    执行结果:

    show() in sup !

    show() in sub !

    show() in sub !

     

    第三行代码。尽管编译是sup类,但执行的却是sub的show()方法。通过方法的重载。让程序表现出不同的状态,来体现程序的多态性。


    4、执行期多态必要条件

    一、要有继承(包含接口的实现);
    二、要有重写;
    三、父类引用指向子类对象。

     

    5、向上转型

              子类自有的方法不可见

             1)、代码检查不同意。

             2)、从实际意义上


    在以下代码中。s仅仅能调用sup中曾声明过的方法。而子类中新添加的所独有的方法则并不可见,自然也无法调用。


    sup s = new sub();

    s.show();


     

    6、向下转型

              存在于继承中,父类引用指向的对象实际是要转型的子类引用的类型。

     

    如果如今已经定义一个了Animal类,而且定义类Dog和类Cat继承Animal.


    [java] view plain copy

    1.  1)  Animal a = new Dog();  

    2.    

    3.        Dog d = (Dog) a;    //正确  

    4.    

    5.  2) Animal a = new Cat();  

    6.    

    7.        Dog d = (Dog) a;    //抛异常    


    对于一个由向上转型而来的对象,假设对它实行向下转型,须要知道该对象之前的类型。否则编译器会报错。如上述代码所描写叙述一样。


    7、动态多态的适用范围


    1、仅仅适用于动态方法,对于变量不能被重写(覆盖)。”重写“的概念仅仅针对方法,如 变量不能被重写(覆盖)

    2、静态static方法属于特殊情况域不会有多态机制。所调用的方法依据编译时採用的类型所确定。


    以下通过代码解释:

    /*
    例子1:
      classParent{
         int num = 3;
      }
     
      classChild extends Parent{
         int num = 4;
      }
    */
     
    /*
    例子2:
    class Parent{
     
    }
     
    class Child extends Parent{
        intnum = 4;
    }
    */
     
    /*
    例子3:
    class Parent{
        void show(){
            System.out.println("ParentShow!");
         }
      }
     
      classChild extends Parent{
        void show(){
            System.out.println("ChildShow!");
         }
      }
    */
     
    /*
    例子4:
    class Parent{
        
      }
     
      class Child extends Parent{
        voidshow(){
            System.out.println("ChildShow!");
         }
      }
    */
     
     
    class Parent{
        static void show(){
            System.out.println("ParentShow!");
         }
      }
     
      class Child extends Parent{
        static void show(){
            System.out.println("ChildShow!");
         }
      }
     
     
    public class PC{
       public static void main(String[] args){
            Parentp = new Child();
            //例子1:
            //System.out.println(p.num);//3。 输出的是父类的num。
             
            //例子2:
            //System.out.println(p.num);//错误: 找不到符号 num
             
            //例子3:
            //p.show();//ChildShow!  输出的是子类的方法。
             
            //例子4:
            //p.show();//  错误: 找不到符号   p.show();
             
            //例子5:
            p.show();//Parent Show!  执行父类的静态方法。

    } } /*



    总结:

    对象多态时:

    1.成员变量:(不涉及覆盖)

    编译时: 參考引用变量所属的类中是否有调用的成员变量,有, 编译通过。没有。编译失败。

    执行时: 參考引用变量所属的类中是否有调用的成员变量。 并执行该类所属中的成员变量。

    简单的说:编译和执行都參考等号的左边。


    2.成员函数(非静态):

    编译时:參考引用变量所属的类中是否有调用的成员变量。 有, 编译通过。 没有,编译失败:

    执行时:參考的是对象所属的类中是否有调用的函数。

    简单的说:编译看左边, 执行看右边。


    3.静态函数。 变量:

       编译和执行都是參考左边參数类型!

       事实上静态方法不存在多态。 静态方法是属于类的,我们说的是对象的多态!静态方法直接用类名调用就好了,

       不是必需创建对象!

       静态的方法仅仅能被静态的方法所覆盖!

     

    8、多态的优点


    1.可替换性(substitutability)。多态对已存在代码具有可替换性。比如,多态对圆Circle类工作,对其它不论什么圆形几何体,如圆环。也相同工作。


    2.可扩充性(extensibility)。多态对代码具有可扩充性。

    添加新的子类不影响已存在类的多态性、继承性。以及其它特性的执行和操作。实际上新加子类更easy获得多态功能。比如。在实现了圆锥、半圆锥以及半球体的多态基础上,非常easy增添球体类的多态性。


    3.接口性(interface-ability)。

    多态是超类通过方法签名,向子类提供了一个共同接口。由子类来完好或者覆盖它而实现的。

    如图8.3 所看到的。图中超类Shape规定了两个实现多态的接口方法,computeArea()以及computeVolume()。子类,如Circle和Sphere为了实现多态,完好或者覆盖这两个接口方法。


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


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



    參考资料:http://www.cnblogs.com/hujunzheng/p/3872619.html

  • 相关阅读:
    asp.net 读取Excel文档
    ASP.NET实现IE下禁用浏览器后退按钮办法
    asp.net 追加文本(追加写入记事本)
    Sql Server中charindex、patindex的区别
    css3 简单动画
    ie6下兼容问题
    IE6下 input 背景图滚动问题及标签规范
    css2---必须学的经典---定位问题
    EF 用CallContext上下文管理
    EF查询分页
  • 原文地址:https://www.cnblogs.com/wzjhoutai/p/7283093.html
Copyright © 2011-2022 走看看