Java基础突击第六天0012(多态,instanceof)

在Java中面向对象主要有两种体现,方法的重载与覆写/对象的多态性

多态性:向上转型: Father fatObj01 = new Son();(子类对象转为父类对象)

              向下转型:Father fatObj02 =  new Son();   Son sonObj01 = (Son)fatObj02

与基本数据类型的类型转换相似。子类转父类能转,父类转子类要显示表示。

在进行向下转型前 必须发生向上转型,否则会编译错误。出现对象转换异常。

public class TestJava{
}
class Father{
		public void fun1(){
				System.out.println("Fun01 in the Father");
		}
		public void fun2(){
				this.fun1();
		}
}
class Son extends Father{
		public void fun1(){
				System.out.println("Fun01 in the Son");
		}
		public void fun3(){
				System.out.println("Fun03 in the Son");
		}
}
class SonOther extends Father{
		public void fun1(){
				System.out.println("Fun01 in the SonOther");
		}
		public void fun4(){
				System.out.println("Fun04 in the SonOther");
		}
}
class Demo{
		public static void deliver(Father fatTypeObj){
				fatTypeObj.fun1();
		}
		public static void instanceofTest(Father fatherObj){
				fatherObj.fun1();
				if(fatherObj instanceof Son){
						System.out.println("This object is belong to class Son!");
						Son sonTemp = (Son)fatherObj;
						sonTemp.fun3();
				}
				if(fatherObj instanceof SonOther){
						System.out.println("This object is belong to class SonOther!");
						SonOther sonOtherTemp = (SonOther)fatherObj;
						sonOtherTemp.fun4();
				}
		}
	      public static void main(String[] args){
				Son sonObj01 = new Son();
				Father fatherObj01 = sonObj01;  // Upcasting
				fatherObj01.fun1();


				//Father fatherObj02 = new Father(); Compile error,Fatherclass doesn't know its Sonclass
				Father fatherObj02 = new Son();
				Son sonObj02 = (Son)fatherObj02;
				sonObj02.fun1();
				sonObj02.fun2();
				sonObj02.fun3();
				System.out.println("-------------");
				deliver(new Son());
				deliver(new SonOther());


				Father fatherObj03 = new Father();
				System.out.println("instanceof test in Upcasting and Downcasting case!");
				System.out.println("Is fatherObj01 belong to class Father?"+(fatherObj01 instanceof Father));
				System.out.println("Is fatherObj01 belong to class Son?"+(fatherObj01 instanceof Son));
				System.out.println("Is fatherObj03 belong to class Father?"+(fatherObj03 instanceof Father));
				System.out.println("Is fatherObj03 belong to class Father?"+(fatherObj03 instanceof Son));
				instanceofTest(new Son());
				instanceofTest(new SonOther());
		}
}//Demo

输出:

Fun01 in the Son
Fun01 in the Son
Fun01 in the Son
Fun03 in the Son
-------------
Fun01 in the Son
Fun01 in the SonOther
instanceof test in Upcasting and Downcasting case!
Is fatherObj01 belong to class Father?true
Is fatherObj01 belong to class Son?true
Is fatherObj03 belong to class Father?true
Is fatherObj03 belong to class Father?false
Fun01 in the Son
This object is belong to class Son!
Fun03 in the Son
Fun01 in the SonOther
This object is belong to class SonOther!
Fun04 in the SonOther

虽然是用父类对象调用fun1方法,不过经过子类向父类向上转型执行之后,父类对象调用后执行的是经过子类覆盖后的方法。

父类用本身实例化自己的对象,但它并不知道谁是自己的子类,所以显示转换出现编译错误。不过用子类去实例化父类对象,显示转换通过。

不过转型后,父类对象无法调用[子类定义而父类未定义]的方法。

上述程序使用一个deliver方法接收Father类的对象。

通过将不同子类传入deliver方法以达到不同的子类效果。

因为采用了多态性,每增加一个子类,deliver方法都不需要做任何改变。

因为deliver方法接收的是父类对象,传入子类对象的话势必会发生向上转型。

一旦发生对象的向上转型之后,调用的方法肯定是被子类覆写过的方法。


使用instanceof关键字判断一个对象到底是哪个类的实例,返回boolean类型。

不过记得加括号,貌似+优先级都比instanceof要高,而且instanceof是个关键字不是方法。

时刻注意加括号(对象名 instanceof 类名) 返回true或false

子类实例化的对象同时是子类和父类的实例,可以直接进行向上或向下转型()。

但如果用父类实例化了子类的对象,则肯定不是子类的实例。

所以在向下转型之前最好先行判断父子类关系,避免转换异常。


在类的设计中,重点在于父类的设计。

而且在类的设计中,永远不要继承一个已经实现好的类,只能继承抽象类或实现接口。

因为一旦发生对象的向上转型(子类转父类,随便转)关系后,所调用的方法一定是被子类覆写过的方法。


猜你喜欢

转载自blog.csdn.net/u012144068/article/details/80942774