Demo1
B---->public void fun1()
结论:如果想发生一个向下转型,必须发生一个向上转型,不然就根本无法做到;
输出:
class A {
public void fun1(){
System.out.println("A--->public fun1()");
}
public void fun2(){
this.fun1();
}
};
class B extends A{
public void fun1(){
System.out.println("B---->public void fun1()");
}
public void fun3(){
System.out.println("B------>public void fun3()");
}
};
public class PolDemo {
public static void main(String[] args){
B b = new B();//实例化对象
A a=b;//向上转型关系
a.fun1();
a.fun2();
// a.fun3();
}
};
运行输出;
B---->public void fun1()
B---->public void fun1()
结论:将B强转A 是以A 为对照实体,所以 不存在fun3() ;如果子类重写父类,先执行子类,找不到在到父类中找;
Demo2
再改改上面的例子:
public class PolDemo {
public static void main(String[] args){
A a=new A();
B b=a;//报错,不能转换,原因类与类之间的关系不明确。这就是向下转型,所不取的地方;
b.fun1();//报错
}
};
输出:报错;
结论:类与类之间,必须存在明确的关系才能转换。
Demo3
public class PolDemo {
public static void main(String[] args){
A a= new B();//向上转型
B b=(B)a;//向下转型,这是可以的,因为上面的那句已经确定他和他老子的关系啦
a.fun1();
a.fun2();
}
};
输出:
B---->public void fun1()B---->public void fun1()
结论:如果想发生一个向下转型,必须发生一个向上转型,不然就根本无法做到;
Java多态性的应用:
class A {
public void fun1(){
System.out.println("A--->public fun1()");
}
public void fun2(){
this.fun1();
}
};
class B extends A{
public void fun1(){
System.out.println("B---->public void fun1()");
}
public void fun3(){
System.out.println("B------>public void fun3()");
}
};
class C extends A{
public void fun1(){
System.out.println("C---->public void fun1()");
}
};
public class PolDemo {
public static void main(String[] args){
fun1(new B());
fun1(new C());
}
public static void fun1(A a){
a.fun1();
}
}
当有无数个类多继承A时,都可以轻松完成,或对代码进行轻松的维护;这只需要修改new X() 就可以了,这类是于工厂;
他这一强大的优点让人无法忽视啊。
用 instanceof 验证类与类的关系:
public class PolDemo {
public static void main(String[] args){
A a1 = new B();
System.out.println("A a1 =new B() : "+(a1 instanceof A));
System.out.println("A a1 =new B() : "+(a1 instanceof B));
A a2= new A();
System.out.println("A a2 =new B() : "+(a2 instanceof A));
System.out.println("A a2 =new B() : "+(a2 instanceof B));
// A a3=new A();
// B b1=(B)a;//IDE 报错;
// System.out.println("B b1 =new B() : "+(a2 instanceof A));
// System.out.println("B b1 =new B() : "+(a2 instanceof B));
}
输出:
A a1 =new B() : true
A a1 =new B() : true
A a2 =new B() : true
A a2 =new B() : false
典型糟糕的Demo
public class PolDemo {
public static void main(String[] args){
A a1 = new B();
System.out.println("A a1 =new B() : "+(a1 instanceof A));
System.out.println("A a1 =new B() : "+(a1 instanceof B));
A a2= new A();
System.out.println("A a2 =new B() : "+(a2 instanceof A));
System.out.println("A a2 =new B() : "+(a2 instanceof B));
B b3=(B)new A();//IDE 没出错,但运行出错啦!向下转型;糟糕的到吗
A a3= (A) b3;
System.out.println("B b1 =new B() : "+(a2 instanceof A));
System.out.println("B b1 =new B() : "+(a2 instanceof B));
}
}
IDE 没保存,但编译出错!向下转型,类与类的关系不确定啊!
=====================这是经常忽视的问题!================
所以,在向下转型时,最好增加 instanceof 验证 来保证程序不会出错!
进一步优化的Demo
思考:如何优化一下代码:
package basic.java.linknode;
class A {
public void fun1(){
System.out.println("A--->public fun1()");
}
public void funA(){
this.fun1();
}
};
class B extends A{
public void fun1(){
System.out.println("B---->public void fun1()");
}
public void funB(){
System.out.println("B------>public void funB()");
}
};
class C extends A{
<span style="white-space:pre"> </span> public void fun1(){
<span style="white-space:pre"> </span> System.out.println("C---->public void fun1()");
<span style="white-space:pre"> </span> }
<span style="white-space:pre"> </span> public void funC(){
<span style="white-space:pre"> </span> System.out.println("C---->public void funC()");
<span style="white-space:pre"> </span> }
};
public class PolDemo {
<span style="white-space:pre"> </span> public static void main(String[] args){
<span style="white-space:pre"> </span>
<span style="white-space:pre"> </span> fun(new B());
<span style="white-space:pre"> </span> fun(new C());//与定义的顺序有关!
<span style="white-space:pre"> </span> }
<span style="white-space:pre"> </span>
<span style="white-space:pre"> </span> public static void fun(A a){
<span style="white-space:pre"> </span> System.out.println("===========Begin============");
<span style="white-space:pre"> </span> a.fun1();
<span style="white-space:pre"> </span> if(a instanceof B){
<span style="white-space:pre"> </span> B b=(B)a;
<span style="white-space:pre"> </span> b.funB();
<span style="white-space:pre"> </span> }
<span style="white-space:pre"> </span> if(a instanceof C){
<span style="white-space:pre"> </span> C c=(C) a;
<span style="white-space:pre"> </span> c.funC();
<span style="white-space:pre"> </span> }
<span style="white-space:pre"> </span> System.out.println("===========End============");
<span style="white-space:pre"> </span> }
}
}
如果要增加新子类,则肯定要修改fun()方法,这样一来程序就失去了灵活性,所以在程序开发重点的设计应该放在父类上,只要父类设计的足够合理,则开发肯定非常方便;
=======》 记住:一个类一定不能去继承一个实现好的类。而只能继承抽象类或实现接口;《=======