2009-03-05 1 views
1

Хорошо, давайте оставим дискуссию о том, как дружба разрывает инкапсуляцию, и на самом деле попробуйте элегантно придумать согласованный дизайн. Это функция два раза:Внедрение друга (доступно на C++) в Java

1) Общий вопрос о том, как реализовать:

public class A 
    { 
     friend class B; 
    } 

2) Зачем мне нужна эта функция? Некоторые из моих классов реализуют интерфейс Serializable. Тем не менее, я хочу сделать методы Serializable защищенными в классе Derived, чтобы я не выставлял их клиенту (а также в документации - javadoc). Однако внутренние классы должны иметь к ним доступ. Каков общий способ решения этой проблемы в java?

Примечание: Я использую дружбу, определенную в текущем стандарте C++.

Благодаря

+0

ли Java поддерживает «внутренний» модификатор, такой как C#? В C# вы можете использовать внутреннее, чтобы сделать вещи видимыми только в одной сборке. – OregonGhost

+0

Действительно недостаточно информации. В любом случае, если методы serialisable не являются приватными. –

+0

Да, вам не нужен доступ к методам сериализации для сериализации объектов. Это кажется аргументированным, а не вопросом ... – wds

ответ

6

Общим решения сделать методы частного пакет (который является уровнем защиты по умолчанию в Java). Таким образом, любой код в одном пакете может получить к ним доступ, но не внешний код.

Java не допускает произвольного совместного использования методов со специфическими внешними классами.

EDIT: Защищенные элементы на самом деле нет частный, чем частный. Если у вас есть защищенные члены, вы можете получить к ним доступ из производных классов вне вашего пакета и из любого класса внутри пакета. Таким образом, это может быть решением вашей проблемы - получить класс в другом классе в пакете, который вы хотите экспортировать.

Как правило, Java рассматривает пакет как основной модуль инкапсуляции. Открытый/защищенный интерфейс предназначен для классов вне пакета, а уровень защиты по умолчанию позволяет получить доступ к пакету.

+0

Ну, мне нужно получить к ним доступ из других внутренних пакетов :( – 2009-03-05 14:53:22

+0

Пакет-частный (доступ по умолчанию) должен быть довольно редким для любых типов, кроме типов верхнего уровня. –

+0

@ Тома: Я согласен. Я просто указывал, что это является единственным официально одобренным способом совместного использования внутренних компонентов. – Avi

2

Кажется, что вы хотите фасад.

У вас есть класс, который должен предоставить открытый доступ к различным другим классам (даже в разных пакетах), участвующих в реализации. Но вы не хотите, чтобы у клиентов был доступ.

Поэтому сделайте реализацию сложной, как вам нравится. Имейте фасад класса, только с интерфейсом вы хотите, делегировать на реализацию.

0

Одна вещь, которую я заметил ... похоже, что вы не хотите, чтобы методы, которые вы должны переопределить, потому что вы реализуете Serializable, чтобы быть обнародованы. Одна вещь, однако, Serializable является интерфейсом маркера (он не предоставляет никаких методов для переопределения), и методы readObject и writeObject должны быть частными.

Я что-то упустил?

0

Существует два решения вашего вопроса, которые не включают в себя сохранение всех классов в одном пакете.

Первый заключается в использовании шаблона Friend Accessor/Friend Package, описанного в (Практический дизайн API, Tulach 2008).

Второй способ - использовать OSGi. Существует статья here, объясняющая, как это делает OSGi.

Вопросы, относящиеся: 1, 2, 3 и 4.

2

Эта ссылка дает возможность эмулировать доступ друга в Java: http://macchiato.com/columns/Durable7.html

код копируется из ссылки (в случае, если сайт не доступен):

public class A { 
private int privateInt = 31415; 

public class SomePrivateMethods { 
    public int getSomethingPrivate() { return privateInt; } 
    private SomePrivateMethods() {} // no public constructor 
} 
public void giveKeyTo(B other) { 
    other.receiveKey(new SomePrivateMethods()); 
} 
} 

public class B { 
private A.SomePrivateMethods key; 

public void receiveKey(A.SomePrivateMethods key) { 
    this.key = key; 
} 

public void usageExample() { 
    A anA = new A(); 

    //int foo = anA.privateInt; // doesn't work, not accessible 

    anA.giveKeyTo(this); 
    int fii = key.getSomethingPrivate(); 
    System.out.println(fii); 
} 
}