簡體   English   中英

Java類,其字段只能由其子類訪問(沒有getter / setter)?

[英]Java class whose fields are only accessible to its subclasses (without getters/setters)?

我真正想要的是一個帶有泛型構造函數的類,當調用子類的相同構造函數時,子類將可以訪問相同的字段。 這是我想做的一個例子:

public abstract class Command{
    private Mediator m

    public Command(Mediator med){
       m = med;
    }

    abstract void exec();
}

public class FoobarCommand extends Command{
    public FoobarCommand(Mediator med){
        super(med);
    }

    public void exec(){
        med.doAFoobar()
    }
 }

public static void main(String[] args){
    Mediator m = new Mediator();
    Command c = new FoobarCommand(m);
    c.exec();
}

顯然這不起作用,因為FoobarCommand沒有直接訪問Mediator med。 那么你將如何訪問med領域? 我不希望除了子類之外的任何人都可以訪問它,並且“protected”不是一個選項,因為我希望人們能夠創建自己的命令(顯然這些命令在包之外)。

嚴格來說,實際上沒有這樣的訪問修飾符。 聲明只能訪問子類的字段(或方法/類)是不可能的; 您可以使用的限制性最強的修飾符是protected ,它仍然允許訪問父類包中的其他類。

但除了那個niggle之外, protected是要走的路。

編輯 :澄清受保護一種選擇。 訪問受保護的方法,你必須一個子類同一包中; 你不必兩個都是。 因此,在不同的包中創建的Command的子類仍然可以訪問(super).m

聲明Mediator Med為“受保護”而非私人。

你需要申報Mediator在你的母班保護。

此外,在子類的exec()方法中,您需要執行m.doAFoobar()而不是med.doAFoobar(),因為med不是成員,而是構造函數的形式參數。

abstract class Command {
    protected Mediator m

    public Command(Mediator med){
        m = med;
    }

    abstract void exec();
}

該類不是公共的,因此它只能由同一個包中的其他類擴展,並且'm'受到保護,因此可以通過派生類訪問它。

如果您提供med受保護的訪問權限,則它將可用於包外部的子類。

http://java.sun.com/docs/books/tutorial/java/javaOO/accesscontrol.html

如果希望只有類本身以及該包中的任何派生類和其他類可以訪問字段,請使用protected關鍵字。 這就是它的用途,它甚至應該在包裝之外工作。 他們不需要調用med.doFoobar();而是需要調用m.doFoobar();

或者,您可以創建受保護(或公共,甚至)get函數。 這樣你就暴露了獲取中介的能力,但你不必讓它們在聲明后覆蓋它。

但是,在java keywording中,你想要的東西(無法在包中讀取)是不可能的。 但是,既然你是編寫這個特定軟件包的人,那么你不能從包內部訪問它嗎? 或者只用這個文件創建自己的包? 沒有辦法允許子類訪問,也不允許包中的類。

你可以做的是給子類一個名為完全相同的變量,然后使用構造函數和方法將它設置為超類

public abstract class Command{
    private Mediator m

    public Command(Mediator med){
       m = med;
    }

    abstract void exec();
}

public class FoobarCommand extends Command{

    private Mediator m;

    public FoobarCommand(Mediator med){
        super(med);
        m = med;
    }

    public void exec(){
        m.doAFoobar()
    }
 }

public static void main(String[] args){
    Mediator m = new Mediator();
    Command c = new FoobarCommand(m);
    c.exec();
}

但是,它的功能有限。 由於m是一個對象引用,子類中m更改將反映在超類中; 但是,如果類成員是基元,則不會發生這種情況。 (鑒於所有基元都具有等效的對象,如果稍微笨重,這可以解決)

子類還必須直接接收引用,因為存儲了引用的副本。 對於抽象超類,這很好,因為你可以保證一個子類,但在下面你必須要小心如何處理數據。

暫無
暫無

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

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