簡體   English   中英

來自其他包的受保護方法調用

[英]Protected method call from other package

我以為我了解protected修飾符,但看起來我不了解。 例子很簡單:

package com;
public class Main {

     protected void method1() {
         // some code
     }
}

和:

package net;

import com.Main;

public class Out extends Main {

    public Out(){
         Main m = new Main();
         m.method1();
    }
}

為什么我不能從擴展Main的類中調用method1 編譯器錯誤建議將修飾符更改為public

我真的很困惑。

package com.example.furniture;

public class Seat {

    public boolean canAccommodate(int numberOfPeople) {
        return numberOfPeople <= getMaxNumberOfPeopleThatICanAccommodate();
    }

    protected int getMaxNumberOfPeopleThatICanAccommodate() {
        return 4;
    }

}


package com.example.furniture;

public class Chair extends Seat {

    public boolean willBreakIfNumberOfPeopleSittingExceeds(int numberOfPeople) {
        return numberOfPeople > getMaxNumberOfPeopleThatICanAccommodate();
    }

}

即使getMaxNumberOfPeopleThatICanAccommodate()沒有在Chair明確定義,上述方法也可以工作, Chair將使用來自Seat的實現。 protected修飾符允許子類調用(或覆蓋)該方法,也允許來自同一包的類調用該方法:

package com.example.furniture;

public class Bed {

    public boolean canFitMorePeopleThanThis(Seat seat) {
        return peopleICanFit() > seat.getMaxNumberOfPeopleThatICanAccommodate();
    }

    private int peopleICanFit() {
        return 2;
    }

}

使用受保護方法擴展該方法的類也可以覆蓋該方法:

package com.example.furniture;

public class ReallySmallChair extends Seat {

    public boolean willBreakIfNumberOfPeopleSittingExceeds(int numberOfPeople) {
        return numberOfPeople > getMaxNumberOfPeopleThatICanAccommodate();
    }

    @Override
    protected int getMaxNumberOfPeopleThatICanAccommodate() {
        return 1;
    }

}

但是,如果您嘗試從外部包訪問受保護的方法,它將不起作用:

package com.example.room;

public class LivingRoom {

    Seat seat = new Seat();
    Seat chair = new Chair();

    public boolean canAccommodate(int numberOfPeople) {
        int maxAccommodate = seat.getMaxNumberOfPeopleThatICanAccommodate() +
                chair.getMaxNumberOfPeopleThatICanAccommodate();

        return numberOfPeople <= maxAccommodate;
    }

}

嘗試訪問seat.get...chair.get...方法時,您將收到編譯器錯誤。

如果您在不同的包中有一個 Seat 的子類,那么您仍然可以訪問受保護的方法,因為它滿足兩個條件之一(子類或同一包中的另一個類),但只有它自己的方法:

package com.example.room;

public class RecreationalVehicle extends Seat {

    public boolean canAccommodate(int numberOfPeople) {
        return numberOfPeople <= getMaxNumberOfPeopleThatICanAccommodate();            
    }

}

這是有效的,因為getMaxNumberOfPeopleThatICanAccommodate()是一個屬於RecreationalVehicle的方法(它是一個子類)。 如果它試圖從Seat變量訪問它,它不會允許它,因為RecreationalVehicle不允許觸摸另一個實例的受保護方法,因為它不在同一個包中:

package com.example.room;

public class RecreationalVehicle extends Seat {

    Seat seat = new Seat();

    public void foo() {
        seat.getMaxNumberOfPeopleThatICanAccommodate();            
    }

}

會導致編譯器錯誤。

它不起作用,因為您在Out創建了Main實例( OutMain ,但Main不是Out )。

如果您直接調用method1 ,它將起作用:

public Out(){
    method1();
}

或者如果您有一個Out實例:

public Out(){
    Main m = new Main();
    ((Out)m).method1();
}

或者

public Out(){
    Out m = new Out();
    m.method1();
}

您可以在此處找到一些詳細信息(第 6.6.2 節):

對象的受保護成員或構造函數可以從包外部訪問,在該包中僅由負責實現該對象的代碼聲明它。

看起來你實際上可以從不同的包調用超類的方法,你只是不能明確地做到這一點:

package com.example.room;

import com.example.furniture.Seat;

public class RecreationalVehicle extends Seat{

RecreationalVehicle rec = new RecreationalVehicle();

public boolean canAccomodate(int numberOfPeople){

    int n = rec.getMaxNumber();

    getMaxNumber();
    return true;
    }
}

這個類沒有實現 getMaxNumber(),但是調用 rec.getMaxNumber() 就可以了。 那是對超類的實際調用,對嗎?

關鍵是:為什么我們不能在具有“父”引用類型的對象上從其他包調用超類的方法?

暫無
暫無

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

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