對繼承與多態、成員變量的隱藏和方法重寫、super關鍵字、final關鍵字、對象的上轉型對象、抽象類的學習理解(java)

繼承

是一種由已有的類創建新類的機制。利用繼承,我們可以先創建一個共有屬性的一般類,根據該一般類再創建具有特殊屬性的新類,新類繼承一般類的狀態和行爲,並根據需要增加它自己的新的狀態和行爲。由繼承而得到的類稱爲子類,被繼承的類稱爲父類(超類)。
:Java不支持多重繼承(子類只能有一個父類)。

聲明子類

使用關鍵字extends來定義一個類的子類,格式如下:
class 子類名 extends 父類名 {

}
例如:
class Student extends People {

}
說明:把Student類定義爲People類的子類、People類是Student類的父類

子類的繼承性

類可以有兩種重要的成員:成員變量和方法。子類的成員中有一部分是子類自己聲明定義的,另一部分是從它的父類繼承的。

所謂子類繼承父類的成員變量就是把繼承來的變量作爲自己的一個成員變量,就好象它們是在子類中直接聲明一樣,可以被子類中自己定義的任何實例方法操作。

所謂子類繼承父類的方法就是把繼承來的方法作爲子類中的一個方法,就好象它們是在子類中直接定義了一樣,可以被子類中自己定義的任何實例方法調用。
例題:子類的繼承

class Father
{ float weight,height;
String head;
void speak(String s)
{ System.out.println(s);
}
}
class Son extends Father
{ String hand,foot;
}

Son s=new Son();

子類和父類在同一包中的繼承性

如果子類和父類在同一個包中,那麼,子類自然地繼承了其父類中不是private的成員變量作爲自己的成員變量,並且也自然地繼承了父類中不是private的方法作爲自己的方法,繼承的成員變量或方法的訪問權限保持不變。

子類和父類不在同一包中的繼承性

如果子類和父類不在同一個包中,那麼,子類繼承了父類的protected、public成員變量做爲子類的成員變量,並且繼承了父類的protected、public方法爲子類的方法,繼承的成員或方法的訪問權限保持不變。

子類對象的生成

子類創建對象時,子類的構造方法總是先調用父類的某個構造方法,完成父類部分的創建;然後再調用子類自己的構造方法,完成子類部分的創建。如果子類的構造方法沒有明顯地指明使用父類的哪個構造方法,子類就調用父類的不帶參數的構造方法 。

子類創建對象時,子類的構造方法總是先調用父類的某個構造方法,完成父類部分的創建;然後再調用子類自己的構造方法,完成子類部分的創建。如果子類的構造方法沒有明顯地指明使用父類的哪個構造方法,子類就調用父類的不帶參數的構造方法 。
子類可以通過繼承的方法來操作子類未繼承的變量和方法 .
結論:
1)創建子類對象時,子類總是按層次結構從上到下的順序調用所有超類的構造函數。如果繼承和組合聯用,要先構造基類的構造函數,然後調用組合對象的構造函數(組合按照聲明的順序調用)。
2)如果父類沒有不帶參數的構造方法,則在子類的構造方法中必須明確的告訴調用父類的某個帶參數的構造方法,通過super關鍵字,這條語句還必須出現在構造方法的第一句。

成員變量的隱藏和方法重寫

1)對於子類可以從父類繼承的成員變量,只要子類中聲明的成員變量和父類中的成員變量同名時,子類就隱藏了繼承的成員變量
在子類中要操作這個與父類同名的成員變量時,子類操作的是子類重新聲明的這個成員變量。而不是被隱藏掉的。
2)
1.重寫的語法規則
如果子類繼承了父類的實例方法,那麼子類就有權利重寫這個方法。
方法重寫是指:子類中定義一個方法,這個方法的類型和父類的方法的類型一致或是父類方法的類型的子類型,且這個方法的名字、參數個數、參數的類型和父類的方法完全相同.
2.重寫的目的
子類通過方法的重寫可以隱藏繼承的方法,子類通過方法的重寫可以把父類的狀態和行爲改變爲自身的狀態和行爲。
3. 重寫後方法的調用
子類創建的一個對象,如果子類重寫了父類的方法,則運行時系統調用的是子類重寫的方法;
子類創建的一個對象,如果子類未重寫父類的方法,則運行時系統調用的是子類繼承的方法;
4.重寫的注意事項
重寫父類的方法時,不允許降低方法的訪問權限,但可以提高訪問權限(訪問限制修飾符按訪問權限從高到低的排列順序是:public、protected、友好的、private。)

super關鍵字

1 用super操作被隱藏的成員變量和方法
子類可以隱藏從父類繼承的成員變量和方法,如果在子類中想使用被子類隱藏的成員變量或方法就可以使用關鍵字super。比如super.x、super.play()就是訪問和調用被子類隱藏的成員變量x和方法play().
2 使用super調用父類的構造方法
子類不繼承父類的構造方法,因此,子類如果想使用父類的構造方法,必須在子類的構造方法中使用,並且必須使用關鍵字super來表示,而且super必須是子類構造方法中的頭一條語句。

final關鍵字

final關鍵字可以修飾類、成員變量和方法中的局部變量。
可以使用final將類聲明爲final類。final類不能被繼承,即不能有子類。
如: final class A {
… …
}
如果用final修飾父類中的一個方法,那麼這個方法不允許子類重寫。
如果成員變量或局部變量被修飾爲final的,就是常量。

對象的上轉型對象

假設,A類是B類的父類,當用子類創建一個對象,並把這個對象的引用放到父類的對象中時,稱對象a是對象b的上轉型對象。比如:
A a;
a=new B();

A a;
B b=new B();
a=b;
上轉型對象的使用
1.上轉型對象不能操作子類新增的成員變量;不能調用子類新增的方法。
2.上轉型對象可以訪問子類繼承或隱藏的成員變量,也可以調用子類繼承的方法或子類重寫的實例方法。
3. 如果子類重寫了父類的某個實例方法後,當用上轉型對象調用這個實例方法時一定是調用了子類重寫的實例方法。

多態

多態性就是指父類的某個方法被其子類重寫時,可以各自產生自己的功能行爲。

abstract類和abstract()方法

用關鍵字abstract修飾的類稱爲abstract類(抽象類)。
例如:abstract class A {
… …
}
用關鍵字abstract修飾的方法稱爲abstract方法(抽象方法)
例如:abstract int min(int x,int y);
abstract類有如下特點
和普通的類相比,abstract類裏可以有abstract方法。也可以沒有。對於abstract方法,只允許聲明,不允許實現,而且不允許使用final修飾abstract方法。
對於abstract類,不能使用new運算符創建該類的對象,只能產生其子類,由子類創建對象。
如果一個類是abstract類的子類,它必須具體實現父類的所有的abstract方法。

面向抽象編程

在設計一個程序時,可以先聲明一個abstract類,通過在類中聲明若干個abstract方法,表明這些方法在整個系統設計中的重要性,方法體的內容細節由它的非abstract子類去完成。

然後利用多態實現編程。使用多態進行程序設計的核心技術是使用方法重寫和上轉型對象,即將abstract類聲明對象作爲其子類的上轉型對象,那麼這個上轉型對象就可以調用子類重寫的方法。

所謂面向抽象編程,是指當設計某種重要的類時,不讓該類面向具體的類,而是面向抽象類,即所設計類中的重要數據是抽象類聲明的對象,而不是具體類聲明的對象。

實例

下面舉個例子描述繼承、重寫、抽象類的簡單使用。

設計一個動物聲音“模擬器”,希望模擬器可以模擬許多動物的叫聲,要求如下:

  1. 編寫抽象類Animal
    Animal抽象類有兩個抽象方法cry()和getAnimalName(),即要求各種具體的動物給出自己的叫聲和種類名稱。
  2. 編寫模擬器類Simulator
    該類有一個playSound(Animal animal)方法,該方法的參數是Animal類型。即animal可以調用Animal的子類重寫的cry()方法播放具體動物的聲音,調用子類重寫的getAnimalName()方法顯示動物種類的名稱。
  3. 編寫Animal類的子類:Dog和Cat類
  4. 編寫主類Application(用戶程序)
    在主類Application的main方法中至少包含如下代碼;
    Simulatoer simulator =new Simulator();
    simulator.playSound(new Dog());
    simulator.playSound(new Cat());

下表爲Simulator、Animal、Dog、Cat的UML圖。
在這裏插入圖片描述

//Animal.java
public abstract class Animal{ //定義抽象類
	public abstract void cry(); //聲明抽象方法
	public abstract String getAnimalName();
}
//Simulator.java 
public class Simulator{ //編寫模擬器類
	public void playSound(Animal animal){ //實現調用對象參數方法,即animal參數可以調用Animal類子類的方法
		System.out.print("現在播放"+animal.getAnimalName()+"類的聲音:");
		animal.cry();
	}
}
//Dog.java
public  class Dog extends Animal{ //編寫Dog類繼承
	public void cry(){ //實現父類方法的內容
		System.out.println("汪汪....汪");
	}
	public String getAnimalName(){
		return "狗";
	}
}
//Cat.java 
public class Cat extends Animal{  //編寫Cat類繼承
	public void cry(){  //實現父類方法的內容
		System.out.println("喵喵.....喵喵");
	}
	public String getAnimalName(){
		return "貓";
	}
}

//Application.java
public class Application{  //編寫主類
	public static void main(String args[]){
		Simulator simulator=new Simulator(); //創建模擬器對象
		simulator.playSound(new Dog());  //調用模擬器方法參數爲Animal類型(對象的上轉型對象)
		simulator.playSound(new Cat());
	}
}
























發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章