D Class Inheritance Issue:
The non-working example below is some modified code found on a D.Bugs forum posted as a problem with inherting functions
(private, protected, or public...it really didn't matter) from the Base / SuperClass within the newly Derived Class. As it turns
out, when the function-name (return-type, parameter-types, number of parameters didn't matter) is shared between the Base Class
and the SubClass... the Base Class functions of that name become hidden / unreachable to the SubClass.
// class_inhert_prm.d
private import std.stdio;
class A
{
void test() { writefln( "A.test() Called."); }
void test( in int iVal ) { writefln( "A.test( in int iVal=\"%s\" ) Called.", iVal ); }
void test2( in int iVal ) { writefln( "A.test2( in int iVal=\"%s\" ) Called.", iVal ); }
}
class B : A
{
void test() { writefln( "B.test() Called."); }
}
int main( in char[][] args )
{
B ob = new B();
ob.test( 6 ); // <--A.test( in int iVal ) should be called here.
ob.test2( 7 ); // if above error is commented out, A.test2( in int iVal ) works.
ob.test();
return 0;
} // end int main( in char[][] )
C:\dmd\MKOD_ex>..\bin\dmd class_inhert_prm.d
class_inhert_prm.d(20): function class_inhert_prm.B.test () does not match argument types (int)
class_inhert_prm.d(20): Error: expected 0 arguments, not 1
C:\dmd\MKOD_ex>
One of the best ways around this issue, was to add an "alias" in the SubClass that will pull in all the
shared function-names into the same namespace for function overloading to work correctly.
Below look for alias A.test() test;
// class_inhert2.d - last tested with D v1.0
/+
' When Inherting Base Class functions that have the function same name
' has the Base Class function causes them to remain hidden / uncallable.
+/
private import std.stdio;
class A
{
void test() { writefln( "A.test() Called."); }
void test( in int iVal ) { writefln( "A.test( in int iVal=\"%s\" ) Called.", iVal ); }
void test2( in int iVal ) { writefln( "A.test2( in int iVal=\"%s\" ) Called.", iVal ); }
}
class B : A
{
/+
' An alias brings in all the same function-name
' (note: that it doesn't matter about the function's
' return-type or types of paramters nor the number of
' parameters) into Class B's namespace.
+/
alias A.test test;
void test() { writefln( "B.test() Called."); }
// Could call B.test() 1st then call A.test() in this case.
//void test() { writefln( "B.test() Called."); super.test(); }
}
int main( in char[][] args )
{
B ob = new B();
ob.test( 6 );
ob.test2( 7 );
ob.test();
return 0;
} // end int main( in char[][] )
C:\dmd\MKOD_ex>dmd class_inhert2.d
C:\dmd\bin\..\..\dm\bin\link.exe class_inhert2,,,user32+kernel32/noi;
C:\dmd\MKOD_ex>class_inhert2
A.test( in int iVal="6" ) Called.
A.test2( in int iVal="7" ) Called.
B.test() Called.
C:\dmd\MKOD_ex>
Another way to pull in the SuperClass shared function-names into the SubClass' namespace was to use
an "interface" to map them in. This of course will force the SuperClass to have
all the shared versions of the function-names that will be used plus with their correct return-types,
parameters, and number of parameters. But there may be cases where this type of side-effect may allow
some different type of functionally...it's always good to have options. You decide.
// class_inhert3.d
/+
' When Inherting Base Class functions that have the function same name
' has the Base Class function causes them to remain hidden / uncallable.
+/
private import std.stdio;
/+
' Using an interface that has all the [return] function( [parameter(s)] )
' that'll be shared between the SuperClass (Base) and the SubClass(es) which
' will make up the Derived Class' namespace, will make function overloading
' to work correctly.
+/
interface I
{
void test();
void test( in int );
}
class A : I
{
void test() { writefln( "A.test() Called."); }
void test( in int iVal ) { writefln( "A.test( in int iVal=\"%s\" ) Called.", iVal ); }
void test2( in int iVal ) { writefln( "A.test2( in int iVal=\"%s\" ) Called.", iVal ); }
}
class B : A
{
void test() { writefln( "B.test() Called."); }
}
int main( in char[][] args )
{
B ob = new B();
ob.test2( 7 );
// Interfaces can be inherited and functions overridden
I oib = cast(I) ob;
oib.test( 6 );
oib.test();
return 0;
} // end int main( in char[][] )
C:\dmd\MKOD_ex>..\bin\dmd class_inhert3.d
C:\dmd\bin\..\..\dm\bin\link.exe class_inhert3,,,user32+kernel32/noi;
C:\dmd\MKOD_ex>class_inhert3
A.test2( in int iVal="7" ) Called.
A.test( in int iVal="6" ) Called.
B.test() Called.
C:\dmd\MKOD_ex>