簡體   English   中英

Java-幫助我了解對子類的受保護成員的訪問(再次)

[英]Java - Help me Understanding Access to protected members from subclass (Again)

好吧,我必須承認我是Java編程的新手,並且很猶豫在此處發布問題,因為有很多與我的問題相似的問題。 我已經查看了這些問題,但仍然無法理解“受保護”修飾符背后的邏輯是什么。 所以我認為最好在這里發表我自己的問題。

這是PackOne包中的A

package PackOne;

public class A {

    protected void protectedMethod() {
        System.out.println("A's protectedMethod");
    }

}

這是PackTwo包中的B類。 但是,它是A類的子類。

package PackTwo;

import PackOne.A;

public class B extends A {

    public static void main(String[] args) {

        //Test 1 
        protectedMethod(); //error: non-static method protectedMethod()
                           // cannot be referenced from a static context.

        //Test 2
        A instanceofA = new A();
        instanceofA.protectedMethod();//error: protectedMethod() 
                                      //has protected access in PackOne.A
    }

    public void anotherMethodOfB() {

        //Test 3
        protectedMethod();//Pass 
    }

    //Test 4
    A instanceofA = new A();
    instanceofA.protectedMethod();//error: package instanceofA does not existed.
}

請說明為什么只傳遞了Test 3對類A受保護方法的調用,而其他3個Tests(1,2,4)卻產生了錯誤?

這與子類無關。

您不能從靜態函數中調用非靜態方法。 現在

public static void main

是靜態的,而

protectedMethod()

不是。

其次,您不能從類“外部”調用受保護的方法。 如果您在B類中,則不能調用另一個非B類的受保護方法。

最后,對於第4點,此代碼不是方法的一部分,因此根本沒有任何意義。

測試1:這與受保護/私有/公共無關-您需要A的對象實例才能調用此方法。

測試2:您不在A或B的對象實例中,而是在靜態方法中。 您需要從A或B內調用受保護的方法-在靜態方法中不在類之內,僅實例計數。

測試3:您在實例中。

測試4:與測試2相同-這是一個匿名的靜態方法。

這不僅僅意味着您不了解protected訪問,還不了解您可以在何處調用實例方法。

protectedMethod()是可以在類A 實例上調用的方法。

main()的第一個方法調用無效,因為您沒有嘗試在A實例上調用該方法main()是靜態方法,因此它屬於B 而不是B實例。

第四個無效,因為您不能在方法主體外部將方法作為語句調用。

要了解您的問題,您首先需要了解訪問修飾符:

  • Public :任何類都可以訪問此函數/變量。 (您仍然必須先創建一個實例)
  • 私有 :沒有其他類可以訪問此函數/變量。 只能在類內部訪問它。 您仍然可以使用該類中的公共函數來訪問其私有函數和變量,但是無法直接訪問。 請注意,私有函數和變量不被繼承(即不屬於子類)。
  • 受保護的 :受保護的函數和變量只能由該類及其任何子類(任何直接/間接從其繼承的類)訪問。

靜態 :允許您調用函數而不必先創建對象。 Math類是一個很好的示例,因為它僅包含靜態方法和變量(甚至無法實例化)。 (注意:Static不是訪問修飾符。它不僅執行此操作,還需要執行其他操作,如果您想了解更多,請查詢一下)

至於你的例子:

  1. 測試1 :您的方法是從類A繼承的,因此可以使用。 但是,由於它不是靜態方法,因此無法直接訪問它:您需要將其設置為靜態,或者創建B類的實例,然后通過該實例調用該函數。
  2. 測試2 :這無效,因為A和B位於不同的包裝中。 僅在同一個程序包中允許訪問受保護的方法(即使一個程序繼承自另一個程序)。 如果A和B在同一包中,則可以使用。
  3. 測試3 :對象B繼承了A的公共方法和受保護的方法。訪問的不是A中的方法,而是B中的繼承方法。要看到這一點,請將A的代碼更改為以下代碼:

     <!-- language: java --> protected void protectedMethod() { System.out.println(getClass().getName() + ("'s Protected method")); } 

    執行此操作將得到B's Protected method

  4. 測試4 :在函數外部執行代碼不起作用。 永遠不要這樣做。

注意:您可以通過反射訪問私有和受保護的變量,盡管這是高級得多的事情。 通常也不是一個好主意,因為出於某種原因將變量設置為私有/受保護(例如,防止未經授權的訪問/修改)

  • 父類中的protected方法允許子類在內部使用它,這就是“測試3”通過的原因。
  • 測試1失敗,因為main是靜態方法,無法訪問非靜態字段和函數。
  • 測試2失敗,因為您嘗試通過實例調用protected方法,這是不允許的。 與測試4相同。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM