Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mixin overshadowing

Tags:

dart

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.

like image 624
JAre Avatar asked May 05 '14 05:05

JAre


1 Answers

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/

like image 145
lrn Avatar answered Oct 02 '22 02:10

lrn