6
scala> class A
defined class A

scala> class B {this: A => }
defined class B

scala> new B
<console>:10: error: class B cannot be instantiated because it does not conform
to its self-type B with A
             new B
             ^

ClassBは self 型を classAに設定するため、クラスB(またはそのサブクラス) は class を拡張Aして のインスタンスを作成する必要がありますB。しかし、のサブクラスはB1つのクラスしか拡張できないため(これはクラスBです)、これはまったく可能ですか?

したがって、これは私に質問につながります.クラスの自己型を別のクラスに宣言することは意味がありますか?

4

1 に答える 1

10

2 つのクラスを混在させることはできず、特性のみを混在させることはできないため、この定義が具体的な実装につながることはありません。したがって、短い答えは「いいえ」です。どちらも特性である必要があります。

自己型に関する Stackoverflow に関する質問がいくつかあります。2 つの便利なものは次のとおりです。

2 番目の質問には、 Spiros Tzavellasのブログから次の文章を引用している Ben Lings による適切な回答があります。

結論として、メソッドの実装をトレイト内に移動したい場合、具体的なメソッドの実装をサポートし、トレイトの主な責任とは無関係な抽象メソッドでそれらのトレイトのインターフェースを汚染する危険があります。この問題の解決策は、これらの抽象メソッドを他のトレイトに移動し、自己型注釈と多重継承を使用してトレイトを一緒に構成することです。

たとえば、if A(今はクラスではなくトレイトだと仮定してください!) はロガーです。Bによって混合されたロギング APIを公に公開したくありませんA。したがって、mixin ではなく、self-type を使用します。の実装内でBロギング API を呼び出すことができますが、外部からは見えません。


一方、コンポジションは次の形式で使用できます。

trait B {
    protected def logger: A
}

今の違いは、

  • Bloggerその機能を使用したい場合に参照する必要があります
  • のサブタイプはBlogger
  • B名前空間で競合しAません (たとえば、衝突することなく同じ名前のメソッドを持つことができます)。

自己型は Scala のかなり周辺的な機能であり、多くの場合は必要ありません。また、自己型なしでほぼ​​同じことを達成するために、このようなオプションがあります。

于 2012-06-30T12:50:18.540 に答える