JAVA语言特性笔记

来源:互联网 发布:win10双硬盘安装ubuntu 编辑:程序博客网 时间:2024/06/02 03:49

1、JAVA支持的多态性质主要是为两种:静态多分派和动态单分派。

  • 静态多分派在JAVA中的表现形式即:重载。主要由静态方法和私有方法构成(还有实例构造方法、父类方法)。他们的引用在类加载之初就已经被确定了。一个是类级别的,一个是私有方法,private访问限定了它不能被子类访问并覆写。

  • 动态单分派的表现形式为:覆写(Override)
两者的主要区别在于一个是编译期绑定,一个是运行期绑定。这也是为什么静态方法不能被覆写只能被隐藏。
因为静态方法本身是不依靠类的实例而存在的,我们可以通过类名直接访问它。看到一篇博文,觉得举的例子非常恰当。
public class Client {      public static void main(String[] args) {           Base base = new Sub();           //调用非静态方法           base.doAnything();           //调用静态方法           base.doSomething();      }  }  class Base{      //父类静态方法      public static void doSomething(){          System.out.println("我是父类静态方法");    }    //父类非静态方法      public void doAnything(){           System.out.println("我是父类非静态方法");      }  }  class Sub extends Base{      //子类同名、同参数的静态方法      public static void doSomething(){           System.out.println("我是子类静态方法");      }      //覆写父类的非静态方法      @Override      public void doAnything(){           System.out.println("我是子类非静态方法");      }  }点击打开链接
@来自http://www.cnblogs.com/DreamDrive/p/5428678.html


注意这里的Base base=new Sub();这一行代码,很明显这是典型的使用派生类,使用了父类的引用指向子类的对象,向上转型。其中,base的静态类型是Base,这个在编译期就已经确定,而实际类型Sub是在运行期才能确定的。

举个例子,Sub继承了父类Test,父类中有两个重载方法,一个参数类型是Test,一个是Sub。这时候我们调用这个重载方法,将Test test=new Sub();传入进去。前面我们提到了,静态分派的典型应用是重载,而这个例子中test的静态类型是Test,那么答案应该是多少呢?




没错,就是调用了Test类型的重载方法。因为重载是静态分派,所以它的类型在编译期就已经确定了,在确定使用哪一个重载方法的时候,是根据变量的静态类型来确定的。


动态分派:

前面提到了JAVA的动态分派是动态单分派,即在执行覆写的时候,只有一个宗量——参数。即参数是那个类型的,就覆写了哪一个方法。


还是刚才那个例子,只不过稍微改动了一下子类,添加了两个方法, 和Test中一样,一个静态方法和一个实例方法。当传入的类型是Sub时,调用了子类Sub中的test方法。

public class Test{public static String test(Test test){return "It's Test";}public String test(Sub sub){return "It's Sub";}    public static void main(String[]args) {    Test test=new Sub();    Test test2=new Test();    Sub sub=new Sub();    System.out.println(test.test(sub));    }}class Sub extends Test{public static String test(Test test){return "It's Sub Test";}public  String test(Sub sub){return "It's Sub Sub ";}}
输出:It's Sub Sub

静态方法:

那么如果传入Test类型的参数呢?

System.out.println(test.test(test));


我们改动一下,将main方法中最后一句的参数改成test2,看看结果:    It's test



这次却没有覆写父类的方法,调用的不再是子类中的test方法,而是父类中的方法,这是为什么呢?

这是因为就像我们前面提到的,静态方法和私有方法不能被覆写,他们在编译期就已经确定了类型,这时候又回到了最开始提到的静态分派的过程中。

私有方法:

和静态方法一样,都不执行覆写


类的成员变量:

在Test类和Sub类中, 分别加入public int i=1,=2;输出test.i,结果1。

因为类的成员变量也是一般的静态分派。


原创粉丝点击