1. ホーム
  2. scala

[解決済み] self-typesとtrait subclassの違いは何ですか?

2022-03-25 05:20:33

質問

特徴の自己型 A :

trait B
trait A { this: B => }

とは "です。 A を拡張していない具象クラスには混ぜることができません。 B "です。 .

一方、次のようなこともあります。

trait B
trait A extends B

とは の中に混在している(具象・抽象)クラスは、すべて、そのクラスが存在することになります。 A はB"にも混じることになります。 .

この2つの文は同じ意味ではないのでしょうか?self-typeは単純なコンパイル時のエラーの可能性を作り出すだけの役割しかないように思えます。

何が足りないのでしょうか?

解決方法は?

に主に使用されます。 依存性注入 Cakeパターンに代表されるように。そこには 名品 Cakeパターンを含む、Scalaにおける依存性注入の多くの異なる形式をカバーしています。Cake Pattern and Scala"でググると、プレゼンテーションやビデオを含む多くのリンクがヒットします。とりあえず、以下へのリンクを貼っておきます。 別の質問 .

さて、自己型とtraitの拡張は何が違うのかということですが、それは簡単です。もし、あなたが B extends A であれば B アン A . 自己型を使用する場合。 B が必要です。 アン A . 自己型で作成される特定の要件は2つあります。

  1. もし B が拡張されている場合、あなたは 必須 を混ぜることで A .
  2. 具象クラスが最終的にこれらの特性を拡張/混合する場合、いくつかのクラス/特性は以下を実装する必要があります。 A .

次のような例を考えてみましょう。

scala> trait User { def name: String }
defined trait User

scala> trait Tweeter {
     |   user: User =>
     |   def tweet(msg: String) = println(s"$name: $msg")
     | }
defined trait Tweeter

scala> trait Wrong extends Tweeter {
     |   def noCanDo = name
     | }
<console>:9: error: illegal inheritance;
 self-type Wrong does not conform to Tweeter's selftype Tweeter with User
       trait Wrong extends Tweeter {
                           ^
<console>:10: error: not found: value name
         def noCanDo = name
                       ^

もし Tweeter のサブクラスであった。 User であれば、エラーは発生しません。上のコードでは 必須 a User いつでも Tweeter が使用されますが User には提供されていませんでした。 Wrong というエラーが発生しました。さて、上のコードがまだスコープ内にある状態で、考えてみましょう。

scala> trait DummyUser extends User {
     |   override def name: String = "foo"
     | }
defined trait DummyUser

scala> trait Right extends Tweeter with User {
     |   val canDo = name
     | }
defined trait Right 

scala> trait RightAgain extends Tweeter with DummyUser {
     |   val canDo = name
     | }
defined trait RightAgain

Right を混在させる必要があります。 User が満たされる。しかし、上記の2番目の要件は満たされません。 User を拡張するクラス/ト レイットは、まだ残っています。 Right .

RightAgain の両方の要件を満たしています。A User の実装と User が提供されます。

より実用的な使用例については、この回答の最初にあるリンクを参照してください! でも、これでわかってもらえたかな?