本文由个人编制。转载请说明出处.
狠人话不多。直接上代码!
public class Demo7 {
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(a1.show(c));
System.out.println(a1.show(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));
}
}
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{}
运行结果是:
A and A
A and D
B and A
B and A
个人俗气一点的讲解,如由不对,欢迎指出:
遇到这种问题看继承链: C -> B -> A ; D -> B -> A;
下边这段话是重中之重!!看不懂的同学请移步 搜索: 菜鸟教程之JAVA!
在看new对象!:: A 名称 = new A() ; 分两部分看, ( A 名称 ) 我们称为引用, = 等于号后边的 ( new A() )称为创建该对象。
接下来是重点!:
注: 本文的粗体字体都是最重点的,因为它连起来是一个解决 如何理解多态 的方法。
(1)a1.show(c)的解析
A a1 = new A(); 它 new的A()对象,所以别管其他的。直接看 A对象的方法,
A对象里边有两个方法。唯独没有 一个这样的方法:public String show(C obj){
return ("A and C"); } ,你可以自己新增一个,如果有,控制台会输出 A and C。
但我们没有,怎么办? 从继承链看是 C对象 继承了 A对象 。又因为上边我们提到了 ( A 名称 ) 我们称为引用 ,引用的类是 A 类,所以 C对象被提升到 A对象,这是因为 多态 使得 C对象 可以被提升到 父类的对象。从而 识别这个方法: public String show(A obj){ return ("A and A");} ,控制台输出 A and A.
(2)a1.show(d)的解析
这个是最基本的了把。方法里边有个 public String show(D obj){ return ("A and D"); }
直接识别。因为你 new A()对象,看A对象的方法,有的话直接使用.
这道题事实上可以不用多态,不信可以 把 class D extends B{} 删了 extends B 这代码,看还是不是 控制台输出 A and D.也可以从多态理解.
(3)a2.show(b).难点在这:
看 A a2 = new B(); new的是B 对象, 但引用的是 A 类。而 b 对应: B b = new B();
可能你以为是输出 B and B。为什么是 B and A?
按上边我讲解的 (1)!(1)!(1)! 的方法来讲解:
从继承链看是 B对象 继承了 A对象 。又因为上边我们提到了 ( A 名称 ) 我们称为引用 ,引用的类是 A 类,所以 B 对象被提升到 A对象,这是因为 多态 使得 B对象 可以被提升到 父类的对象。从而 识别这个方法: public String show(A obj){ return ("B and A");} ,控制台输出 B and A.
是不是很熟悉,这段话。没错,它就是讲解 (1) 所用的方法。
你可能觉得我在胡说八道:那请你 修改一个这段代码:
A a2 = new B(); 这个的引用是 A类 ,改成 B a2 = new B(); 引用 B 类
你看控制台是输出 B and B,还是 B and A.
因为引用了 B类 ,多态会 优先,注意是优先! 把你传进来的 b 对象提升到 B类。
有人又会说: 你传的是 B b = new B(); 本身是 B类,当然输出 B and B啦.
没错,这个说法是 不用多态理解的方法!但你会发现
a2.show(c)这个也输出 : B and B. 是不是有点朦胧的感觉,先不急,把代码该回去先.
B a2 = new B(); 这个的引用是 B类 ,改成 A a2 = new B(); 引用 A 类. !!!!!!!!!
(4)最后还是用这个方法来解释:也是个总结.
A a2 = new B(); 它 new的 B() 对象,所以别管其他的。直接看 B对象的方法.
C传进来不知道调用哪个方法?
从继承链看是 C 对象 继承了 A对象
又因为上边我们提到了 ( A 名称 ) 我们称为引用 ,引用的类是 A 类,所以 C 对象被提升到 A对象
这是因为 多态 使得 C 对象 可以被提升到 父类的对象,或者父类的爸爸,或者爸爸的爸爸的爸爸!!!无限个爸爸!,当然你的程序会这么愚蠢的情况下就有这样的情况!
从而 识别这个方法: public String show(A obj){ return ("B and A");} ,控制台输出 B and A.
(5)a2.show(d),为什么输出 A and D? 我的方法不对了!??以为输出 B and A?
你错了: 继承是什么? 继承父类的方法!!! B类实际上有A类的方法:
public String show(D obj){ return ("A and D"); } 你传个 D对象 进来,它本身就有对应的方法,直接识别! 直接识别!
又不信?! 改代码!!
class D extends B{} 改为 class D {},删了继承代码
运行是不是还输出: A and D! 对嘛,和多态没半点关系,所以有学会区分什么时候用多态看问题,什么时候用继承看问题。
(6)b.show(b)这个呢?这个不用多态,继承看把,最普通的传参数问题!
(7)b.show(c)?用多态解决,用我的方法:
new的是B类, 直接看B对象里的方法。
引用的是B类 ,C继承B类,所以提升到 B父类这个类型。
对应 public String show(B obj){ return ("B and B"); }.输出 B and B.
(8)学会什么时候用什么方法没有!? 这个不用多态,看继承!
B类继承 A类的方法 public String show(D obj){ return ("A and D"); }
传个 D对象。刚好有就直接识别! 所以输出 A and D!
最后感谢自己有耐心的写完了它,毕竟自己也会忘记。我也乐于分享,非常感谢其他朋友也乐意分享自己的成果,使得我不懂的时候也有他们的帮忙才走的今天,不然就是放弃了。







网友评论