Wednesday 4 April 2007 @ 9:04 pm
Bjarne Stroupstrup, the inventor of the C++ programming language, has an interesting technical FAQ about C++. He has an example in the FAQ that inspired me to try this out in C++, Java and C#. Have a look at the following C++ code. What do you think this prints?
(NOTE: The C++ code looks a bit weird. I had to replace the angle brackets with ‘[’ and ‘]’ because the WordPress editor does not let me enter angle brackets properly, even if I edit the HTML code manually…).
#include [iostream] // NOTE: Use angle brackets here
class Super {
public:
void method(int i) {
std::cout [[ "method(int): " [[ i [[ std::endl; // NOTE: Use angle brackets here
}
};
class Sub : public Super {
public:
void method(double d) {
std::cout [[ "method(double): " [[ d [[ std::endl; // NOTE: Use angle brackets here
}
};
int main(int argc, char* argv[]) {
Sub obj;
// Which method is called for each of these statements, the int or the double version?
obj.method(10);
obj.method(3.2);
return 0;
}
Here is the Java version. What do you think this prints? Do you think Java works the same as C++ or not?
class Super {
public void method(int i) {
System.out.println("method(int): " + i);
}
}
class Sub extends Super {
public void method(double d) {
System.out.println("method(double): " + d);
}
}
public class Main {
public static void main(String[] args) {
Sub obj = new Sub();
// Which method is called for each of these statements, the int or the double version?
obj.method(10);
obj.method(3.2);
}
}
And lastly the C# version. What do you think - does C# work the C++ or the Java way, or is it the same - or different?
namespace Example {
class Super {
public void method(int i) {
System.Console.WriteLine("method(int): " + i);
}
}
class Sub : Super {
public void method(double d) {
System.Console.WriteLine("method(double): " + d);
}
}
class Program {
static void Main(string[] args) {
Sub obj = new Sub();
// Which method is called for each of these statements, the int or the double version?
obj.method(10);
obj.method(3.2);
}
}
}
— By Jesper de Jong PermaLink
April 12th, 2007 at 9:38 am
And the answer is …..
April 18th, 2007 at 10:02 pm
The answer is…:
C++:
method(double): 10
method(double): 3.2
Java:
method(int): 10
method(double): 3.2
C#:
method(double): 10
method(double): 3,2
What is happening here?
In C++ and C#, methods from superclasses are not automatically inherited into the subclass, as in Java. In Java, we are used to the fact that the compiler will look for the best matching method and call that. So, if you call method(…) with an int as a parameter, the method in the superclass will be called, because it matches exactly.
In C++ and C#, the compiler first looks if it can find a method in the subclass that it can use, even if the method doesn’t match exactly (i.e., it will use the method(double) in the subclass even though there is a method(int) in the subclass that matches exactly). Only if it can’t find a matching method, it looks in the superclass.
Note that you can make C++ behave the Java way - you’d have to add a ‘using’ statement to the subclass, like this (this is what was mentioned in Bjarne Stroustrup’s FAQ):
class Sub : public Super {
public:
using Super::method;
void method(double d) {
// … etc.
}
};
I don’t know how to do this in C# or if it is even possible (the C++ syntax doesn’t work).
I like the way Java does this better than how C++ and C# do it - it seems more logical to me to find an exactly matching method first.
April 19th, 2007 at 9:59 am
Hi there,
I am working in a Microsoft C# environment here (hostile territory
) so I showed this post to my colleagues.
We found that this is true for the primitive types like you showed in your example. However, when normal objects (another super and sub object) are used in C# then the best matching method is chosen, just as in Java.
So it seems the difference between C# and Java on this matter only has to do with primitive types. Still it is a bit strange of course…