---------------------- <a href="http://www.itheima.com"target="blank">ASP.Net+Unity開發</a>、<a href="http://www.itheima.com"target="blank">.Net培訓</a>、期待與您交流! ----------------------
繼承
繼承是面對對象的三大特徵之一,也是實現多態的方式之一。
一個類繼承另一個類的時候,可以繼承除了構造函數以外的所有類成員。
繼承的優缺點:
繼承的優點:1,提高了代碼的複用性。
2,讓類與類之間產生了關係。有了這個關係,纔有了多態的特性。
繼承的缺點:打破了封裝性。
繼承的語法:
java中繼承用的extends關鍵字
如:
class A extends B{
}
注:千萬不要爲了獲取其他類的功能,簡化代碼而繼承。必須是類與類之間有所屬關係纔可以繼承。所屬關係 is a。
--------------------------------------------------------------------------------
繼承的規則:
Java語言中:java只支持單繼承,不支持多繼承。
因爲多繼承容易帶來安全隱患:當多個父類中定義了相同功能,
當功能內容不同時,子類對象不確定要運行哪一個。
但是java保留這種機制。並用另一種體現形式來完成表示。多實現。
java支持多層繼承。也就是一個繼承體系。
繼承中功能的使用:
想要使用體系,先查閱體系父類的描述,因爲父類中定義的是該體系中共性功能。通過了解共性功能,就可以知道該體系的基本功能。
那麼這個體系已經可以基本使用了。
那麼在具體調用時,要創建最子類的對象,爲什麼呢?
一是因爲有可能父類不能創建對象,
二是創建子類對象可以使用更多的功能,包括基本的也包括特有的。
簡而言之:查閱父類功能,創建子類對象使用功能。
示例代碼:
package com.itheima.base;
/**
* 繼承
* @author wuyong
*
*/
public class ExtendsDemo {
/**
* @param args
*/
public static void main(String[] args) {
Father father1 = new Father();
father1.show();
Sun sun = new Sun();
sun.show();
}
}
/**
* 父類Father
* @author wuyong
*
*/
class Father
{
void show()
{
System.out.println("father");
}
}
/**
* 子類Sun,繼承父類Father
* @author wuyong
*
*/
class Sun extends Father
{
void show()
{
System.out.println("sun");
}
void print(){
System.out.println("print");
}
}
/**
* java不支持多繼承,所以以下是錯誤的。
* @author wuyong
*
*/
//class C extends A,B{}
子父類出現後,類成員的特點:
類中成員:
1,子父類中的變量
如果子類中出現非私有(private)的同名成員變量時,子類要訪問本類中的變量,用this;子類要訪問父類中的同名變量,用super。
this代表的是本類對象的引用。
super代表的是父類對象的引用。
示例代碼:
package com.itheima.base;
/**
* 繼承
* @author wuyong
*
*/
public class FieldDemo {
/**
* @param args
*/
public static void main(String[] args) {
Father father1 = new Father();
Sun sun = new Sun();
sun.show();
sun.showName();
}
}
/**
* 父類Father
* @author wuyong
*
*/
class Father
{
public String name = "Father";
private int num = 4;
public void setNum(int num)
{
this.num =num;
}
public int getNum()
{
return this.num;
}
}
/**
* 子類Sun,繼承父類Father
* @author wuyong
*
*/
class Sun extends Father
{
int num = 15;
String name = "Sun";
void show()
{
System.out.println(num);
}
void showName(){
System.out.println("Father's name is " + super.name);
System.out.println("Sun's name is " + this.name);
}
}
2、子父類中的函數:
當子類出現和父類一模一樣的函數時,
當子類對象調用該函數,會運行子類函數的內容。
如同父類的函數被覆蓋一樣。這種情況是函數的另一個特性:重寫(覆蓋)
當子類繼承父類,沿襲了父類的功能,到子類中,
但是子類雖具備該功能,但是功能的內容卻和父類不一致,
這時,沒有必要定義新功能,而是使用覆蓋特殊,保留父類的功能定義,並重寫功能內容。覆蓋:
1,子類覆蓋父類,必須保證子類權限大於等於父類權限,纔可以覆蓋,否則編譯失敗。2,靜態只能覆蓋靜態。
重載與重寫的區別:
重載:只看同名函數的參數列表。
重寫:子父類方法要一模一樣。示例代碼:
package com.itheima.base;
/**
* 繼承
* @author wuyong
*
*/
public class MethodDemo {
/**
* @param args
*/
public static void main(String[] args) {
Father father1 = new Father();
father1.speak();
Father father2 = new Sun();
// father2.show();//無法調用子類的show方法,所有子類沒有重寫父類的show方法。
Sun sun = new Sun();
sun.show();
sun.speak();
}
}
/**
* 父類Father
* @author wuyong
*
*/
class Father
{
/**
* 父類show方法
* 私有的方法無法被子類繼承
*/
private int show()
{
System.out.println("Father's show");
return 1;
}
void speak()
{ show();
System.out.println("Father's speak");
}
}
/**
* 子類Sun,繼承父類Father
* @author wuyong
*
*/
class Sun extends Father
{
/**
* 重寫了父類的方法
* /
void speak()
{
//調用父類的speak方法
super.speak();
System.out.println("Sun's speak");
}
/**
* 此方法並不是重寫父類的方法,而是新的方法
*/
int show() //Zi中的show()無法覆蓋Fu中的show()
{
System.out.println("Sun's show");
return 0;
}
}
3、子父類中的構造函數:
在對子類對象進行初始化時,父類的構造函數也會運行,
那是因爲子類的構造函數默認第一行有一條隱式的語句 super();super():會訪問父類中空參數的構造函數。而且子類中所有的構造函數默認第一行都是super();
爲什麼子類一定要訪問父類中的構造函數?
因爲父類中的數據子類可以直接獲取。所以子類對象在建立時,需要先查看父類是如何對這些數據進行初始化的。
所以子類在對象初始化時,要先訪問一下父類中的構造函數。
如果要訪問父類中指定的構造函數,可以通過手動定義super語句的方式來指定。
注意:super語句一定定義在子類構造函數的第一行。
子類的實例化過程:
1.初始化父類的static成員。2.初始化子類的static成員。
3.在棧和堆中定義子類變量並默認初始值,定義方法。4.調用子類的構造方法運行了super();
5.調用父類的構造方法並立即執行父類的構造代碼塊。6.給父類的變量默認初始化,然後顯示賦值。
7.父類構造方法繼續運行,定義父類的屬性和方法。9.執行父類構造方法中其他語句(比如調用方法)。
10.執行子類的構造代碼塊
11.給子類變量賦值。12.子類構造方法繼續執行,定義子類的屬性和方法。
13.再次給子類變量賦值。14.執行子類構造方法中其他語句。
結論:
子類的所有的構造函數,默認都會訪問父類中空參數的構造函數。
因爲子類每一個構造函數內的第一行都有一句隱式super();
當父類中沒有空參數的構造函數時,子類必須手動通過super語句形式來指定要訪問父類中的構造函數。
當然:子類的構造函數第一行也可以手動指定this語句來訪問本類中的構造函數。
子類中至少會有一個構造函數會訪問父類中的構造函數。
示例代碼:
package com.itheima.base;
/**
* 繼承
* @author wuyong
*
*/
public class InstanceDemo {
/**
* @param args
*/
public static void main(String[] args) {
Father father1 = new Sun();
father1 = new Sun(10);
}
}
/**
* 父類Father
* @author wuyong
*
*/
class Father
{
static String name = "Father";
static{
System.out.println("staticBlock == " + name);
}
int num = 5;
Father()
{
//super();
num= 60;
System.out.println("Father run");
}
Father(int num)
{
System.out.println("Father ...." + this.num);
}
}
/**
* 子類Sun,繼承父類Father
* @author wuyong
*
*/
class Sun extends Father
{
static String name = "Sun";
static{
System.out.println("staticBlock == " + name);
}
Sun()
{
super();
//super(4);
System.out.println("Sun run");
}
Sun(int num)
{
//有了this()後,就沒有super()了,因爲this和super都必須是第一行數據,對對象進行初始化。
// this();
//super();
super(3);
System.out.println("Sun..." + num);
}
}
---------------------- <a href="http://www.itheima.com"target="blank">ASP.Net+Unity開發</a>、<a href="http://www.itheima.com"target="blank">.Net培訓</a>、期待與您交流! ----------------------