在Java中实现朋友(可用C ++)功能

时间:2009-03-05 14:44:55

标签: java javadoc

好吧,让我们离开关于友谊是否打破封装的辩论,并且实际上尝试优雅地提出一个连贯的设计。这是一个双重功能:

1)关于如何实施的一般性问题:

   public class A 
   {
      friend class B;
   }

2)为什么我需要这个功能?我的一些类实现了Serializable接口。但是,我想在Derived类中使Serializable方法受到保护,这样我就不会将它们暴露给客户端(以及文档中的javadoc)。但是,内部类应该能够访问它们。在java中解决这个问题的一般方法是什么?

注意:我正在使用当前C ++标准中定义的友谊。

由于

5 个答案:

答案 0 :(得分:6)

一般的解决方案是使方法package-private(这是Java中的默认保护级别)。这样,同一个包中的任何代码都可以访问它们,但不能访问外部代码。

Java不允许任意共享具有特定外部类的方法。

编辑:受保护的成员实际上私有而不是package-private。如果您有受保护的成员,则可以从包外的派生类以及包内的任何类访问它们。这可能是您的问题的解决方案 - 在您要导出到的包中的另一个类中派生类。

通常,Java将包视为封装的主要模块。 public / protected接口用于包外的类,默认保护级别允许在包内访问。

答案 1 :(得分:2)

好像你想要一个外观。

您似乎有一个类需要提供对实现中涉及的各种其他类(甚至在不同的包中)的公共访问权限。但您不希望客户有权访问。

因此,请根据需要使实现变得复杂。有一个façade类,只需要你想要的接口,委托给实现。

答案 2 :(得分: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);
}
}

答案 3 :(得分:0)

我注意到的一件事......听起来你不想要覆盖你必须覆盖的方法,因为你正在实现Serializable被公开。但有一件事,Serializable是一个标记接口(它没有提供任何被覆盖的方法),而readObject和writeObject方法应该是私有的。

我错过了什么吗?

答案 4 :(得分:0)

您的问题有两种解决方案,不涉及将所有类保留在同一个包中。

第一种是使用(Practical API Design,Tulach 2008)中描述的Friend Accessor / Friend Package模式。

第二种是使用OSGi。有一篇文章here解释了OSGi如何实现这一目标。

相关问题:1234