Я хотел бы, чтобы метод вызывался только объектами определенного класса - PullRequest
0 голосов
/ 02 июня 2010

Предположим, у вас есть этот класс:

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

Мне бы хотелось, чтобы метод setNumber мог вызываться только объектами определенного класса. Имеет ли это смысл? Я знаю, что это невозможно, не так ли? Какие есть варианты дизайна? Какой-то хорошо известный шаблон дизайна? Извините за глупый вопрос, но я немного заржавел в дизайне ОО.

РЕДАКТИРОВАТЬ: Я должен быть более ясным. Сожалею. Я знаю, что setNumber может вызываться только объектами класса А. Мне бы хотелось, чтобы только объекты определенного класса (имеющие ссылку на объекты класса А) могли вызывать

classAObj.setNumber(n);

Ответы [ 3 ]

1 голос
/ 02 июня 2010

Допустим, вы хотите, чтобы setNumber вызывался только по классу AllowedSetNumber. Одним из возможных решений является обязательное указание экземпляра AllowedsetNumber в качестве параметра, например

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

Тогда возникает вопрос: как я могу остановить создание экземпляра AllowedSetNumber? Это немного легче прибить - вы можете сделать это на объектных фабриках. Создание конструктора пакета AllowedSetNumber приватным или даже приватным с помощью фабричного метода.

Другая альтернатива, которая не требует изменения сигнатуры метода, - это иметь контекст безопасности локального потока в том же ключе, что и java SecurityManager. Это работает путем анализа трассировки стека, когда объект запрашивает разрешение, и поэтому вызывающий код может быть аутентифицирован, а затем авторизован в соответствии с политикой безопасности.

См. java.security.PrivilegedAction<T>

1 голос
/ 02 июня 2010

Хорошо, сделав метод членом класса "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 голосов
/ 02 июня 2010

Мне нужно уточнить, что именно вы подразумеваете под «определенными классами» ... но я надеюсь, что я правильно интерпретирую, что вы хотите, чтобы только экземпляры класса A могли вызывать метод.

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 или A независимо от сборки могут видеть и ссылаться на setNumber (); и любые классы в той же сборке, что и класс А., смогут видеть его или ссылаться на него, как если бы он был общедоступным.

Я думаю, что охватывает каждый из вариантов ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...