Design patterns I';我希望只由特定类的对象调用方法

Design patterns I';我希望只由特定类的对象调用方法,design-patterns,oop,Design Patterns,Oop,假设您有这个类: public class A { private int number; public setNumber(int n){ number = n; } } 通过使该方法成为类“a”的成员,它只能由该类的对象调用 因此,如果您有另一个类为“B”的对象,那么它就不能调用setNumber,因为该方法不存在 还是我在你的问题中遗漏了什么 看来我有 如果还有另外两个类“C”和“D”,它们都包含对“a”实例的引用,那么这是另一个问题 我想不出一个“

假设您有这个类:

public class A { private int number; public setNumber(int n){ number = n; } }
通过使该方法成为类“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);
A myAinstance = new A();
myAinstance.setNumber(5);

假设您希望
setNumber
仅由类
AllowedSetNumber
调用。一种可能的解决方案是强制将
AllowedsetNumber
的实例作为参数传递,例如

public class A
{
    private int number;
    public setNumber(int n, AllowedSetNumber caller){
        number = n;
    }
}
那么问题就变成了,我如何阻止任何人创建
AllowedSetNumber
实例。这是相当容易确定的-你可以用对象工厂做到这一点。使
AllowedSetNumber
包的构造函数私有,甚至使用工厂方法私有

另一种不需要更改方法签名的替代方法是使用与java SecurityManager相同的线程本地安全上下文。这是通过分析对象请求权限时的堆栈跟踪来实现的,因此可以对调用代码进行身份验证,然后根据安全策略进行授权


请看

我需要澄清一下您所说的“特定类”的确切含义。。。但我希望我的解释是正确的,因为您只希望类A的实例能够调用该方法

public class A
{
  private int number;
  private void setNumber(int Number)
  {
    number = Number;
  }
}
在这种情况下,类A的任何实例都可以调用该方法:

C objectC = new C();
objectA.SetNumber(objectC, 23);
A myAinstance = new A();
myAinstance.setNumber(5);
但是,您不能像引用静态方法一样引用.setNumber(),而与实例无关

如果只希望派生类(来自任何程序集)能够调用它:

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

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

public class B : A
{
}
在这种情况下,类B或A的任何实例都可以调用setNumber(),但其他类无法看到或访问它

如果只希望同一程序集中的所有实例类都能够调用它:

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

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

public class B : A
{
}
在这种情况下,与类“A”相同的程序集中的任何类都可以像调用公共属性一样调用setNumber(),但其他程序集中包含的任何类都无法看到或引用它。在VB.NET中,internal与“Friend”相同

如果只希望同一程序集中的派生类能够调用它:

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

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

public class B : A
{
}
在这种情况下,B类或A类的任何实例都可以看到并引用setNumber();与类A位于同一程序集中的任何类都将能够看到它或引用它,就好像它是公共的一样


我认为这涵盖了每个选项…

我认为海报是在想象一个场景,其中一堆不同的类引用了类a的实例,但只有其中一些类应该能够调用特定的方法(取决于容器的类)。在您解释的场景中,我可能会使用像if(new[]{typeof(C),typeof(D)}.Contains(sender.GetType()){//Do stuff}这样的东西。您想要保护这个方法的深层原因是什么?安全性,用户权限,还有其他的吗?你能澄清一下在什么情况下可以调用它吗?i、 当你说“特定类”时,这个类是从类A派生出来的,它和类A在同一个集合中,还是仅仅是类A的实例?你可能想看看这个问题,问的问题基本上是一样的:类B不是从类A派生出来的。原因是拥有更改号码所需的所有信息的唯一类是ClassB。另一种方法是通过某种类似于反射的机制引用调用方(如果在所使用的框架中可用)。