Thread overview
Overloaded function disappears on polymorphism
Jan 24, 2015
tcak
Jan 24, 2015
ketmar
Jan 24, 2015
Tobias Pankrath
Jan 24, 2015
Ali Çehreli
January 24, 2015
main.d
===================================================
class Car{
	public void makeBeep( char c ){}
	public void makeBeep( string s ){}
}

class Tesla: Car{
	override public void makeBeep( char c ){
		writeln("C = ", c);
	}
}

void main(){
	auto t = new Tesla();

	t.makeBeep("Model S");
}
===================================================

Error: function main.Tesla.makeBeep (char c) is not callable using argument types (string)

For Tesla, I expected that makeBeep( string s ) would still be defined. Because I have overridden on makeBeep( char c ). Isn't that correct?
January 24, 2015
On Sat, 24 Jan 2015 18:55:58 +0000, tcak wrote:

> main.d ===================================================
> class Car{
> 	public void makeBeep( char c ){}
> 	public void makeBeep( string s ){}
> }
> 
> class Tesla: Car{
> 	override public void makeBeep( char c ){
> 		writeln("C = ", c);
> 	}
> }
> 
> void main(){
> 	auto t = new Tesla();
> 
> 	t.makeBeep("Model S");
> }
> ===================================================
> 
> Error: function main.Tesla.makeBeep (char c) is not callable using
> argument types (string)
> 
> For Tesla, I expected that makeBeep( string s ) would still be defined.
> Because I have overridden on makeBeep( char c ). Isn't that correct?

nope. overriding overloaded function cancels all overloads. it's by spec.

January 24, 2015
> For Tesla, I expected that makeBeep( string s ) would still be defined. Because I have overridden on makeBeep( char c ). Isn't that correct?

alias makeBeep = Car.makeBeep; pulls the base classes overloads into your subclass.
January 24, 2015
On 01/24/2015 10:55 AM, tcak wrote:

> main.d
> ===================================================
> class Car{
>      public void makeBeep( char c ){}
>      public void makeBeep( string s ){}
> }
>
> class Tesla: Car{
>      override public void makeBeep( char c ){
>          writeln("C = ", c);
>      }
> }
>
> void main(){
>      auto t = new Tesla();
>
>      t.makeBeep("Model S");
> }
> ===================================================
>
> Error: function main.Tesla.makeBeep (char c) is not callable using
> argument types (string)
>
> For Tesla, I expected that makeBeep( string s ) would still be defined.
> Because I have overridden on makeBeep( char c ). Isn't that correct?

This is called "name hiding" and works the same at least in C++. The purpose is to avoiding function hijacking. Imagine the following scenario where a 'short' argument is dispatched to a function taking 'int':

class Base
{
    void foo(int)
    {}
}

class Derived : Base
{
    override void foo(int)
    {}
}

void main()
{
    // Compiles: 'short' is converted to 'int':
    (new Derived).foo(short.init);
}

Without name hiding, the following addition to Base (which, presumably the author of Derived has no control over) would cause the call to bypass Derived.foo(short) and go to Base.foo(short):

class Base
{
    void foo(int)
    {}

    void foo(short)    // <-- New function
    {}
}

class Derived : Base
{
    override void foo(int)
    {}
}

void main()
{
    /* Compilation ERROR:
     *
     * Deprecation: class deneme.Derived use of deneme.Base.foo(short
     * _param_0) hidden by Derived is deprecated; use 'alias foo = Base.foo;'
     * to introduce base class overload set
     */
    (new Derived).foo(short.init);
}

Ali