Java Inheritance VS C# Inheritance

This topic is very basic, but I felt like writing something on simple subjects that may be misunderstood. It is also a good excuse to go in language specifications and read all the details that most of the people don’t like to read… As I’m working in Java now, I quite like to compare the two languages to see where are the differences and make sure I don’t do any silly mistake.

So, when it comes to inheritance, there is a big difference between Java and C#.

Java Inheritance

In a Java subclass, you can override any method of the superclass. The method that is to be called is always determined at run time. So for example, if you write code like this:

public class Parent {
    public String sayHello() {
        return "Hello from Parent";
    }
}

public class Child extends Parent {
    public String sayHello() {
        return "Hello from Child";
    }
}

If you create a new instance of the Child class, when you call the sayHello() method, it is always the Child one that will be called, no matter what the declaration class is. So, you can teat an instance of Child as an instance of Parent, but the methods called will be the ones from Child (if they are overriden, of course).

Code like this:

Parent o = new Child();
System.out.println(o.sayHello());

will output this:

Hello from Child

C# Inheritance

In C#, things are a bit different. C# language needs to be told which method can be overriden (declared as virtual), and which method overrides (declared as override). So to have the same behavior as Java, C# code has to look like this:

class Parent
{
    public virtual String SayHello()
    {
        return "Hello from Parent";
    }
}

class Child : Parent
{
    public override String SayHello()
    {
        return "Hello from Child";
    }
}

If the virtual and override are omitted (or just the override, actually), then it is the Parent’s method that is executed when the Child object is declared as Parent.

In C# language specification, there is a clear explanation on how is behaves:

In a virtual method invocation, the run-time type of the instance for which that invocation takes place determines the actual method implementation to invoke. In a non-virtual method invocation, the compile-time type of the instance is the determining factor.

Summary

To sum it up, in Java the method called will be determined by the instantiation class, while in C# it will depend on how the class and the calling code is written. C# gives you much more flexibility, but it is more complicated and the capacity for a class to override a method is determined by its parent class. With Java, you loose the ability to call the parent’s method, but is that very useful? On the other hand, C# ensures that if you don’t want a method to be overriden, it won’t be.

Oh and we forgot to talk about the new keyword in C#. I never came across code that used it, but a nice description is given here.

Something I don’t like about C#

In general, I prefer C# over Java. It’s a matter of personal taste, but I find C# more elegant, even if they are very close to each others. But there is something about C# that always bugs me: the way inheritance is declared.

If we look at this code:

public class FooBar : Bar, Foo
{
}

Apart from Visual Studio’s tooltip that helps you, how do you know if Bar is a interface or a class? It can be both, and there is no way of telling.

We obliviously know that Foo is an interface, as only one base class can be defined and it has to be right after the ":" character (see the Class base specification of the C# language).

A class declaration may include a class-base specification, which defines the direct base class of the class and the interfaces implemented by the class.

class-base:
:   class-type

:   interface-type-list

:   class-type   ,   interface-type-list

interface-type-list:
interface-type

interface-type-list   ,   interface-type

But what about Bar? According to the language specification, it can be either an class or an interface, we cannot know just by looking at it. Guidelines for Names that states that interfaces should be prefixed with I, so we could assume that it is a class. However, in this particular example, Foo is an interface for sure but is not prefixed with I, so we cannot assume that Bar is an interface, right?

Now, if we look at Java’s syntax, it is much neater:

public class FooBar extends Bar implements Foo
{
}

Looking at this, there is no doubt that Bar is a class and Foo is an interface (see Java Language Specification parts on Superclasses and Superinterfaces). Even if the developer gave crappy names, we can sort out what is an interface and what is a class.

Now, that said, Visual Studio will always tell you if it is a class or an interface. but if you open the source file with something else than a smart IDE? Notepad for example? I think that the language should speak for itself and not rely on naming conventions. With C#, you can have a doubt, while with Java there is none.

But I still love C# for everything else, I think…