Chinaunix首页 | 论坛 | 博客
  • 博客访问: 230904
  • 博文数量: 19
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 1182
  • 用 户 组: 普通用户
  • 注册时间: 2013-02-20 23:47
个人简介

如果人生是一条隐含马尔科夫模型,那维特比算法告诉我已经偏离最优路线了,但如果起点是现在呢?

文章分类

全部博文(19)

文章存档

2020年(2)

2014年(3)

2013年(14)

分类: Java

2013-02-21 00:46:38

 java中的重载就是说一个类里面有多个名字相同而参数列表不同的方法,重写是说同一个方法在子类里可以与父类有不同的行为,那jvm中是怎么实现的呢

        先来解释重载,

        

点击(此处)折叠或打开

  1. public class Overload{
  2.         static class Human{
  3.         }
  4.         static class Man extends Human{
  5.         }
  6.         static class Woman extends Human{
  7.         }
  8.         void sayHello(Human man){
  9.                 System.out.println("hello man");
  10.         }
  11.         void sayHello(Man man){
  12.                 System.out.println("hello gentleman");
  13.         }
  14.         void sayHello(Woman man){
  15.                 System.out.println("hello laddy");
  16.         }
  17.         public static void main(String[] args){
  18.                 Human man=new Man();
  19.                 Human woman=new Woman();
  20.                 Overload over=new Overload();
  21.                 over.sayHello(man);
  22.                 over.sayHello(woman);
  23.                 System.out.println("---------------------------");
  24.                 over.sayHello((Man)man);
  25.                 over.sayHello((Woman)woman);
  26.         }
  27. }


        over这个方法接收者对于参数类型为Man和Woman有不同的实现,请问上述代码在jvm执行时会是同样的结果吗?答案是不一样,因为=号左边的Human叫做静态类型,右边的new Man叫做实际类型,前者在编译期就以确定,后者得在运行期才可知,而重载是在编译期就确定了方法,因此第21,22行就选择了以作为以Human为参数的方法,同理:24,25分别选择以Man,Woman为参数的方法

        再接下来是重写,

        

点击(此处)折叠或打开

  1. public class Overwrite{
  2.         static class Human{
  3.                 void sayHello(){
  4.                 }
  5.         }
  6.         static class Man extends Human{
  7.                 void sayHello(){
  8.                         System.out.println("hello gentleman");
  9.                 }
  10.         }
  11.         static class Woman extends Human{
  12.                 void sayHello(){
  13.                         System.out.println("hello laddy");
  14.                 }
  15.         }
  16.         public static void main(String[] args){
  17.                 Human man=new Man();
  18.                 Human woman=new Woman();
  19.                 man.sayHello();
  20.                 woman.sayHello();
  21.         }
  22. }


        19,20行首先得确定方法接收者,由于编译期不能确定方法接收者,得等到运行期,这也就是为什么重写得等到运行期才能确定的原因,用javap命令大概会看到这么几行输出

点击(此处)折叠或打开

  1. public static void main(java.lang.String[]);
  2.     Code:
  3.        0: new #2 // class Overwrite$Man
  4.        3: dup
  5.        4: invokespecial #3 // Method Overwrite$Man."":()V
  6.        7: astore_1
  7.        8: new #4 // class Overwrite$Woman
  8.       11: dup
  9.       12: invokespecial #5 // Method Overwrite$Woman."":()V
  10.       15: astore_2
  11.       16: aload_1
  12.       17: invokevirtual #6 // Method Overwrite$Human.sayHello:()V
  13.       20: aload_2
  14.       21: invokevirtual #6 // Method Overwrite$Human.sayHello:()V
  15.       24: return
  16. }

aload_1,2就是加载new出来的那两个对象到栈顶,这样确定了方法接收者,再而按照从下到上(子类往父类走)的顺序确定方法,所以,方法签名完全一样(对应着静态类型也一样)但是由于方法接收者不一样,多态之重写就体现出来了

阅读(1872) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~