我正在编写(好,完成)Java的“扩展”,这将有助于角色编程 我用javacc将代码翻译成Java代码。我的编译器为每个声明的类添加了一些代码。这是一个更清晰的例子:
MyClass extends String implements ObjectWithRoles { //implements... is added
/*Added by me */
public setRole(...){...}
public ...
/*Ends of stuff added*/
...//myClass stuff
}
它为您声明的每个单一类添加了Implements ..和必要的方法。相当粗糙,不是吗?
如果我在一个类中编写我的方法会更好,并且所有类都扩展了..但是..如果类已经扩展了另一个类(就像示例一样)?
我不想创建一种管理角色的包装器,因为我不希望程序员必须知道的不仅仅是Java,很少有新的保留字及其用法。
我的想法是扩展java.lang.Object ..但你做不到。 (右?)
其他想法?
我是新来的,但我关注这个网站,谢谢你的阅读和你给出的所有答案! (我为英语道歉,我是意大利人)
答案 0 :(得分:6)
如果它只是一个“研究”项目,您想要探索这种扩展如何工作,您可以提供自己的Object
类实现。只需复制现有的对象实现,添加setRole
方法等,并将-Xbootclasspath:.:/usr/lib/jvm/java-6-sun/jre/lib/rt.jar
作为参数提供给java命令。 (在查看真实.
之前,我会在rt.jar
中查找api-classes。)
答案 1 :(得分:3)
Object
- 每个类都扩展它。如果要添加功能,请使用对象组合。即,
YourClass extends Whatever implements ObjectWithRoles {
private RoleHandler roleHandler;
public RoleHandler getRoleHandler() {..} // defined by the interface
}
然后所有方法都放在RoleHandler
答案 2 :(得分:3)
你应该考虑使用组合而不是继承来解决这个问题;通过这种方式,您可以提供所需的功能,而无需在继承时使用“一次性”。
例如,JDK提供了一个类PropertyChangeSupport
,可用于管理PropertyChangeListener
和PropertyChangeEvent
的触发。在您希望编写触发PropertyChangeEvent
的类的情况下,您可以嵌入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);
}
}
答案 3 :(得分:2)
如果您正在谈论为所有对象添加角色,我还会考虑基于注释的解决方案。你可以用@Role(“User”)之类的东西来注释你的类。在另一个类中,您可以提取该角色值并使用它。
我认为它需要一个带有运行时保留的注释,您可以使用反射检查运行时是否存在注释,并使用getAnnotation获取该注释。我觉得这比自动扩展所有课程要清晰得多。
我相信有一些框架完全使用这样的解决方案,因此应该有一些示例代码。
答案 4 :(得分:1)
如果你正在做你正在做的事情,那么继承可能不是正确的习惯用法。您可能需要考虑装饰器模式,从而构造一个类,该类将其他一些具有较少功能的类作为其参数,并为其添加一些附加功能,将现有类委托给已存在的功能。如果实现对于许多装饰器是通用的,您可能需要考虑将该功能放在可以共享的类中,以及可以为所有装饰器委派的功能。根据您的需要,双重调度或反射可能是适当的,以便为各种类别制作类似但不完全相同的装饰器。
此外,正如评论中指出的那样,String被声明为“final”,因此无法扩展。因此,您应该考虑一个委托/装饰对象的解决方案。例如,您可能有一些包装字符串的对象,并通过getString()或toString()提供对字符串的访问,但随后在String类之上添加了附加功能。
答案 5 :(得分:1)
您真正想做的是monkey patching,即在不修改代码的情况下更改现有类的行为。
不幸的是,Java不支持这一点,也不支持mixins之类的替代方案。因此,除非你愿意转换为像Groovy这样更具动态性的语言,否则你将不得不忍受像组合这样不那么优雅的解决方案。