reimplementing an interface in a derived class

bauss jj_1337 at live.dk
Thu Jan 3 23:32:47 UTC 2019


On Thursday, 3 January 2019 at 22:30:48 UTC, kdevel wrote:
> https://dlang.org/spec/interface.html #11 has this code example:
>
> ```
> interface D
> {
>     int foo();
> }
>
> class A : D
> {
>     int foo() { return 1; }
> }
>
> class B : A, D
> {
>     override int foo() { return 2; }
> }
>
> ...
>
> B b = new B();
> b.foo();            // returns 2
> D d = cast(D) b;
> d.foo();            // returns 2
> A a = cast(A) b;
> D d2 = cast(D) a;
> d2.foo();           // returns 2, even though it is A's D, not 
> B's D
> ```
>
> What is the meaning of the ", D"? It does not seem to make a 
> difference if it is omitted.

When you override foo() from A within B then you're omitting A's 
implementation.

That's because all functions are virtual by default and thus you 
override the implementation.

Basically you have something like (Simplified example)

A:
auto b = new B;
b.v_table["foo"] = &b.super.foo; // If B doesn't override foo. 
(super = A)
b.v_table["foo"] = &b.foo; // If B overrides foo.

When you call foo() it basically looks it up in the v_table.

Even if you cast B to A then the reference to A is still a 
reference to B but you just tell the compiler that the signature 
of your reference is A.

So when you do the following:
> B b = new B();
> b.foo();            // returns 2
> D d = cast(D) b;
> d.foo();            // returns 2
> A a = cast(A) b;
> D d2 = cast(D) a;
> d2.foo();           // returns 2, even though it is A's D, not 
> B's D

It really translates to this:
B b = new B();
b.foo();
D d = use_signature_of_D_on_a_reference_to_B(b);
d.foo(); // Still calling b.foo() because D is not really a type 
and still a reference to B.
A a = use_signature_of_A_on_a_reference_to_B(b);
a.foo(); // Still calling b.foo() because B implement's A's 
signature by having it as a super class. This means that right 
now A is technically B and you just stripped away the signature 
of B to the signature of A.
D d2 = use_signature_of_D_on_a_reference_to_A(a);
d2.foo(); // Calls B.foo() because as stated earlier A is really 
B.

There is no A actually ever existing in your scenario.

Only a reference to B that different signatures are cast from.


More information about the Digitalmars-d-learn mailing list