1

我有一个类(Capsule),它有很多受保护的方法(30+)。这个想法是允许开发人员扩展这个类并使用类中的受保护方法(ImADev),但让开发人员将它们公开为公共(覆盖他们认为合适的方法)。

我现在有一个用例,我想将这些对象传递给一些实用程序类/方法,并允许它们访问受保护的方法..除非它们受到保护,所以我的实用程序类/服务看不到它们。

请参见下面的示例:

// My Capsule class with protected methods
public abstract class Capsule {
   public Capsule(..) { .. }
   protected String getFoo() { return "foo"; }
}

// How a dev should use the class
public class ImADev extends Capsule {
    public ImADev(..) { super(..); }
    public String getBar() { this.getFoo() + "BAR");
}

// A special utility class
// Helper.helper() can accept any class derived from Capsule
public class Helper {
    public String helper(Capsule c) { 
        return " im doing something awesome with " + c.getFoo();
        // Except i cant do this, because c.getFoo() is protected.
    } 
}

解决这个问题的最佳方法是什么?请记住,我有很多受保护的方法。

4

4 回答 4

2

要么您的班级做得太多,在这种情况下,将其分解为更小更明确的班级

或者,实现实用程序类可以调用的安全公共方法来包装受保护的方法

或者,只是将它们公开,因为听起来它们可能/应该是

或者,将类中的数据与行为(组合)分开,然后您的实用程序类只需处理更安全的公共 getter 方法,而不是可以更改内部的受保护行为方法

在不了解您的应用程序及其使用的情况下提供更好的答案有点困难

于 2012-05-24T23:07:52.093 回答
1

除了将实用程序类与具有受保护方法的类放在同一个包中之外,没有办法“解决”这个问题。如果这些类在一个以上的包中,那将无济于事。

在决定使用 protected 时,您做出了决定,现在您被其含义所困扰。您可以接受它、更改为公共或更改包成员资格以利用默认访问权限。

于 2012-05-24T23:03:59.103 回答
1

我看到至少有两个选择。

  1. 使 Helper 成为 Capsule 的子类。或者,
  2. 将受保护的方法转换为默认可访问性,并将 Helper 类与 Capsule 类放在同一个包中。

编辑:你也可以通过反射完成你想要的。

于 2012-05-24T23:08:04.083 回答
1

实际上有一种方法可以从包或子类外部调用受保护的方法:http: //docs.oracle.com/javase/1.5.0/docs/api/java/lang/reflect/AccessibleObject.html

我只是在开玩笑!该工具可用于诸如持久性序列化之类的技术内容。

将方法声明为“受保护”只是一种组织代码并定义哪个部分应该处理哪些数据的方法,因此尝试“绕过”并不是一个好主意,除非您错误地将其声明为受保护。在这种情况下,纠正第一个错误。

如果您对如何以高效和清晰的方式组织代码感兴趣,我强烈建议您阅读http://java.sun.com/docs/books/effective/

于 2012-05-24T23:09:34.800 回答