1. 程式人生 > >理解java的三大特性之繼承

理解java的三大特性之繼承

對象實例化 rgs 子類 name [] cto per 更改 成員變量

繼承是所有OOP語言不可缺少的部分,在java中使用extends關鍵字來表示繼承關系。當創建一個類時,總是在繼承,如果沒有明確指出要繼承的類,就總是隱式地從根類Object進行繼承。java語言不支持多重繼承,也就是說,子類至多只能有一個父類。

1.繼承的作用

通過繼承,子類可以使用父類中的一些成員變量和方法,從而提高代碼的重用性,提高開發效率。

2.哪些類不能被繼承

被final修飾的類不能被繼承。java中常見的不能被繼承的類有:String,StringBuffer,StringBuilder,以及基本類型的包裝類Double,Integer,Long等。

3.繼承的實現

3.1 子類可以繼承父類原有的屬性和方法,也可以增加父類所不具備的屬性和方法。

package zhishidian;

class Pet {
//父類的屬性,有被private和public修飾的 private String name = "無名氏"; //昵稱 private int health = 100; //健康值 public int love = 0; //親密度 /** * 無參構造方法 */ public Pet(){ this.health = 95; System.out.println("執行寵物的無參構造方法"); } /** * 有參構造方法 * @param name 昵稱 */ public Pet(String name){ this.name = name; } public String getName(){ return name; } public int getHealth(){ return health; } public int getLove(){ return love; } /** * 輸出寵物信息 */ public void print(){ System.out.println("寵物的自白:\n我的名字叫" + this.name + ",我的健康值是" + this.health + ",我和主人的親密程度是" + this.love + "。"); } } public class Dog extends Pet {    //子類可以增加父類所不具備的屬性和方法    private String strain;//品種 public String getStrain(){ return strain; } /** * 有參構造方法 * @param name 昵稱 * @param strain 品種 */ public Dog(String name, String strain){ //此處不能使用this.name=name; this.name繼承自父類,但是被private修飾。 super(name); this.strain = strain; } public static void main(String[] args) { // 1.創建寵物對象pet並輸出信息 Pet pet = new Pet("貝貝"); pet.print(); // 2.創建狗狗對象dog並輸出信息 Dog dog = new Dog("歐歐","雪納瑞"); //子類繼承父類原有的屬性和方法 dog.print(); System.out.println(dog.love); } }

3.2 直接重寫父類中的方法。

重寫(又叫覆蓋)是繼承的實現方式之一,也就是說只有在子類中才會出現方法的重寫。重寫是指在子類中保留父類成員方法的名稱不變,參數列表不變,重寫成員方法的實現內容,修改成員方法的返回值類型,或更改成員方法的存儲權限。(修改存儲權限只能從小的範圍到大的範圍修改,例如private可以修改為public,但是反向出錯)

package com.java.test;

class ExtendsTest{
	protected int adds(int a,int b){
		int s=0;
		s=a+b;
		return s;
	}
	protected ExtendsTest doIt(){
		return null;
	}
}
public class tests extends ExtendsTest{
	//重寫成員方法的實現內容,修改成員方法的存儲權限
	public int adds(int a,int b){
		return a;
	}
	//修改成員方法的返回值類型
	protected tests doIt(){
		return null;
	}
	//重構,只重寫實現內容
	protected int adds(int a,int b){
		System.out.println("重構");
		return a+b;
	}
}

4.父類中不能被子類繼承的內容

4.1 父類中的構造函數不能被子類繼承

構造函數必須與類名一致,並且不能有返回值(包括void),主要作用是完成對象的初始化工作。構造函數總是伴隨著new操作一起執行,且不能由程序的編寫者直接調用,必須要由系統調用,且只在對象實例化時自動調用一次(普通方法可以被對象調用多次)。

當父類沒有提供無參的構造函數時,子類的構造函數必須顯式地調用父類的構造函數,如果父類提供了無參數的構造函數,子類可以不顯式調用父類的構造函數,編譯器默認會調用父類提供的無參構造函數。當有父類時,在實例化對象時會先執行父類的構造函數,然後執行子類的構造函數。

package zhishidian;

class FathersClass{
	public FathersClass(String s){
		System.out.println("父類的構造函數執行");
	}
}
public class ConstructorTest extends FathersClass{
	/*
	 * 當父類沒有提供無參數的構造方法時,子類的構造函數(子類的構造函數可以有參數也可以沒有參數)中必須顯式
	 * 地調用父類的構造函數,使用super(參數名)調用,若沒有顯示調用,出錯;
	 * 當父類提供了無參的構造方法時,子類不需要顯式調用父類的無參構造方法,編譯器會默認調用父類的構造方法;
	 * */
	public ConstructorTest() {
		super("s");
		System.out.println("子類的構造函數執行");
	}
	public static void main(String[] args){
		//ConstructorTest繼承了FathersClass,繼承父類就是要獲得其成員變量成員方法,
		ConstructorTest ct=new ConstructorTest();
	}
}

運行結果:

父類的構造函數執行
子類的構造函數執行

父類中沒有無參的構造函數,若在子類的構造方法中不使用super("s")進行顯式調用父類的有參構造函數,出錯:

技術分享圖片

4.2 父類中被private和default修飾的成員變量和方法不能被子類繼承

子類只能繼承父類的非私有(被public和protected修飾)的成員變量和方法。

理解java的三大特性之繼承