2010-06-02 19 views
0

的對象調用的方法假設你有這個類:我只想通過一個特定的類

 
public class A 
{ 
    private int number; 
    public setNumber(int n){ 
     number = n; 
    } 
} 

我想的方法setNumber只能由特定的類的對象調用。 它有道理嗎?我知道這是不可能的,是嗎?哪些是設計方案? 一些衆所周知的設計模式? 對不起這個愚蠢的問題,但我在OO設計中有點生疏。

編輯:我應該更清楚。抱歉。 我知道setNumber只能由A類的對象,我想一個特定類的,只有對象(有A類對象的引用)來調用,可以通過將方法的調用

 
classAObj.setNumber(n); 
+1

你爲什麼要防範這種方法的深層原因是什麼?安全,用戶權利,還有其他什麼? – mdma 2010-06-02 16:23:53

+0

你能否澄清一下可以調用它的情況?即當你說「特定的類」時,該類是從A類派生的,它會與A類在同一個程序集中,還是隻會是類A的實例? – BenAlabaster 2010-06-02 16:33:06

+0

你可能想看看這個問題基本上是一樣的: http://stackoverflow.com/questions/1609472/friend-class-with-limited-access – n1ckp 2010-06-02 16:38:15

回答

1

比方說,你想setNumberAllowedSetNumber類只能調用。一種可能的解決方案是要求您通過AllowedsetNumber的實例作爲參數,例如

public class A 
{ 
    private int number; 
    public setNumber(int n, AllowedSetNumber caller){ 
     number = n; 
    } 
} 

那麼接下來的問題是,我如何可以創建一個AllowedSetNumber實例制止。這很容易確定 - 你可以用對象工廠來做到這一點。使包的構造函數AllowedSetNumber私有,甚至私有工廠方法。

另一種不需要改變方法簽名的方法是使用與java SecurityManager相同的線程安全上下文。這可以通過在對象請求權限時分析堆棧跟蹤來實現,因此可以對調用代碼進行身份驗證,然後根據安全策略進行授權。

java.security.PrivilegedAction<T>

+0

將通過一些類似於反射的機制來引用調用者,如果它在所使用的框架中可用的話。 – BenAlabaster 2010-06-02 16:51:39

1

好「A」類的成員只能由該類的對象調用。

因此,如果您有另一個類「B」的對象,那麼它不能調用setNumber,因爲該方法不存在。

或者我錯過了你的問題中的某些東西?

看來我有。

如果你有兩個其他類「C」和「D」,它們都持有對「A」實例的引用,那麼這是一個不同的問題。

我想不出一個「好」的做法。該彈簧想到的唯一的事情就是:

public class A 
{ 
    private int number; 
    public setNumber(object sender, int n) 
    { 
     if (sender.GetType() == C) // Not sure of the exact syntax here 
     { 
      number = n; 
     } 
    } 
} 

然後當你調用setNumber你必須:

objectA.setNumber(this, 23); 

然而,這並不能阻止代碼的作者創建對象「C」型的,以傳遞到方法:

C objectC = new C(); 
objectA.SetNumber(objectC, 23); 
+0

我認爲海報正在想象一個場景,其中一堆不同的類引用了A類的實例,但只有其中一些應該能夠調用該特定方法(取決於容器的類)。 – 2010-06-02 16:22:55

+0

是的,這是場景。 – 2010-06-02 16:25:39

+0

在你正在解釋的場景中,我可能會使用類似if(new [] {typeof(C),typeof(D)} .Contains(sender.GetType())){//做的東西} – BenAlabaster 2010-06-02 17:01:08

0

我需要一些澄清,究竟你的意思是「特定的類」 ......但我希望我在正確的解釋,你只需要一個類的實例是能夠調用該方法。

public class A 
{ 
    private int number; 
    private void setNumber(int Number) 
    { 
    number = Number; 
    } 
} 

在這種情況下,A類的任何實例可以調用方法:

A myAinstance = new A(); 
myAinstance.setNumber(5); 

但是,您將無法指A.setNumber(),就好像它是一個靜態的方法 - 與實例無關。

如果只想派生類(從任何組件),才能稱之爲:

public class A 
{ 
    private int number; 
    protected void setNumber(int Number) 
    { 
    number = Number; 
    } 
} 

public class B : A 
{ 
} 

在這種情況下,B類的任何實例 A可以調用setNumber(),但沒有其他班級可以看到或訪問它。

如果你只是想在同一組件內的所有實例類可以稱之爲:

public class A 
{ 
    private int number; 
    internal void setNumber(int Number) 
    { 
    number = Number; 
    } 
} 

在這種情況下,相同的組件類中的任何類「A」將能夠調用setNumber()就好像它是一個公共屬性一樣,但其他程序集中不包含的類將能夠看到它或引用它。在VB.NET中,內部與「朋友」相同。

如果你只是想在同一組件內的派生類能夠調用它:

public class A 
{ 
    private int number; 
    protected internal void setNumber(int Number) 
    { 
    number = Number; 
    } 
} 

public class B : A 
{ 
} 

在這種情況下,B類一個無論組件的任何實例可以看到和參考setNumber( );並且與A類相同的程序集中的任何類將能夠看到它或引用它,就好像它是公共的。

我認爲這涵蓋了每個選項...