3

対応するコンパニオン オブジェクト、つまり、トレイトを使用するクラスのコンパニオン オブジェクトを使用するトレイトを定義しようとしています。

たとえば、私は持っています:

:paste

class Parent {
  def callMyCompanion = print(Parent.salute)
}

object Parent {
  def salute = "Hello from Parent companion object"
}

class Child extends Parent {

}

object Child {
  def salute = "Hello from Child companion object"
}

次に、親オブジェクトを作成します。

scala> val p = new Parent()
p: Parent = Parent@1ecf669

scala> p.callMyCompanion
Hello from Parent companion object

しかし、子供と一緒に:

scala> val c = new Child()
c: Child = Child@4fd986

scala> c.callMyCompanion
Hello from Parent companion object

取得したい: Child コンパニオン オブジェクトからこんにちは

どうすれば達成できますか?

-- 明確にするために編集

ご回答ありがとうございます。この場合、callMyCompanion は自分自身を説明するために作成したダミー メソッドです。親メソッドを実装するすべてのクラスでオーバーライドすることなく、親メソッドを再利用しようとしています...

私がこれまでに見つけた解決策は、コンパニオンオブジェクトを使用するインスタンスメソッドを実装することでした...

4

4 に答える 4

6

これまでに見つけた解決策は、クラス内のコンパニオン オブジェクトへの参照を追加して、すべてのインスタンス変数がそのクラスのコンパニオン オブジェクトにアクセスできるようにすることでした。

そうすれば、コンパニオン オブジェクトへの参照を取得するメソッドをオーバーライドするだけで済みます...

そのためには、ParentCompanion トレイトを実装する必要がありました...

ただし、callMyCompanion や、コンパニオン オブジェクトへのアクセスが必要なその他のメソッドをオーバーライドする必要はありません。

リフレクションを介してコンパニオン オブジェクトの参照を取得できれば、すべてがはるかに簡単になります...

コードはこのようなものです

:paste

trait ParentCompanion {
  def salute: String
}

class Parent {
  def callMyCompanion = print(companion.salute)
  def companion: ParentCompanion = Parent
}

object Parent extends ParentCompanion {
  def salute = "Hello from Parent companion object"
}

class Child extends Parent {
  override def companion = Child
}

object Child extends Companion {
  def salute = "Hello from Child companion object"
}
于 2012-06-04T05:41:18.830 に答える
6

すでにコメントに書いたように、ここでは型クラスが役立つかもしれません:

trait Greeter[T] {
  def salute: Unit
}
object Greeter {
  implicit def anyToGreeter[A](x: A) = new {
    def salute(implicit greeter: Greeter[A]) = greeter.salute
  }
}

class Foo
class Bar extends Foo

implicit object FooGreeter extends Greeter[Foo] {
  def salute = println("Hello from FooGreeter.")
}
implicit object BarGreeter extends Greeter[Bar] {
  def salute = println("Hello from BarGreeter.")
}

これにより、次の出力が得られます。

scala> import Greeter._
import Greeter._

scala> new Foo().salute
Hello from FooGreeter.

scala> new Bar().salute
Hello from BarGreeter.
于 2012-06-04T12:02:18.503 に答える
2

この要求は、静的オーバーライドと同じです。Childそのようなことは scala、AFAIK には存在しませんが、メッセージのコンパニオン オブジェクトを呼び出すインスタンス メソッドのオーバーライドを含めることができます。そんなことはしたくないと何かが言っている。

于 2012-06-04T04:13:14.053 に答える
1

コンパニオン オブジェクトがどれであるかを知らずに実際にコンパニオン オブジェクトにアクセスすることの主な問題は、基本的にAnyRefonly を持っていることであり、これはまったく役に立ちません。

別のアプローチは、構造型付けを使用することです。すべての異なるコンパニオン オブジェクトには共通点があると思います (特性saluteでキャプチャしたものなど)。ParentCompanion次に、次のことができます。

class Parent {
  val companion : {
    def salute : String 
  } = Parent
  def foo = println(companion.salute)
}
object Parent {
  val salute = "Parent Companion"
}
class Child extends Parent {
  override val companion = Child
}
object Child {
  val salute = "Child Companion"
}

これにより、すべてのサブクラスは、companion属性をオーバーライドして、対応するコンパニオン オブジェクトを指すようにするParentことができますsalute。次に、次のように、コンパニオンでこのメソッドを呼び出すことができます。

scala> (new Parent).foo
Parent Companion

scala> (new Child).foo
Child Companion
于 2012-06-04T06:59:14.423 に答える