6

我正在编写(嗯,完成)Java 的“扩展”,这将有助于角色编程。
我使用 javacc 将我的代码翻译成 Java 代码。我的编译器向每个声明的类添加了一些代码。这是一个更清楚的例子:

MyClass extends String implements ObjectWithRoles { //implements... is added
    /*Added by me */
    public setRole(...){...}
    public ...
    /*Ends of stuff added*/
    ...//myClass stuff
}

它为您声明的每个单独的类添加了实现.. 和必要的方法。相当粗糙,不是吗?

如果我在一个类中编写我的方法并且所有类都扩展它会更好..但是..如果类已经扩展了另一个类(就像示例一样)?

我不想创建一种管理角色的包装器,因为我不希望程序员必须知道的不仅仅是 Java,很少有新的保留字及其使用。

我的想法是扩展 java.lang.Object.. 但你不能。(对吗?)
其他想法?

我是新来的,但我关注这个网站,所以谢谢你的阅读和你给出的所有答案!(我为英语道歉,我是意大利人)

4

6 回答 6

6

如果它只是一个“研究”项目,您想探索这种扩展如何工作,您可以提供您自己的Object类实现。只需复制现有的对象实现,添加您的setRole方法等,并-Xbootclasspath:.:/usr/lib/jvm/java-6-sun/jre/lib/rt.jar作为参数提供给 java 命令。(我会先寻找 api-classes.再寻找真正的rt.jar.)

于 2010-05-18T08:35:18.677 回答
3
  • 您可以扩展Object- 每个类都扩展它。
  • 您似乎需要多重继承之类的东西-Java中没有这样的东西
  • 如果要添加功能,请使用对象组合。IE,

    YourClass extends Whatever implements ObjectWithRoles {
        private RoleHandler roleHandler;
        public RoleHandler getRoleHandler() {..} // defined by the interface
    }
    

然后所有的方法都放在RoleHandler

于 2010-05-18T08:29:33.477 回答
3

你应该考虑使用组合而不是继承来解决这个问题;这样,您就可以提供所需的功能,而无需在继承时使用“一次性”。

比如JDK提供了一个类PropertyChangeSupport,可以用来管理PropertyChangeListeners和s的触发PropertyChangeEvent。在您希望编写一个触发PropertyChangeEvents 的类的情况下,您可以嵌入一个PropertyChangeSupport实例变量并将所有方法调用委托给它。这避免了继承的需要,意味着您可以用新功能补充现有的类层次结构。

public class MyClass extends MySuperClass {
  private final PropertyChangeSupport support;

  public MyClass() {
    this.support = new PropertyChangeSupport(this);
  }

  public void addPropertyChangeListener(PropertyChangeListener l) {
    support.addPropertyChangeListener(l);
  }

  protected void firePropertyChangeEvent() {
    PropertyChangeEvent evt = new ...
    support.firePropertyChangeEvent(evt);
  }
}
于 2010-05-18T08:29:55.910 回答
2

如果您正在谈论为所有对象添加角色,我也会考虑基于注释的解决方案。你会用@Role("User") 之类的东西来注释你的类。在另一个类中,您可以提取该角色值并使用它。

我认为它需要一个具有运行时保留的注释,您可以在运行时使用反射检查注释是否存在,并使用getAnnotation获取该注释。我觉得这比自动扩展所有类要干净得多。

我相信有些框架正是使用这样的解决方案,所以应该在某处有示例代码。

于 2010-05-18T08:44:01.363 回答
1

如果你正在做你正在做的事情,那么继承可能不是正确的习语。您可能需要考虑装饰器模式,即构建一个类,该类将其他功能较少的类作为其参数,并向其添加一些附加功能,将已经存在的功能委托给现有类。如果实现对您的许多装饰器来说是通用的,您可能需要考虑将该功能放在可以共享的类中,并且您可以将所有装饰器委托给该类。根据您的需要,双重调度或反射可能是合适的,以便为各种类制作相似但不完全相同的装饰器。

此外,正如评论中所指出的,String 被声明为“final”,因此不能扩展。因此,您应该真正考虑一种委托/装饰对象的解决方案。例如,您可能有一些对象包装了一个字符串并通过 getString() 或 toString() 提供对字符串的访问,但随后在 String 类之上添加了附加功能。

如果您只想将某些对象与其他属性相关联,请使用Map(例如HashMap)。

于 2010-05-18T08:35:03.077 回答
1

你真正想做的是猴子补丁,即改变现有类的行为而不修改它们的代码。

不幸的是,Java 不支持这一点,也不支持诸如mixins之类的替代方法。因此,除非您愿意切换到像 Groovy 这样更动态的语言,否则您将不得不接受像组合这样不太优雅的解决方案。

于 2010-05-18T08:46:29.603 回答