Java面向對象三大特徵之一 —— 繼承的相關概念

(一)、概念

  • 繼承:就是子類繼承父類的屬性行爲,使得子類對象具有與父類相同的屬性、相同的行爲。子類可以直接訪問父類中的非私有的屬性和行爲.
  • 多個類可以稱爲子類,單獨那一個類稱爲父類超類(superclass)或者基類
  • 繼承描述的是事物之間的所屬關係,這種關係是:is-a 的關係。
    在這裏插入圖片描述

(二)、繼承的格式

  • 通過extends關鍵字,可以聲明一個子類繼承另外一個父類,定義格式如下:
class 父類 {
	...
}
class 子類 extends 父類 {
	...
}

繼承演示,代碼如下:

/*定義員工類Employee,做爲父類*/
class Employee {
	String name; // 定義name屬性
	// 定義員工的工作方法
	public void work() {
		System.out.println("盡心盡力地工作");
	}
}

/* 定義講師類Teacher 繼承 員工類Employee*/
class Teacher extends Employee {
	// 定義一個打印name的方法
	public void printName() {
		System.out.println("name=" + name);
	}
}

/* 定義測試類*/
public class ExtendDemo01 {
	public static void main(String[] args) {
		// 創建一個講師類對象
		Teacher t = new Teacher();
		// 爲該員工類的name屬性進行賦值
		t.name = "小明";
		// 調用該員工的printName()方法
		t.printName(); // name = 小明
		// 調用Teacher類繼承來的work()方法
		t.work(); // 盡心盡力地工作
	}
}

(三)、繼承後的特點——成員變量

3.1 成員變量重名

  • 在父子類的繼承關係當中,如果成員變量重名,則創建子類對象時,訪問有兩種方式:
    ①、直接通過子類對象訪問成員變量:【等號左邊是誰,就優先用誰,沒有則向上找】。
    在這裏插入圖片描述
class Fu {
	// Fu中的成員變量。
	int num = 5;
}

class Zi extends Fu {
	// Zi中的成員變量
	int num = 6;

	public void show() {
		// 訪問父類中的num
		System.out.println("Fu num=" + num);
		// 訪問子類中的num
		System.out.println("Zi num=" + num);
	}
}

class ExtendsDemo03 {
	public static void main(String[] args) {
		// 創建子類對象
		Zi z = new Zi();
		// 調用子類中的show方法
		z.show();
	}
}
演示結果:
Fu num = 6
Zi num = 6

3.2 區分子類方法中重名的三種

  • 子父類中出現了同名的成員變量時,在子類中需要訪問父類中非私有成員變量時,需要使用super關鍵字,修飾父類成員變量。
  • 使用格式:
super.父類成員變量名
class Zi extends Fu {
	// Zi中的成員變量
	int num = 6;

	public void show() {
		//訪問父類中的num
		System.out.println("Fu num=" + super.num);
		//訪問子類中的num
		System.out.println("Zi num=" + this.num);
	}
}
演示結果:
Fu num = 5
Zi num = 6

Fu 類中的成員變量是非私有的,子類中可以直接訪問。若Fu 類中的成員變量私有了,子類是不能
直接訪問的。通常編碼時,我們遵循封裝的原則,使用private修飾成員變量,那麼如何訪問父類的私有成員變量呢?對!可以在父類中提供公共的getXxx方法和setXxx方法。

②、通過間接的成員方法訪問成員變量:【該方法屬於誰,就優先用誰,沒有則向上找。】
在這裏插入圖片描述

class Fu {
	int num = 100;
	public void methodFu() {
		//使用本類當中的,不會向下找子類的
		System.out.println(num);
	}
}

class Zi extends Fu {
	int num = 200;
	public void methodZi() {
		//因爲本類當中有num,所以這裏使用的是本類的num
		System.out.println(num);
	}
}

class ExtendsDemo03 {
	public static void main(String[] args) {
		Fu fu = new Fu();
		Zi zi = new Zi();
		//這個方法是子類的,優先使用子類的,如果沒有再向上找
		zi.methodZi();//200
		//這個方法是在父類當中定義的
		fu.methodFu();//100
	}
}

(四)、成員方法重名——重寫(Override)

  • 在父子類的繼承關係當中,創建子類對象,訪問方法的規則:【創建的對象是誰,就優先用誰,如果沒有則向上找。】
  • 注意事項:無論是成員方法還是成員變量,如果沒有都是向上找父類,絕對不會向下找子類的。
class Fu {
	public void methodFu() {
		System.out.println("父類方法執行!");
	}
	public void method() {
		System.out.println("父類重名方法執行!");
	}
}

class Zi extends Fu{
	public void methodZi() {
		System.out.println("子類方法執行!");
	}
	public void method() {
		System.out.println("子類重名方法執行!");
	}
}

public class ExtendsDemo03{
	public static void main(String[] args) {
		Zi zi = new Zi();
		
		zi.methodFu();
		zi.methodZi();
		
		//創建的是new了子類對象,所以優先使用子類方法
		zi.method();
	}
}
  • 如果子類父類中出現重名的成員方法,這時的訪問是一種特殊情況,叫做方法重寫 (Override)。
  • 方法重寫:子類中出現與父類一模一樣的方法時(返回值類型,方法名和參數列表都相同),會出現覆蓋效果,也稱爲重寫或者複寫。聲明不變,重新實現

1.方法覆蓋重寫的注意事項:

  1. 必須保證父子類之間方法的名稱相同,參數也相同。@Override:寫在方法前面用來檢測是不是有效的正確覆蓋重寫。
  2. 子類方法的返回值必須【小於等於】父類方法的返回值範圍。注意:java.lang.Object類是所有類的公共最高父類,java.lang.String就是Object的子類。
  3. 子類方法的權限必須【大於等於】父類方法的權限修飾符。提示:public > protected > ( default) > private。備註:(default)不是關鍵字,而是什麼都不寫,留空。

2. 重寫的應用

子類可以根據需要,定義特定於自己的行爲。既沿襲了父類的功能名稱,又根據子類的需要重新實現父類方法,從而進行擴展增強。比如新的手機增加來電顯示頭像的功能,代碼如下
在這裏插入圖片描述

//本來的老款手機
class Phone {
	public void call() {
		System.out.println("打電話");
	}
	public void send() {
		System.out.println("發短信");
	}
	public void show() {
		System.out.println("顯示號碼");
	}
}

//定義一個新的手機,使用老手機作爲父類
class NewPhone extends Phone {
	@Override
	public void show() {
		super.show();// 把父類的show方法拿過來重複使用
		// 自己子類再添加更多內容
		System.out.println("顯示姓名");
		System.out.println("顯示頭像");
	}
}

public class Demo01Phone {

	public static void main(String[] args) {
		Phone phone = new Phone();
		phone.call();
		phone.send();
		phone.show();
		System.out.println("-----------");
		NewPhone newPhone = new NewPhone();
		newPhone.call();
		newPhone.send();
		newPhone.show();
	}
}
運行結果:
打電話
發短信
顯示號碼
-----------
打電話
發短信
顯示號碼
顯示姓名
顯示頭像

這裏重寫時,用到super.父類成員方法,表示調用父類的成員方法

注意事項
①、 子類方法覆蓋父類方法,必須要保證權限大於等於父類權限。
②、 子類方法覆蓋父類方法,返回值類型、函數名和參數列表都要一模一樣。

(五)、繼承後的特點——構造方法

繼承關係中,父子類構造方法的訪問特點:
①、子類構造方法當中有一個默認隱含的" super() "調用,所以一定是先調用的父類構造,後執行的子類構造。
②、子類構造可以通過super關鍵字來調用父類重載構造。
③、super的父類構造調用,必須是子類構造方法的第一個語句。不能一個子類構造調用多次super構造。

總結:子類必須調用父類構造方法。不寫則贈送super():寫了則用寫的指定的super調用。super只能有一個,還必須是第一個。

class Fu{
	public Fu() {
		System.out.println("父類無參構造");
	}
	public  Fu(int num) {
		System.out.println("父類有參構造");
	}
}
class Zi extends Fu{
	public Zi() {
//		super();//在調用父類無參構造方法
		super(20);//在調用父類重載的構造方法
		System.out.println("子類構造方法");
	}
}

public class Demo01 {

	public static void main(String[] args) {
		Zi zi = new Zi();
	}
}

(六)、 super和this

6.1 super關鍵字用來訪問父類的內容,用法有三種:

  1. 在子類的成員變量方法中,訪問父類的成員變量。
  2. 在子類的成員方法中,訪問父類的成員方法。
  3. 在子類的構造方法中,訪問父類的構造方法。

6.2 this關鍵字用來訪問本類內容,用法也有三種:

  1. 在本類的成員方法中,訪問本類的成員變量。
class Fu{
	int num = 10;
}
class Zi extends Fu {
	int num = 20;
	System.out.print(num);//局部變量
	System.out.print(this.num);//本類中的成員變量
	System.out.print(super.num);//父類中的成員變量。
}
  1. 在本類的成員方法中,訪問本類的另一個成員方法。
public void methodA(){
	System.out.print("AAA");
}
public void methodB(){
	this.methodA();
	System.out.print("BBB");
}
  1. 在本類的構造方法中,訪問本類的構造方法。
    【在第三種用法當中要注意:
    ①、this(…)調用也必須是構造方法的第一個語句,唯一一個。
    ②、super和this兩種構造調用,不能同時使用。】
public Zi(){
	this(123);//本類的無參構造,調用本類的有參構造
}
public Zi(int n){
}

在這裏插入圖片描述

(七)、Java繼承的特點

在這裏插入圖片描述

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