物件轉型(instanceof關鍵字)(物件的引用與所指物件的型別之間各種關係)
1、物件之間的轉換並非是隨意進行的轉換,在基本型別的轉換中,有自動型別轉換,還有一種強制型別轉換,但是物件型別的轉換不能強制地隨意地進行轉換,而是有一種約束,是一種上下繼承層次關係的轉換。
2、instanceof關鍵字:
(1)使用方法:引用空格instanceof空格類名
例如:a instanceof Cat;
意思就是某型別的引用a所指的物件的型別,其實最終要的是該引用所指的物件型別(並非是a引用的型別,是a所指物件的型別)是否是Cat類或者是屬於Cat子類
引用型別和物件型別是兩個概念
(2)作用:用於判斷引用所指的物件是否屬於該類或者該類的子物件
(3)返回值:true或者是false
(1)a一直是Pet的引用型別,c一直是Cat的引用型別,d一直是Dog的引用型別,a引用所指的物件型別是Pet,所以是對的;c引用所指的物件是Cat,Cat是Pet的子類,所以是對的;d引用所指的物件是Dog,Dog是Pet的子類,所以是對的;a指的物件不是cat類,也不是cat的子類,所以也是錯誤的。
(2)可以把一個dog型別的物件賦值給一個pet型別的引用,子類是可以賦值給一個父類型別的變數/引用,子類對父類的賦值實際就是子類物件中繼承自父類的部分賦值給父類物件!
(3)a=new Dog("","");
這一步結束之後,a還是Pet型別的引用,但是指向的物件型別不再是Pet了,指向的物件型別變為了Dog(引用型別沒變,指向的物件型別改變
(4)a的引用型別是pet型別的,但是a所指的物件變成了Dog型別的了, Dog為pet子類,所以返回值為true。
(5)如果就是想通過父類來使用子類新增的成員變數的話,只能對a進行強制型別轉換(強制型別轉換換的是引用型別),比如將pet型別的引用轉換為Dog型別的引用,次轉換為向下轉換,d1是Dog型別物件,它可以指向的可以是Dog型別的物件或者是Dog型別的子物件。
注意:
(1)強制型別轉換的時候,換的是引用的型別
(2)用instanceof判斷的是該類所指物件的型別與後面物件之間的關係
(3)是否可以使用某一個變數看的是,這個類的引用型別與變數之間的關係。
(4)子類型別的物件可以賦值給父類型別的引用,父類型別的引用不能訪問子類新增成員物件和方法,例如:
Student s;
s=new Postgraduce();//正確,因為一個子類型別的物件可以直接賦值給一個父類型別的引用;
s.getName();//正確,因為getName()方法是父類中有的方法,子類中也會繼承;
s.getTurtor();//錯誤,因為getTurtor()方法是子類中的方法,父類型別的引用不能呼叫子類中新建立的成員物件或者是方法。
s.getTurtor();這裡編譯的時候會報錯。
(5)類之間強制型別轉換是有風險的,確實強制型別轉換換了引用型別之後,可以使用子類新增變量了,(因為父類的引用型別不能使用子類新增變數,如果將父類的引用型別轉換為子類引用型別的話,那麼引用型別是對的,就可以使用新增的變量了),但是,如果該類所指的物件是父類的話,雖然之後的可以使用子類新增變量了,可是想要引用的那個變數沒有值,仍然會出現錯誤,例如,本來指向的是Cat,但是後來強制型別轉換成Dog,雖然引用型別是Dog引用型別,但是沒有Dog所含有的皮毛這個變數,所以這個強制型別轉換時錯誤的。編譯可以通過,但是執行的時候是錯誤的。
3、例項1:
將pet型別的引用轉換為cat,因為進行強制型別轉換了,所以編譯的時候是正確的,但是執行的時候會出錯,因為,引用c是Cat型別的物件,它可以指向的物件只能是Cat型別的物件或者是Cat型別的子物件,但是上面的a指向的是pet型別的物件,所以會報錯。
4、
使用上面的方法則可以巧妙地減小強制型別轉換的風險,先判斷要強制型別轉換的變數所指的物件與要強制轉換型別的關係,如果是要強制型別轉換的變數所指的物件是強制轉換的型別或其子類的話,就可以進行強制型別轉換,否則就不能進行強制型別轉換。