Могу ли я ограничить методы, которые может вызвать другой класс на Java?
Предположим, что у меня есть классы A
, B
и C
, где класс C
имеет читаемые и записываемые свойства:
public class C {
private int i = 0;
// Writable.
public void increment() { i++; }
// Readable.
public int getScore() { return i; }
}
Можно ли использовать A
только метод increment()
и только B
использовать метод getScore()
?
Ответы
Ответ 1
Нет, невозможно назначить доступ для каждого класса.
Рассмотрите возможность разделения вашего класса на отдельные интерфейсы, чтобы каждый класс получал объект с требуемым интерфейсом. Например:
interface Incrementable { public void increment(); }
interface HasScore { public int getScore(); }
class C implements Incrementable, HasScore { /* ... */ }
class A {
public A(Incrementable incr) { /* ... */ }
}
class B {
public B(HasScore hs) { /* ... */ }
}
Конечно, есть последствия для безопасности, но это должно заставить вас думать в правильном направлении.
Ответ 2
Да, это так, но вам нужно пройти через некоторые колебания.
public interface Incrementable {
public void increment();
}
public interface Readable {
public int getScore();
}
public class C implements Incrementable, Readable
{
...
}
Теперь, когда вы определяете метод в A, который получает ссылку на экземпляр B
, определите этот метод вместо Incrementable
. Для B
определите его, чтобы взять Readable
.
Ответ 3
Java имеет четыре области: частный, защищенный, общедоступный и "пакет". Кое-что, что доступно публике, можно получить из любого места. защищен только от подклассов. частный - это только тот класс. Область "пакет" не называется, но если вы опускаете любой из трех других, предполагается область пакета. Это доступно только для других классов в одном пакете.
НТН.
Ответ 4
Нет, это невозможно сделать.
Ответ 5
Не то, что вы захотите, но вы можете подойти к трассировке стека (создать исключение) и проверить класс, вызывающий метод инкремента.
Ответ 6
Хотя прямой ответ - нет, другим способом (уродливым) может быть создание двух интерфейсов, расширяющих третью (или вы можете просто взять параметр Object как):
Reader и Writer, чтобы передать вызывающий класс в качестве параметра для каждой функции:
public interface Caller;
public interface Reader extends Caller;
public interface Writer extends Caller;
public void increment(Caller c) {
if (c instanceof Writer) {
i++;
}
}