4

首先,我对语言理论几乎一无所知,除了 Java 之外我几乎不知道任何其他语言,但我有一个我认为很酷的想法,但我需要你们告诉我:
a:为什么它很烂
b:语言 x 多年来是如何做到的
c:我的思想多么糟糕
d:以上所有

这个想法将使组合具有与代码重用相同的便利性extends

因此,如果您有这样的课程:

公共接口 A {  
    公共无效方法InA();  
}

然后你有一个这样的课程:

公共类 B {  
    私人作曲A;
    公共 B() {
        // 在构造函数中构造 A
    }
}

然后你就可以这样做了:

B myB = 新 B();
myB.methodInA();

无需在 B 类中添加委托。但是你也可以像继承一样做同样的事情,即:

@Overrides
公共无效方法InA(){
    // B自己的委托方法
}

缺点包括:

  • 方法隐藏在源代码中,使得调用的来源不太明显,但情况也是如此extends
  • 如果组合字段共享相同的方法签名,则需要解决冲突(冲突接口如何解决这个问题?)
  • 如果您想拥有多个相同类型的组合字段,那么委托给哪个字段将会有明显的冲突
  • 可能还有 100 件我没想到的事情

就像我说的,我显然不是语言理论家,而且我还没有花很多时间思考这个问题,这个想法突然出现在我的脑海中,我想知道我错了多少。我只是觉得这会很酷。

4

6 回答 6

1

这听起来很酷,但我认为它会产生一些可怕的语言结构。显然,如果您声明同一类的多个“组合”,则会出现问题,但即使您禁止这样做,如果调用与多个(不同)组合类中的方法匹配,那又如何呢?您必须指定在主类中调用了哪一个,并且需要额外的语法。如果班级中有公共成员,情况会变得更糟。

组合用于防止多重继承问题。允许这样的组合实际上是允许多重继承,至少在解析调用哪个方法方面是这样。由于 Java 的一个关键设计决定是禁止多重继承(有充分的理由),我认为这不太可能被引入 Java。

于 2008-10-31T17:46:19.060 回答
0

我不确定这样做是否有明显的优势。我理解你的意思。目前要在 A 上调用一个方法,您必须使用 myB.getAInstance().methodInA(),但您希望使用 myB.methodInA()。

但是,如果您有多个 A 实例会发生什么?如何解决方法调用?很多时候,组合意味着一对多的关联,所以 B 有很多 A 实例。那会发生什么?

我同意你列出的缺点。它可能只会导致太多的混乱而不是它的价值。

于 2008-10-31T17:34:44.527 回答
0

查看某些语言中所谓的“混合”,以及 Perl 5 Moose OO 系统中的“角色”。

于 2008-10-31T18:12:00.740 回答
0

我认为如果你限制它,使得一个类只能使用这个特性来组成一个类,它会有点有用,并且会避免很多正在讨论的令人头疼的问题。

我个人讨厌具体类的继承。我是 Bloch 的Effective Java中第 14 项的大力支持者,Fav composition over inheritence。我认为这样的事情会使他在该项目中推荐的习语更容易实现。

老实说,如果你真的知道你在做什么,我敢打赌你可以编写一个编译器注释来处理这个问题。因此,假设您有一个实现接口 IBar 的类 Bar,您的类将如下所示:

public class Foo {

  @Delegate(IBar.class)
  private Bar bar;

  // initialize bar via constructor or setter
}

然后在编译期间,可以使 Foo 实现 IBar,并且该接口上尚未由 Foo 实现的任何方法最终都会生成如下所示:

public Baz method1(Qux val) {
  return bar.method1(val);
}

如上所述,您希望限制每个类只有一个字段可以使用此注释。如果多个字段具有此注释,您可能希望引发编译错误。或者,您可以想办法将某种优先模型编码到传递给它的参数中。

现在我已经写出来了,这似乎有点酷。也许下周我会玩弄它。如果我设法弄清楚任何事情,我会更新这个。

于 2008-10-31T18:17:56.750 回答
-1

还需要考虑组合聚合之间的区别。编译器如何知道您的意思是“is-a”还是“has-a”关系?

  • 整个对象图是否有资格进行垃圾收集或只有图的头部?

一些 ORM 映射工具和框架在它们之上/周围提供持久对象之间的关系belongsTohas-many关系,有些还提供级联删除(用于组合)。我不知道有哪一种可以提供您正在寻找的简单语法糖。

实际上,再想一想,Groovy 的 MetaClass 和 MetaProgramming 习惯用法可能会提供一些非常相似的东西,即“自动魔术”委托。

于 2008-10-31T17:48:06.200 回答
-1

C++ 中允许多重继承,我知道这不同,但它遵循相同的思考过程。Java 被设计为不允许多重继承,以便减少混乱,从而减少错误和漏洞利用。

你的建议与java的原则直接冲突。

话虽如此,它会很酷(不一定有用)。我是一名从 C++ 转换而来的 Java 程序员。我喜欢能够犯自己的错误。

于 2008-10-31T17:52:43.307 回答