您的位置:首页 > 编程语言 > Java开发

参数类型对java用继承实现多态时的影响

2015-07-18 22:40 453 查看
    最近对java父子类关系以及继承和多态有了新的理解。

   java多态有两种形式,一种是通过方法重载实现的编译时多态,另一种是通过类之间的继承、方法重写以及晚联编技术实现的运行时多态。

   对于被子类重写的、父类中的无参的方法不是本次讨论的对象,对于这个,因为是父类的引用指向了子类,当然是这次是关于类的继承以及父子类调用的一个test。调用了子类重写的方法,而父类中的原本的方法被隐藏了。

  
这次是关于方法含参且重写后父子类的方法参数不同的一个test。

class a{
void fun(b B){
System.out.println("a and B");
}
void  fun(a A){
System.out.println("A and a");
}
}
class b extends a{
void fun(b B){
System.out.println("b and B");
}
void fun(a A){
System.out.println("b and a");
}
void fun(bb B){
System.out.println("a don't have this fun");
}
}

class bb extends a{
void fun(bb B){
System.out.println("a  and bb");
}
}
class c{
void fun(a A ){
System.out.println("funa");
}
void fun(b B){
System.out.println("funb");
}
}
class d extends b{
void fun(d D){
System.out.println("d and d");
}
}

public class Main{
public 	static  void main(String[] args){
a A = new a();
b B = new b();
a A1 = new b();
c C = new c();
d D = new d();
A.fun(B);//NO.1
B.fun(B);//NO.2
A1.fun(B);//NO.3
A1.fun(D);//NO.4
C.fun(A);//NO.5
C.fun(B);//NO.6

bb BB = new bb();
B.fun(BB);//NO.7
A.fun(BB);//NO.8
A1.fun(BB);//NO.9

}
}


下图是运行结果:

a and B   //NO.1
b and B   //NO.2
b and B   //NO.3
b and B   //NO.4
funa      //NO.5
funb      //NO.6
a don't have this fun  //NO.7
A and a   //NO.8
b and a   //NO.9


NO.1和NO.2实例化的就是父类和子类的对象,所以执行的就是该类本身的方法,没有实现多态。

NO.3中子类重写了父类的方法,调用的子类的方法,即实现了多态。

NO.4中,d是b的子类,而b又是a的子类,也就是d是a的子类的子类。由于b重写了a类方法,由NO.3可知,会调用b中的方法。可b中有参数为a的fun方法,也有参数为b的fun方法,究竟调用的是哪一个?从结果上看,它调用的是参数为b的方法,也就是将它匹配到了它亲爸那而不是它爷爷那......从这里也可以看出,两种类型有继承关系,即在继承树的同一个分支上时,java会自动进行类型转换的。

至于NO.5和NO.6,说明方法的执行并没有因为a、b是父子类而受到影响,总是绑定到关系最近、最精确的那一个。

NO.7中,类b中有参数为bb的方法,所以输出该结果。

而NO.8中,a类没有参数类型为bb的方法,所以道理同NO.4,执行了参数为bb父类的方法即参数为a的方法。

NO.9由于A1是指向了子类b的一个引用,但是并没有绑定参数类型为bb的fun()方法,这是因为指向子类的父类引用不能调用子类特有的方法(编译时会报错),而事实上这个参数类型为bb的方法也不是重写的父类方法,而是子类中的重载

   又看到一篇讨论静态变量和静态方法的绑定规则的文章,感觉不错,贴出来~

   行时环境中,通过引用类型变量来访问所引用对象的方法和属性时,Java虚拟机采用以下绑定规则:

   1, 实例方法与引用变量实际引用的对象的方法绑定,这种绑定属于动态绑定,因为是在运行时由Java虚拟机动态决定的 。

   2, 静态方法与引用变量所声明的类型的方法绑定,这种绑定属于静态绑定,因为实际上是在编译阶段就已经绑定 。

   3, 成员变量(静态变量,实例变量)与引用变量所声明的类型的成员变量绑定,这种绑定属于静态绑定,因为实际上是在编译阶段就已经绑定 。

  
戳这儿  http://edison-cool911.iteye.com/blog/1131204
  



内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: