Java多态的经典实例分析

版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/elice_/article/details/82888630

目录

一、多态的表现形式

二、重载和重写的简单介绍

1.重载(overload)

2.重写(override)

三、向上转型和向下转型的简单介绍

1.向上转型

2.向下转型

四、在多态中方法的调用机制

五、实例的分析

1.继承关系

2.new对象的分析

3.对于方法的调用


一、多态的表现形式

两种

1.方法的重载和重写

2.对象的多态性(向上转型和向下转型)

二、重载和重写的简单介绍

1.重载(overload)

        1)在同一个类中

        2)有两个或两个以上重名的方法

        3)但是方法的参数个数、类型、顺序至少有一个不一样

2.重写(override)

        1)发生在继承关系当中,子类对父类的方法进行的重新定义

        2)子类中的某些方法与父类中的某些方法,方法名,参数列表完全一致,即使方法体内部没有改变,或者是空方法体也是重写

三、向上转型和向下转型的简单介绍

1.向上转型

子类引用的对象转换为父类类型称为向上转型。通俗地说就是是将子类对象转为父类对象。此处父类对象可以是接口。

Father f=new Son();    //向上转型

2.向下转型

向下转型是把父类对象转为子类对象。

Animal a=new Animal();

Dog g=(Dog)a;    //向下转型

四、在多态中方法的调用机制

1.不发生继承的类调用方法时,调用哪个就用哪个,如果发生了重载,那么,可以根据参数个数,类型,顺序判断到底调用了哪一个方法

2.当发生了继承关系,但是没有向上,向下转型时,子类对象调用的方法,要么是自身独有的,要么就是自身重写的,如果没有重写,那么也会直接调用父类的方法;而父类对象则只能调用自身的方法,而无法使用子类的方法。

3.如果发生了继承,并且有向上转型的对象,那就秉承着一个原则,即:编译看左边,运行看右边。

也就是说,首先看父类中这个被调用的方法在哪里,当父类中存在这个方法时,才可以调用,并且要继续看子类中是否重写了该方法,如果重写了,就调用重写后的方法。

总结:

当超类对象引用变量引用子类对象时,被引用对象的类型而不是引用变量的类型决定了调用谁的成员方法,但是这个被调用的方法必须是在超类中定义过的,也就是说被子类覆盖的方法,但是它仍然要根据继承链中方法调用的优先级来确认方法,该优先级为:this.show(O)、super.show(O)、this.show((super)O)、super.show((super)O)。

this.show(O)本类中是否有该方法

super.show(O)本类的父类中是否有该方法

this.show((super)O)本类中是否有参数父类的方法(即现在参数的父类类型作为参数的方法)

super.show((super)O)本类的父类中是否有参数父类的方法

五、实例的分析

package test;

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();
	   
	        a1.show(b);//"A and A"
	        System.out.println(a1.show(b));//A and A
	        a1.show(c);//"A and A"
	        System.out.println(a1.show(c));//a and A
	        a1.show(d);//"A and D"
	        System.out.println(a1.show(d));//A and D
		
	        a2.show(b);//"B and B"错了
	        System.out.println(a2.show(b));//B and A
		a2.show(c);//"B and B"错了
		System.out.println(a2.show(c));//B and A
		a2.show(d);//"A and D
		System.out.println(a2.show(d));//A and D
		
	        b.show(b);//"B and B"
	        System.out.println(b.show(b));//B and B
		b.show(c);//"B and B"	
		System.out.println(b.show(c));//B and B
		b.show(d);//"A and D"	 
		System.out.println(b.show(d));//A and D
	}

}

注释的部分分别是我猜测的答案和真是输出的答案。

下面分块说明

1.继承关系

A是B的父类,B是C和D的父类

并且C,D没有重写B的任何方法,也没有自身的方法

B对A进行了方法的重写show(A obj)

单独看B,它的两个show方法就属于重载

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 {
}

2.new对象的分析

由于调用方法只用到了这三个对象,因此只看这三个。

a1单纯的A对象

a2发生了向上转型,A引用B的对象

b单纯的B对象

                A a1 = new A();  
	   
		A a2 = new B();  
	   
		B b = new B();

3.对于方法的调用

  1)a1对象调用,以a1.show(b)为例,首先A中并没有show(B obj)的方法,A继承于Object类,其中也没有show(B obj)。

        那么由于B继承于A,看A中是否有show(A obj),好的,有,那么就调用该方法,输出“A and A”

                System.out.println(a1.show(b));//A and A
	        System.out.println(a1.show(c));//A and A
	        System.out.println(a1.show(d));//A and D

2)a2对象调用,以a2.show(b)为例,因为是向上转型,那么遵循,编译看左,运行看右的原则,在父类A中没有show(B obj)方法,但同样的有show(A obj),因此要调用该方法;又因为在B中重写了A中的show(A obj),因此在调用的时候就调用了子类重写的show(A obj),输出“B and A”

		
	        System.out.println(a2.show(b));//B and A
		System.out.println(a2.show(c));//B and A
		System.out.println(a2.show(d));//A and D

3)b对象调用,以b.show(b)为例,在B中恰好就有show(B obj)的方法,因此就输出"B and B"

		System.out.println(b.show(b));//B and B
		System.out.println(b.show(c));//B and B 
		System.out.println(b.show(d));//A and D

 

 

展开阅读全文

没有更多推荐了,返回首页