JAVA中多型性的理解(下)————多型性中的屬性&方法
大家好,作為一個剛開始接觸寫博客的計算機小白,寫的內容是我在學習和理解程序中的一些想法,如果有不準確或者錯誤的地方麻煩大家指教【拱手】【拱手】
文章目錄
- JAVA中多型性的理解(下)————多型性中的屬性&方法
- 前言
- 一、強制型別轉換的方法&錯誤型別
- 代碼:
- 代碼運行結果
- 二、強制型別轉換方法——總結(一)
- 二、強制型別轉換方法——總結(二)
- 三、關鍵字instanceof的使用
- 四、關于屬性和方法在多型性中的呼叫總結
- 五、結尾
前言
首先回顧上一篇博客的內容,我們知道當物件有了多型性后,記憶體中實際上加載了子類的特有的屬性和方法,但是由于變數宣告為父型別別,所以導致在呼叫物件的屬性和方法的時候,我們只能呼叫父類中宣告過的屬性和方法,導致子類特有的屬性和方法不能夠被呼叫,但如果我們想呼叫呢?其實是有方法的
第一種:強制資料型別轉換(和基本資料型別轉換想類似)
第二種:關鍵字instanceof的使用
一、強制型別轉換的方法&錯誤型別
下面的代碼是基于我上一篇博客中代碼案例,進行增加修改,實作的對強制型別轉換的實作以及錯誤的轉換型別的分析
父類:Person
子類:Man,Woman
目的:實作多型性的強制型別轉換
代碼:
package com.HeZiHan.java;
public class DuoTaiZhuanHuan {//主類
public static void main(String[] args) {
//列印父類的eat方法 and 每一個子類重寫后的eat方法
Person p1 = new Person();
p1.eat();
Man m1 = new Man();
m1.eat();
Woman w1 = new Woman();
w1.eat();
System.out.println("************************************************");
//列印進行多型化后的person的物件的eat方法
Person p2 = new Man();
p2.eat();
Person p3 = new Woman();
p3.eat();
System.out.println("************************************************");
//在主類中呼叫主類里的方法,但該方法也實作了多型化的使用
//在該方法中,實參和形參在一起,相當于Person person = new Man();Person person = new Woman();
DuoTaiZhuanHuan n =new DuoTaiZhuanHuan();
n.show(new Man());
n.show(new Woman());
System.out.println("************************************************");
System.out.println("分割線:上面是對多型性中方法呼叫的回顧,下面代碼反映的是多型性中呼叫子類特有的方法和屬性");
//在上面的代碼中我們知道,父類物件p2被賦值于子類Man;父類物件p3被賦值于子類Woman;
//現在我們展示如何呼叫子類中特有的屬性和方法,以及如何理解強制型別轉換
//Man m2=p2;-----------(×)
//如果我們直接將父類物件p2直接轉換為Man型別,雖然p2已經被Man經過多型性賦值,但P2本質上任然是Person類,而非Man類
//所以我們如果想要呼叫P2中子類Man中所特有的屬性和方法,就需要將它的型別進行轉化
Man m2 = (Man)p2;
m2.eat();
//首先我們需要知道,在上面的代碼中,我們實作了將父類物件p2經過多型性將子類Man賦值于父類物件
//此時我們將p2的型別轉換為子類Man型別之后,用Man型別對象m2去接受,然后在通過呼叫m2的方法,實作呼叫p2中子類的方法
System.out.println("************************************************");
//錯誤的轉換方式
// Man m3 = (Man)p3;
// m3.eat();
//這里之所以會錯是因為在型別轉換的時候,型別不搭配導致的錯誤
//我個人的理解是:首先p3已經在上面的代碼中實作了被子類Woman賦值,那么在此時p3的記憶體中就包含了子類Woman的屬性和方法,那么這個時候如果將它轉變為Man型別,此時它的記憶體中并不包含Man特有的屬性和方法,從而導致轉換失敗
System.out.println("************************************************");
//錯誤的轉換方式
// Person p4 = new Person();
// Man m4 = (Man)p4;
// m4.eat();
//這里的錯誤型別和上述的錯誤型別相同
//也可以這樣想:如果我們將Person型別的p4裝換為Man型別,此時p4對應的記憶體中并沒有加載子類Man中的屬性和方法,就算呼叫子類特殊的屬性和方法,我們呼叫什么內容呢?里面都沒有加載子類的屬性和方法
System.out.println("************************************************");
//錯誤的轉換方式
// Person p5 = new Man();
// Woman w2 = (Woman)p5;
// w2.eat();
//這里的錯誤型別與上述型別相同,即被轉換物件記憶體中,并沒有加載轉目標型別中的屬性和方法,從而導致轉換失敗
}
//主類中的一個方法
public void show(Person person){
person.eat();
person.sleep();
}
// System.out.println("************************************************");
//如果沒有多型性的話,那么想要呼叫這個show方法就需要對這個方法進行多次重寫,如下:
// public void show(Man man){
// man.eat();
// man.sleep();
// }
// public void show(Woman woman){
// woman.eat();
// woman.sleep();
// }
}
//父類Person
class Person {
int age;
double weight;
public void eat(){
System.out.println("人需要吃飯");
}
public void sleep(){
System.out.println("人每天平均需要睡8小時");
}
}
//子類Man
class Man extends Person{
int houses;
//對父類中的方法進行重寫
public void eat(){
System.out.println("男人每天多吃肉");
}
public void sleep(){
System.out.println("男人平均每天睡7小時");
}
}
//子類Woman
class Woman extends Person{
int car;
//對父類中的方法重寫
public void eat(){
System.out.println("女人每天多吃蔬菜");
}
public void sleep(){
System.out.println("女人平均每天睡9小時");
}
}
代碼運行結果
人需要吃飯
男人每天多吃肉
女人每天多吃蔬菜
************************************************
男人每天多吃肉
女人每天多吃蔬菜
************************************************
男人每天多吃肉
男人平均每天睡7小時
女人每天多吃蔬菜
女人平均每天睡9小時
*****************錯誤型別①&正確的轉換方式*******************************
分割線:上面是對多型性中方法呼叫的回顧,下面代碼反映的是多型性中呼叫子類特有的方法和屬性
男人每天多吃肉
*****************錯誤型別②*******************************
*****************錯誤型別③*******************************
*****************錯誤型別④******************************
二、強制型別轉換方法——總結(一)
錯誤型別①:直接將父類物件轉換為子類(一)
(沒有加最基本的強制轉換符)

錯誤型別②:不同型別之間的轉換
(父類物件M被子類A類通過多型性賦值,但將M轉換為子類B類)


錯誤型別③:父類直接強制轉型為子類(二)
(此時的父類物件中并沒有加載子類的任何屬性方法,即使轉換通過,那么要呼叫哪些子類中特有的屬性和方法呢?記憶體中根本就沒有可供呼叫的特殊的屬性和方法)


錯誤型別④:同級子類之間的轉化
(父類的兩個子類之間相互轉換,eg:上面的代碼中將被Woman賦值過的p3強轉為Man)


二、強制型別轉換方法——總結(二)
①我們在實作將多型性中的型別強制性轉換時,本質上是“向下轉化”
②“父類 物件 = new 子類()”中右邊子類是我們向下轉換的最大限度
③自己總結的流程圖,存在不足,希望諒解

三、關鍵字instanceof的使用
①“a instanceof A”判斷物件a是否是類A的實體,如果是回傳“True”,反之回傳“Fasle”
②使用情況,我們在通過上面的強制型別轉換可知,有時會出現強制轉換型別失敗,“ClassCastException”型別的錯誤,所以為了避免這種錯誤的出現,我們在向下轉型之前,先進行instanceof的判斷,一旦回傳True,就向下轉型,如果回傳False,則不向下轉型
③特例:如果a instanceof A 回傳True,且a instanceof B 也回傳True,則說明B是類A的父類
四、關于屬性和方法在多型性中的呼叫總結
①若子類重寫了父類的方法,就意味著子類定義的方法徹底覆寫了父類里同名的方法,運行看右邊
②對于實體(物件)則不存在這樣的情況,即使子類里定義了與父類完全相同的實體變數,這個實體變數依然不可能覆寫父類中定義的實體變數,編譯看左邊

五、結尾
感謝大家看到這里,這些就是我這個計算機小白的一些想法,如果有哪里出現了錯誤或者其他問題,歡迎大家指正,感謝感謝,
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/273710.html
標籤:java
上一篇:Java希爾排序淺析
下一篇:Java內部類
