一、繼承
繼承就是一種由已有類創建新類,在已有類的基礎上擴展功能。
1、只能單一繼承,即子類只能有一個父類,但是可以多層繼承。
2、子類中出現了同名稱的成員變量,會發生隱藏現象,即子類的成員變量會屏蔽掉父類的同名成員變量。如果要在子類中訪問父類中同名成員變量,需要使用super關鍵字來進行引用。
3、子類可以對父類的方法進行重寫(即方法的返回類型、方法名、參數列表完全相同時,僅方法體不一樣),子類對父類的方法重寫之後,創建子類對象,直接調用的是子類重寫的方法,這時要想調用父類的方法就要在子類方法中用到super.方法名(參數列表)。另有調用父類中被重寫的構造方法時super語句要寫在子類構造方法第一行。
代碼演示:
public class Sub {
String name="老子";
public Sub(){
System.out.println("老子:哈哈,我是老子,不信你去百度翻譯查‘老子’怎麼翻譯");
}
public Sub(int i){
System.out.println("老子:兒子,孫子在哪?");
}
Sub(String s)
{
System.out.println(s);
}
void f(){
System.out.println("老子:小子,你調用的是老子的方法");
}
public static void main(String[] args) {
Son1 s=new Son1();//如果父類只有有參的構造函數,即使子類有無參構造函數,這樣寫會報錯。
Son1 s1=new Son1(1);
s1.f();
System.out.println(s1.name);//子類變量覆蓋了父類變量
Son1 s2=new Son1("兒子");//將默認調用父類無參構造函數
}
}
class Son1 extends Sub{
String name="兒子";
Son1(){
System.out.println("兒子:查了,老子是您“me”呀!");
}
Son1(int i){
super(i);//不寫這句默認調用的是父類無參構造函數
System.out.println("兒子:說的跟兒子你有媳婦似的!");
}
Son1(String s)
{
System.out.println(s);
}
void f(){//子類覆蓋父類方法,不能縮小訪問權限。
System.out.println("兒子:我長大了,要用自己的方法");
super.f();//調用父類的方法,可以不放在第一行
}
}
運行結果:
老子:哈哈,我是老子,不信你去百度翻譯查‘老子’怎麼翻譯
兒子:查了,老子是您“me”呀!
老子:兒子,孫子在哪?
兒子:說的跟兒子你有媳婦似的!
兒子:我長大了,要用自己的方法
老子:小子,你調用的是老子的方法
兒子
老子:哈哈,我是老子,不信你去百度翻譯查‘老子’怎麼翻譯
兒子
對於無參數的父類構造器,會被子類默認調用;
對於帶參數的父類構造器,子類必須使用關鍵字super顯示地調用,並配以適當的參數。
子類覆蓋父類方法,可以修改方法作用域修飾符,但只能把方法的作用域放大。
父類只有有參數構造函數,子類在構造方法中必須要顯示調用父類相應的構造函數,否則編譯出錯。
靜態方法和實例方法不能相互隱藏。
有多層繼承時首先根基類中的static初始化,然後是下一個導出類,以此類推,static初始化完成之後。然後實例變量和構造器從根基類到下一個導出類一步步初始化調用。
二、組合
在新類中產生現有類的對象,由於新類是由現有類的對象組成的,這種方法稱之爲組合。
注意區分組合和繼承:
代碼演示如下所示:
class Plate{
Plate(int i){
System.out.println("Plate constructor"+i);
}
}
class DinnerPlate extends Plate{
DinnerPlate(int i){
super(i);
System.out.println("DinnerPlate constructor"+i);
}
}
class Utensil{
Utensil(int i){
System.out.println("Utensil constructor"+i);
}
}
class Spoon extends Utensil{
Spoon(int i){
super(i);
System.out.println("Spoon constructor"+i);
}
}
class Fork extends Spoon{
Fork(int i){
super(i);
System.out.println("Fork constructor"+i);
}
}
class Knife extends Fork{
Knife(int i){
super(i);
System.out.println("Knife constructor"+i);
}
}
class Custom{
Custom(int i){
System.out.println("Custom constructor"+i);
}
}
public class PlaceSetting extends Custom{
private Spoon sp;//組合
private Fork frk;//組合
private DinnerPlate pl;//組合
private Knife kn;
public PlaceSetting(int i){
super(i+1);//調用父類構造方法
sp=new Spoon(i+2);
frk=new Fork(i+3);//從根基類到派生類一步步調用構造函數
kn=new Knife(i+4);//從根基類到派生類一步步調用構造函數
pl=new DinnerPlate(i+5);
System.out.println("PlaceSetting constructor"+i);
}
public static void main(String[] args) {
PlaceSetting x=new PlaceSetting(9);
}
}
運行結果:
Custom constructor10
Utensil constructor11
Spoon constructor11
Utensil constructor12
Spoon constructor12
Fork constructor12
Utensil constructor13
Spoon constructor13
Fork constructor13
Knife constructor13
Plate constructor14
DinnerPlate constructor14
PlaceSetting constructor9