【问题标题】:Java: extending Object classJava:扩展对象类
【发布时间】:2010-05-18 08:23:19
【问题描述】:

我正在编写(嗯,完成)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.. 但你不能。 (对吧?)
其他想法?

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

【问题讨论】:

  • 您不能扩展String。这是一个最终类,你不能继承它:java.sun.com/javase/6/docs/api/java/lang/String.html
  • “我的想法是扩展 java.lang.Object.. 但你不能。(对吗?)”嗯,我会说任何没有扩展子类的类默认情况下是 Object .
  • @James P. 我认为 Fabio 的意思是用他自己的更新版本替换 Object。可以做到这一点,为您自己的应用程序创建一个通用基类并从那里扩展所有内容。但是您不想将自动扩展添加到所有内容:)
  • @extraneon:啊,我明白了。是的,不幸的是,一旦形成了类层次结构,您就不能“热交换”父类。一个解决方案是要么形成一个包装器(Fabio 似乎并不想要),另一个是使用组合。

标签: java class object extends


【解决方案1】:

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

【讨论】:

  • 我正在尝试实施您的解决方案:在使用我的方法修改的目录 (.) java/lang/Object.java 中添加 Object 文件。它编译(所以它找到了方法)但是当我尝试执行时我得到 NoSuchMethodError.. 我使用 -Xbootclasspath 和 -classpath 具有相同的结果。 (即使没有它,Javac 也可以工作!)
  • 你应该添加Object.class,不是在.目录下,而是在./java/lang目录下。
  • 愚蠢的英语..我已经完成了,我已经将 java/lang 复制到 .它编译但不执行。对不起..
  • 您不应将java/lang 复制到.。您应该将 object.class 文件放在当前目录中的目录 java/lang 中。再次阅读我的上一条评论 :) 另外,请确保实现以 package java.lang; 开头
  • 我们彼此不了解。我已经复制了目录,目录,而不是内容。在我的 。有一个包含 lang 的 java,其中包含 Object.java 和 Object.class(在我编译时创建)。如果我放入我的文件(我尝试编译的那个)包 java.lang;它说 NoClassDefFoundError。感谢您的耐心等待。
【解决方案2】:

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

比如JDK提供了一个PropertyChangeSupport类,可以用来管理PropertyChangeListeners和PropertyChangeEvents的触发。在您希望编写一个触发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);
  }
}

【讨论】:

    【解决方案3】:
    • 您可以扩展 Object - 每个类都扩展它。
    • 您似乎需要多重继承之类的东西 - Java 中没有这种东西
    • 如果要添加功能,请使用对象组合。即,

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

    然后所有的方法都放在RoleHandler

    【讨论】:

    • 当我说“扩展对象”时,我想创建一个对象的超类,这不是正确的术语,抱歉。无论如何,您的答案很有用,我会检查是否是解决方案。谢谢你。法比奥 F.
    • 等等,我想他正在谈论扩展 Object 类,为所有对象添加功能
    【解决方案4】:

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

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

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

    【讨论】:

      【解决方案5】:

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

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

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

      【讨论】:

      • 1) 没有“顶级包”之类的东西。 2) 名为“Object”的类绝对不会被同一包中的其他类自动扩展。
      • 我 100% 确定它从未在任何符合标准的 JVM 中工作过。
      • @Michael,没关系,我想我可能对 AS3 或其他具有类似 hack 的终极超级类的语言感到困惑。
      【解决方案6】:

      您真正想做的是monkey patching,即在不修改其代码的情况下更改现有类的行为。

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

      【讨论】:

      • 你不一定需要像 Groovy 或 Ruby 这样的动态类型语言来做猴子补丁或混合 - 一些静态语言,例如 Scala,也支持混合,你可以做一些看起来像使用“pimp my library”模式在 Scala 中进行猴子修补。
      猜你喜欢
      • 1970-01-01
      • 2017-11-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-05-07
      • 1970-01-01
      • 2020-10-17
      • 2019-01-22
      相关资源
      最近更新 更多