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.