接口的實現類可以在覆寫默認方法中使用super來調用父接口中的成員么?


答案是不可以

 

一、super和this在子類中的使用
當一個子類繼承一個父類時,我們在子類的構造器中通過super()來調用其父類的構造器。

public class FatherClass {
	FatherClass(){
    }
}
 
class SonClass extends FatherClass{
    SonClass(){
        super();
    }
}

  


以上是一個最簡單的super()的用法,其中如果我們在子類的構造器中省略super(),那么編譯器會自動為子類的構造器中添加一個super()在第一行。(當父類有無參構造器時我們才可以省略)

super()僅能在子類構造器中調用,且只能調用一次。

此外,我們可以通過super.或者this.的方式來調用父類的變量或父類的方法以及當前子類的變量或當前子類的方法。

這個設計的目的是為了解決某些時候類的變量或方法可能被覆蓋。

例如:

public class FatherClass {
	int i = 10;
	
	FatherClass(){
	 }
	FatherClass(int i){
		this.i = i;
	}
	public void show() {
		System.out.println(this.i);
	}
}
 
class SonClass extends FatherClass{
	int i = 5;
	public void show() {
		System.out.println(super.i+"\n"+this.i+"\n"+i);
	}
}

  


顯然,子類定義int i = 5會覆蓋父類的i,如果我們不使用super或this,那么所有的i都將指向當前子類的i。

但通過super.i我們將可以調用父類的i。

同時,在父類的有參構造器中我們可以看到,如果形參名和類的變量名重復,那么形參將會覆蓋類的變量。

但我們可以通過this.i的方法來指向類的變量i而非形參i。

其次,我們可以通過當前子類.super.i或當前子類.this.i的方式來分別調用父類的i或者子類的i。

這一方式和直接使用super.i與this.i是等同的。

我們無法通過父類.super或父類.this的方式來調用父類的父類或父類。

二、super和this在內部類中的使用
對於內部類而言,super()和this的用法基本一致。

並且我們可以通過外部類.super和外部類.this的方法來調用外部類的父類和外部類。

(外部類和內部類的具體定義在此不詳細描述)

public class FatherClass {
	int i = 10;
	public void show() {
		System.out.println(i);
	}
}
 
class SonClass extends FatherClass{
	int i = 9;
	class InnerClass{
		int i = 8;
		public void show() {
		System.out.println(SonClass.super.i);
		System.out.println(SonClass.this.i);
		System.out.println(this.i);
		}
	}
	public void show() {
		System.out.println(super.i+"\n"+this.i+"\n"+i);
	}
}
 
class GrandsonClass extends SonClass{
	class InnerClass extends SonClass.InnerClass{
		public void show() {
			System.out.println(super.i);
		}
	}
}

  


三、super和this在實現類中的使用
當我們直接在實現類中使用super和this,以及當前類名.super和當前類名.this和一、二是一樣的。

但特殊的是,我們可以使用父接口.super的方式來調用父接口中的默認方法或變量(這種方式只能調用父接口中的默認方法)

(父接口.this的使用方法是錯誤的,不成立的行為)

有些人會問,為什么需要調用父接口中的方法或變量。

首先,父接口中的變量我們知道一定是static final修飾的一個public變量,那么我們可以直接通過父接口.變量名的方式來調用,和父接口.super.變量名的調用方式是等同的。(原文這里不對,public static final修飾的“變量”只能使用父接口名調用)

但是final修飾的常量變量是不能被繼承的,所以即便實現類中沒有對該變量進行覆蓋,我們仍然無法對其進行直接調用。

其次,父接口中的方法可以被調用的前提顯然是父接口中的方法被實現。

而接口中能夠實現方法的形式只有兩種,1.default修飾的方法(詳細內容可見筆記四)2.static final(靜態方法只用static修飾)修飾的方法。

對於第二種情況和調用接口變量是等同的,就不再贅述。

但第一種情況如果我們覆蓋了該方法,在其他情況下想要調用未重寫的該方法,我們必須通過父接口.super.方法名的方式來調用。

四、super和this在子接口中的使用
由於接口不是類,super和this的使用和類將會產生較大的區別。

首先我們無法在子接口中使用super,只能使用this。(接口名.super和接口名.this仍舊等價於super和this)

而對於父接口,我們無法通過super來調用的情況下,我們必須通過父接口名.super的方式來調用某個父接口。

也就是說父接口名.super指向的不是父接口的父接口,而是其本身。

這是因為一個接口可以繼承多個接口,我們無法直接使用super來指代某一個父接口,所以編譯器阻止了super這樣的用法,即便只繼承了一個父接口,改而使用父接口名.super這樣顯式的指出哪一個父接口。

五、特殊注意事項
盡管接口不是類,但我們仍然可以調用接口的getClass方法。

但是接口的getClass方法得到的class是其實現類。
————————————————
版權聲明:本文為CSDN博主「靈神君主」的原創文章,遵循CC 4.0 BY-SA版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/qq_36988636/article/details/107455282


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM