现在的位置: 首页 > 综合 > 正文

java多态性深入理解

2018年09月29日 ⁄ 综合 ⁄ 共 1655字 ⁄ 字号 评论关闭

        运行时多态是面向对象程序设计代码重用的一个最强大机制,java多态性概念可以被说成“一个接口,多个方法”,java实现运行时多态性的基础是动态方法调度,它是一种在运行时而不是在编译期调用重载方法的机制。

        方法重写overriding和重载overloading是java实现多态的不同表现,重写是父类与子类之间多态性的一种表现,重载是一个类中多态性的一种表现。如果子类中一个方法与父类有相同的名称和参数,我们说该方法被重写了。子类的对象在使用该方法时,将调用子类中的定义,对它而言,父类中的定义被“屏蔽”了。如果在一个类中定义了多个同名的方法,它们或有不同的参数个数或不同的参数类型,则称为方法的重载,重载可以改变方法的返回值类型。

       当超类对象引用变量引用子类对象时,被引用对象的类型而不是引用变量的类型决定了调用谁的成员方法,但是这个被调用的方法必须是在超类中定义过的,也就是被子类覆盖的方法。(但是如果强制把超类转换成子类的话,就可以调用子类中新添加而超类中没有的方法了)。

       方法调用的优先级,由高至低依次为:this.method(o); super.method(o); this.method(super(o)); super.method(super(o));

示例如下:

class A{
	public String show(D obj){
		return ("A and D");
	}
	public String show(A obj){
		return ("A and A");
	}
}

class B extends A{
	public String show(B obj){
		return ("B and B");
	}
	public String show(A obj){
		return ("B and A");
	}
}

class C extends B{}
class D extends B{}

public class test {
	public static void main(String[] args) {
		A a1 = new A();
		A a2 = new B();
		B b = new B();
		C c = new C();
		D d = new D();
		
		System.out.println(a2.show(b)); 
		System.out.println(a2.show(c));
		System.out.println(a2.show(d));
		System.out.println(b.show(b));
		System.out.println(b.show(c));
		System.out.println(b.show(d));
	}
}

输出结果:

B and A
B and A
A and D
B and B
B and B
A and D

我们看System.out.println(a2.show(c));的结果为什么是B and A。根据调用的有衔接,先看this.method(o),其中this是a2,o是c,A中没有show(C c)方法,所以在看super.method(o),A没有super,所以再看this.method(super(o))方法,即A的show(B b),也没有此方法,在看A的show(A a),有该方法,但是”被引用变量的类型而不是引用变量的类型决定调用哪个方法“,a2引用了一个b变量,而b中重写了show(A a)方法,所以最后调用的是b的show(A
a)方法,输出为B and A。如果B中没有重写该方法,那么最后还是调用A中的show(A a)方法。

这里我们要注意一下,既然是”被引用变量的类型而不是引用变量的类型决定调用哪个方法“,那么为什么不一开始就按如下思路做呢?a2引用的是一个B变量,this.method(o)就是b.show(c),没有该方法,再看super.show(c),也就是a.show(c),也没有再看this.show(super(o))即b.show(b),有该方法,输出B and B。

因为”这个被调用的方法必须在超类中定义过,也就是被子类覆盖的方法“,B的show(B b)在A中定义过吗?没有!所以这么做是不对的!

抱歉!评论已关闭.