【问题标题】:Only allow some classes to call a method in Java只允许某些类调用Java中的方法
【发布时间】:2011-08-11 07:18:09
【问题描述】:

假设我有这样的结构:

对象 A 包含对象 B 的一个实例
对象 B 包含对象 C 的一个实例

对象 D 扩展对象 C

我有一个对象 D 的实例,其他人将在我的程序中编写和使用它。我想拥有一些关于该对象的信息,但不让他们访问。我目前正在做的是将这些信息和方法存储在包含对象 D 而不是对象 C 的对象 B 中。

问题是,如果我将其设为私有以使对象 D 无法使用任何方法,那么我也无法从程序中的其他任何地方访问它们。有什么办法可以让 D 不能访问一个方法而其他类可以?

【问题讨论】:

  • 您可能想查看facade pattern
  • 嗯,我不太明白这对我有什么用。

标签: java inheritance visibility


【解决方案1】:

如果我正确理解了您的问题,您可能希望将抽象与实现分离,以便将来更改实现。

你可以通过实现Bridge Design Pattern来做到这一点。

编辑

回答您的评论:
您不能直接调用 CircleShape 的公共方法。 DrawingAPI 的具体实现(即 DrawingAPI1)不应该对 CircleShape 类的存在有任何想法。如果你不知何故需要调用调用者的某些方法,只需定义另一个接口并将调用者的引用传递给被调用者:

public interface CircleInfo {
  Color getBorderColor();
  /* some other methods */
}

public class CircleShape implements Shape, CircleInfo {
  public Color getBorderColor() {
    return Colors.Black; // not sure if it works, just an example
  }

  public void draw() {
    drawingAPI.drawCircle(x, y, radius, this);
  }   

  /* Other methods implementation here */
}

// DrawingAPI modification
interface DrawingAPI {
  public void drawCircle(double x, double y, double radius, CircleInfo info);
}

// Concrete implementation
class DrawingAPI1 implements DrawingAPI {
  public void drawCircle(double x, double y, double radius, CircleInfo info) {
    System.out.printf("API1.circle at %f:%f radius %f color %s\n",
      x, y, radius, info.getBorderColor().toString());
}

【讨论】:

  • 嗯,看看他们在该页面上的示例,似乎它可能有效。但是,使用该页面上的示例,DrawingAPI1 的 drawCircle 是否可以调用 CircleShape 中的公共方法?
  • 不能直接调用调用者的公共方法,请看我编辑的答案。
【解决方案2】:

听起来 D 不应该扩展 C。D 的实例应该有权访问它可以在需要时委托给它的实例。这个委托应该用一个你可以用 C 实现的接口来输入。该接口将仅包含 D 应该能够调用的那些方法。你将这个接口的一个实例注入到 D 中,这样它就可以做它需要的事情了。

public interface Delegate {
    public String getInformation();
}

public class C implements Delegate {
    public String getInformation() {...}
    public void otherMethod();
    public void anotherOtherMethod();
}         

public class D {
    private Delegate delegate;

    public D(Delegate delegate) {
        this.delegate = delegate;
    }

    public void printSomething() {
        System.out.println(delegate.getInformation());
    }
}

【讨论】:

  • 嗯,这让我有点过头了。让我再举一个例子,也许你可以为我进一步解释。所以对象 A 是一个团队,对象 B 是一个 PlayerObject。 PlayerObject 存储有关我需要的播放器的信息,并包含对实际 Player(C) 的引用。 D 是棒球运动员,所以它是球员的一种。我怎样才能做到这样我才能问玩家他想移动到哪里,但他实际上不能移动自己(以防止作弊)。这只是我大致需要做的一个简化示例。
  • 在这种情况下,您将让 PlayerObject 实现委托。 Player+(BaseballPlayer 等)将获得 PlayerObject 的一个实例。 (假设 Player+ 需要从 PlayerObject 中确定它想要移动的位置,但 Player+ 不应该能够调用其他 PlayerObject 方法。)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-09-03
  • 2019-04-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多