On 12/22/2014 1:11 AM, Derix wrote:

Yep, I rekon the difference was not clear to me. It still isn't
right now, but at least now I know that it exists and I have to
look into it.

Overriding - a subclass reimplements a method from a base class. The method must have the same number and type of parameters. The subclass version essentially replaces the superclass version.

import std.stdio;

class A
{
   public void foo( int x )
   {
      writeln( "I'm an A." );
   }
}

class B : A
{
   // Note that the parameter is an int,
   // just as in the base class
   public override void foo( int x )
   {
      writeln( "I'm a B." );
   }
}

void main()
{
    // prints "I'm an A."
    A one = new A;
    one.foo();

    // prints "I'm a B."
    A two = new B;
    two.foo();

    // ditto
    B three = new B;
    three.foo();
}

Overloading - two or more methods with the same name, but different types and/or number of parameters. They can be implemented in a single class, or in a subclass. Which method is called depends on the parameters passed at the call site.

import std.stdio;

class A
{
    void bar( int x )
    {
       writeln( "One int." );
    }

    void bar( double x )
    {
       writeln( "One double." );
    }
}

class B
{
    void bar( int x, double y )
    {
        writeln( "An int and a double." );
    }

}

void main()
{
    A one = new A;

    // prints "One int."
    one.bar( 10 );

    // prints "One double."
    one.bar( 10.0 );

    // Error -- one is declared as an A.
    // A does not have the int,double version.
    one.bar( 10, 10.0 );

    A two = new B;

    // prints "One int."
    two.bar( 10 );

    // prints "One double."
    two.bar( 10.0 );

    // Error -- the underlying instance of two
    // is a B, but two is declared as an A. A
    // does not have the int,double version
    two.bar( 10, 10.0 );

    B three = new B;

    // prints "One int."
    three.bar( 10 );

    // prints "One double."
    three.bar( 10.0 );

    // prints "An int and a double."
    three.bar( 10, 10.0 );      
}


As to the spell you cast to my cats in your rewriting of the
class, I'm still a bit confused about the ways of the 'downcast'.
I'll try and compile a working hack around your outline, but that
will have to wait another day : late Sunday afternoon, lazy ...

Using the A and B classes from above:

class C : A {}

void main()
{
   A one = new A;

   // This cannot work. One is not a B,
   // and cannot be 'downcast' to be. The line
   // 'new A' means it is and always will be
   // an A.
   B aB = cast( B )one.
   assert( aB is null );

   A two = new B;

   // This works. Since two was assigned a B, the
   // compiler knows that it can be 'downcast' so
   // it lets you do it.
   B anotherB = cast( B )two;
   assert( anotherB !is null );

   A three = new C;

   // Again, this cannot work. This instance was created
   // as a C, not a B, so the cast will result in null.
   B yaB = cast( B )three;
   assert( yaB is null );

   // It *can* be cast to a C
   C aC = cast( C )three;
   assert( aC !is null );


   // And instances of B and C can be 'upcast' to A
   A four = cast( A )anotherB;
   A five = cast( A )aC;
}

downcasting - taking an instance of a class and casting it to a subclass. This can only work if the instance was originally created as a that specific subclass.

upcasting - taking an instance of a class and casting it to its superclass. This will *always* work. Every class you create in D can be cast to Object, since all classes implicitly derive from Object.

Reply via email to