Вопрос

Let's say i have code like this :

class A{ foo() => "A";}
class B{ foo() => "B";}
class C{ foo() => "C";}

class Mix extends A with B,C {
  foo() => "MIX";
  bar() => super.foo();
}

class MessABC = Object with A,B,C;
class MessBCA = Object with B,C,A;
class MessCAB = Object with C,A,B;

void main() {
  Mix mix = new Mix();
  MessABC mABC = new MessABC();
  MessBCA mBCA = new MessBCA();
  MessCAB mCAB = new MessCAB();

  print("Mix.foo = ${mix.foo()} Mix.bar = ${mix.bar()} \n"
        "mABC.foo = ${mABC.foo()} \n"
        "mBCA.foo = ${mBCA.foo()} \n"
        "mCAB.foo = ${mCAB.foo()} \n");

}

The output

Mix.foo = MIX Mix.bar = C
mABC.foo = C
mBCA.foo = A
mCAB.foo = B

On the mix object I can call both Mix.foo and C.foo with the super (actually i expected A.foo) But can i somehow call A.foo and B.foo ?

Also i am a bit confused by the with semantics. A,B,C Looks like "one rank enumeration" but the order is important. And "Dart Editor" doesn't warn me about the name collision. Perhaps i can enable this warning?

To me it feels like something that makes you confused and error-prone.

Это было полезно?

Решение

Mixin application is processed from left to right.

The superclass of Object with A,B,C is Object with A,B, which again has the superclasses Object with A and then Object.

The overriding rules for mixins are the same as for non-mixin superclasses. Your C.foo in Mix overrides the ones inherited from A and B, so Mix.bar's super.foo() only reaches the C.foo, and there is no way to access A.foo or B.foo.

Overriding is perfectly ok, and doesn't cause any warnings, as long as the methods have compatible signatures.

The most thorough description of mixins is still https://www.dartlang.org/articles/mixins/

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top