Java子類與繼承
一、繼承
繼承是一種由已有類建立新類的機制。 利用繼承,可以先定義一個共有屬性的一般類。根據該一般類再定義具有特殊屬性的子類 ,子類繼承一般類的屬性和行為,並根據需要增加它自己新的屬性和行為。 例子:
class 子類名 extends 父類名 { } class Student extends People { }Java不支援多重繼承,即子類只能有一個父類。
二、子類的繼承性
子類的成員變數中有一部分是子類自己宣告定義的,另一部分是從子類的父類繼承的。 什麼叫繼承? 所謂子類繼承父類的成員變數作為子類的一個成員變數,就好像這個變數是在子類中直接 宣告一樣,可以被子類中自己定於的任何例項方法操作。 所謂子類繼承父類的方法作為子類的一個方法,就像它們是在子類中直接定義一樣。可 以被子類中定義的任何方法呼叫。 子類和父類在同一包中的繼承性:子類自然繼承了其父類中不是private的成員變數和方法,繼承的成員變數或方法的訪問 許可權保持不變。 子類和父類不在同一包中的繼承性:
父類中的private和友好訪問許可權的成員變數和方法不會被子類繼承,子類只繼承弗雷中 的protected和public訪問許可權的成員變數和方法。 Protected的作用和說明: 一個類A中的protected成員變數和方法可以被它的子孫類繼承,比如B是A的子類,D又是 C的子類,那麼B,C和D類都繼承了A類的protected成員變數和方法。 如果用D類在D本身建立一個物件,那麼該物件總是可以通過 “ . ” 運算子訪問繼承的或自己 定義的protected變數和protected方法。 如果在另一個類中: 在Other類中用D類建立一個物件object, (1)對於子類D自己宣告的protected成員變數和方法,只要Other類和D類在同一個包中,Object物件 就可以訪問這些protected成員變數和方法。 (2)對於子類D從父類繼承的protected成員變數或protected方法,需要追溯到這些protected成員變數 或方法所在的"祖先"類,比如可能是A類,只要Other類和A類在同一包中,object物件能訪問繼承的 protected變數和protected方法。
三、子類與物件
當用子類的構造方法建立一個子類的物件時,不僅子類中的成員變數被分配了記憶體,而且父類的成員 變數被分配了記憶體空間,但只將其中一部分,即子類繼承的那部分成員變數,作為分配給子類物件的 變數。 父類中的private成員變數儘管分配了記憶體空間,也不作為子類物件的變數,即子類不繼承父類的私有 成員變數。 如果子類和父類不在同一個包中,父類的友好變數分配記憶體空間,但不作為子類物件的變數。 子類中還有一部分方法是從父類繼承的,這部分方法卻可以操作這部分未繼承的變數。 instanceof 運算子
instanceof是Java獨有的雙目運算子 物件 instanceof 類 當左邊的操作元是右邊類或其子類所建立的物件時,instanceof運算的結果是true,否則是false。成員變數的隱藏和方法重寫
1、成員變數的隱藏 在編寫子類時,仍然可以宣告成員變數,一種特殊的情況就是,所宣告的成員變數的名字和從父類 繼承的成員變數和名字相同。 在這種情況下,子類就會隱藏所繼承的成員變數: (1)子類重新宣告這個成員變數 (2)子類物件仍然可以呼叫從父類中繼承的方法操作用被子類隱藏的成員變數。 也就是說,自類繼承的方法所操作的成員變數,一定是被子類繼承或隱藏的成員變數。 子類新定義的方法可以操作子類繼承和子類新宣告的成員變數,但無法操作子類隱藏的成員變數。 2、方法重寫 如果子類可以繼承父類的某個方法,就可以重寫這個方法。 子類定義一個方法,這個方法的型別和父類的方法型別一致,並且這個方法的名字、引數個數和引數型別, 以及返回值型別和父類的方法完全相同。 子類通過方法的重寫可以把父類的狀態和行為改變為自身的方法和行為。 重寫方法既可以呼叫繼承的成員變數、呼叫繼承的方法。也可以操作子類新宣告的成員變數,呼叫新定義的 其他方法,但無法操作被子類隱藏的成員變數和方法。 注意:重寫父類方法時,不允許降低方法的訪問許可權,但可以提高訪問許可權。 子類重寫方法的方法型別,可以是父類方法型別的子型別。 注意:小心出現季成後方法過載錯誤。
四、super和final關鍵字
1、Super關鍵字的使用
用super操作被隱藏的成員變數和方法:
子類一旦隱藏了繼承的成員變數和方法,那麼子類建立的物件就不再擁有該變數,不能呼叫該方法。
被隱藏的成員變數和方法由關鍵字super負責。
當super呼叫被隱藏的方法時,該方法中出現的的成員變數是被子類隱藏的成員變數或繼承的成員變數。
使用super呼叫父類的構造方法:
當用子類的構造方法建立一個子類的物件時,子類的構造方法總是先呼叫父類的某個構造方法。
由於子類不繼承父類的構造方法,因此子類在其構造方法中使用super來呼叫父類的構造方法,
而且super必須是子類構造方法的頭一條語句,如果沒有明顯寫出super關鍵字來呼叫父類中的某
個構造方法,預設的有:super(); ( 呼叫父類的不帶引數的構造方法 )
使用super(a,b,c) 呼叫父類的構造方法
使用this(a,b,c) 可以呼叫本類另外的構造方法
2、final關鍵字
final關鍵字可以修飾類、成員變數和方法中的區域性變數。
可以使用final將類宣告為final類,final類不能被繼承,即不能有子類。
用final修飾父類的一個方法,那麼這個方法不允許子類重寫。
被修飾為final的成員變數和區域性變數為常量。
常量沒有預設值,在宣告時必須指定該常量的值。
五、物件的上轉型物件
子類與父類的關係是“ is - a ” 關係,當說到老虎是動物時,老虎將失掉老虎獨有的屬性和功能。
物件的上轉型物件的實體是子類負責建立的,但上轉型物件會失去原物件的一些屬性和功能。
(1)上轉型物件不能操作子類新增的成員變數,不能呼叫子類新增的方法;
(2)上轉型物件可以訪問子類繼承或隱藏的成員變數,也可以呼叫子類繼承的方法或子類重寫的子類重寫的方法。
上轉型物件操作子類繼承或重寫的的例項方法,其作用等價於子類物件去呼叫這些方法。
因此,如果子類重寫了父類某個例項方法後,當物件的上轉型物件呼叫這個例項方法時,一定呼叫了子類重寫的例項方法。
注意:
(1)父類建立的物件不等於子類物件的上轉物件;
(2)可以將物件的上轉型物件再強轉換到一個子類物件,這時,該子類物件又具有了所有的屬性和功能;
(3)不可以將父類建立的物件的引用賦值給子類宣告的物件。
如果子類重寫了父類的靜態方法,那麼子類物件的上轉型物件不能呼叫子類重寫的靜態方法,只能呼叫父類的靜態方法。
繼承與多型:
當一個類有很多子類時,並且這些子類都重寫了父類中某個方法。
當把子類建立的物件例項的引用放到一個父類的物件中時,就得到該物件的一個上轉型物件,那麼這個上轉型物件在呼叫這個方法時就可能具有多種形態。
因為不同的子類在重寫父類的方法時可能產生不同的行為。
多型性是指父類的某個方法被子類重寫,可以各自產生自己的功能行為。
五、abstract類和abstract方法
用關鍵字abstract修飾的類稱為abstract類(抽象類)。
用關鍵字abstract修飾的方法稱為abstract方法(抽象方法)。
對於abstract方法,只允許宣告,不允許實現(沒有方法體),而且不允許使用final和abstract同時修飾一個類,也不允許使用static修飾abstract方法,即abstract方法必須是例項方法。
1、abstract類中可以有abstract方法
abstract類中可以有abstract方法(非abstract類中不可以有abstract方法),也可以有非abstract方法。
2、abstract類不能使用new運算子建立物件
如果一個抽象類是某個抽象類的子類,那麼它必須重寫父類的抽象方法,給出方法體,所以不允許用final和abstract同時修飾一個方法或類。
3、abstract類的物件作為上轉型物件
可以使用abstract類宣告物件,不能用new運算子建立物件,但該物件可以成為其子類物件的上轉型物件,那麼該物件就可以呼叫子類重寫的方法。
注意:
abstract類也可以沒有abstract方法。
如果一個abstract類是abstract類的子類,它可以重寫abstract方法,也可以繼承父類的abstract方法。