bearophile wrote:
Larry Luther:

Ok, I've added -w to compilation commands and I've switched back to pure text.<

Good :-)


What am I missing?<

I have modified a bit your D code like this, to have something with a main() 
that runs:


import std.c.stdio: puts;

class A {
    int x, y;

    void copy(const A a) {
        puts("A copy");
        x = a.x;
        y = a.y;
    }
}

class B : A {
    int z;

    void copy(const B b) {
        puts("B copy");
        super.copy(b);
        z = b.z;
    }
}

void main() {
    A a1 = new A;
    A a2 = new A;

    B b1 = new B;
    B b2 = new B;

    a1.copy(a2); // should execute A.copy
    a1.copy(b1); // should execute A.copy
    b1.copy(b2); // should execute B.copy
    b1.copy(a1); // should execute A.copy
}



I have also translated your the code to Java, because sometimes Java designers are more 
"correct" thant D designers:


class A {
    int x, y;

    void mycopy(A a) {
        System.out.println("A mycopy");
        x = a.x;
        y = a.y;
    }
}

class B extends A {
    int z;

    void mycopy(B b) {
        System.out.println("B mycopy");
        super.mycopy(b);
        z = b.z;
    }

    public static void main(String[] args) {
        A a1 = new A();
        A a2 = new A();

        B b1 = new B();
        B b2 = new B();

        a1.mycopy(a2); // should execute A.mycopy
        a1.mycopy(b1); // should execute A.mycopy
        b1.mycopy(b2); // should execute B.mycopy
        b1.mycopy(a1); // should execute A.mycopy
    }
}


The Java code compiles and runs with no errors, and prints:
A mycopy
A mycopy
B mycopy
A mycopy
A mycopy


But the D version is different. It seems you have found a small difference 
between Java and D that I didn't know about.

If I comment out the last line of the main() in the D code (b1.copy(a1);) and I 
compile the D code with -w it generates the warning I was talking about:

test.d(13): Error: class test.B test.A.copy(const const(A) a) is hidden by B


If I leave that line uncommented then the compilation stops with a different 
error:

test.d(33): Error: function test.B.copy (const const(B) b) is not callable 
using argument types (A)
test.d(33): Error: cannot implicitly convert expression (a1) of type test.A to 
const(B)

It seems in D the copy() of B replaces (hides) the copy() of A, even if no 
override is used. I don't know why D is designed this way, it can even be a 
design/implementation bug. But the presence of that warning suggests me this is 
expected, so it's probably just a difference between Java and D. If no one 
answers to this here then maybe later I will ask about this in the main D group.

Bye,
bearophile

For what it's worth, here is a code that uses 'dup' instead of 'copy'. I know this is not the same thing; but I find this more intuitive:

import std.stdio;
import std.string;

class A
{
    int x, y;

    this(int x, int y)
    {
        this.x = x;
        this.y = y;
    }

    A dup() const
    {
        writeln("A copy");
        return new A(x, y);
    }

    override string toString() const
    {
        return format("A(%s,%s)", x, y);
    }
}

class B : A
{
    int z;

    this(int x, int y, int z)
    {
        super(x, y);
        this.z = z;
    }

    override B dup() const
    {
        writeln("B copy");
        return new B(x, y, z);
    }

    override string toString() const
    {
        return format("B(%s,%s,%s)", x, y, z);
    }
}

void main() {
    A a1 = new A(1, 1);
    A a2 = new A(2, 2);
    B b1 = new B(11, 11, 11);
    B b2 = new B(22, 22, 22);

    a1 = a2.dup;
    assert((a1.x == 2) && (a1.y == 2));

    a1 = b1.dup;
    assert((a1.x == 11) && (a1.y == 11));
    assert(typeid(a1) == typeid(B));      // <-- personality change

    b1 = b2.dup;
    assert((b1.x == 22) && (b1.y == 22) && (b1.z == 22));

    // b1 = a1.dup; // <-- ERROR because not all As are Bs;
    //                           but as we know that a1 is
    //                           actually a B at this point;
    //                           we can down cast:
    assert(cast(B)a1 !is null);
    b1 = (cast(B)a1).dup;
    assert((b1.x == 11) && (b1.y == 11) && (b1.z == 11));

    writeln(a1);
    writeln(a2);
    writeln(b1);
    writeln(b2);
}

Ali

Reply via email to