Why does an abstract class need to implement interface methods?

In a comment for a previous post (Top 10 differences between Java and C#), John P. Wood wrote:

As a (primarily) Java developer, I’ve also noticed that C# handles abstract classes that implement interfaces differently. In Java, an abstract class can implement an interface, and not provide implementations of all of the interface’s methods.  It is the responsibility of the first concrete class that has that abstract class as an ancestor to implement all of the methods in the interface.

C# on the other hand seems to require that the abstract class provide implementations for all of the methods on the interface. Even if that implementation is just a method signature.

Like these 3 posts (1 (bottom), 2, 3), I am struggling with why the Microsoft Team chose to do this.  Why ask the developer to write a little stub for the interface method, when the abstract class has no intention of implementing it at all?

I believe it’s a natural artifact of virtual and non-virtual methods in C# (gotcha #2).  In Java, methods are virtual by default (as far as I’m aware, Java doesn’t support non-virtual methods).  However, C# (being derived from C++) does support non-virtual methods.  When an abstract class implements an interface in C#, you are given the chance to describe the interface methods as abstract, virtual or non-virtual.  Here’s exactly what each options means:

  1. abstract - No attempt at an implementation is made in the abstract class.  It’s up to the first concrete class to provide an implementation.  As a side note, defining a method as abstract implicitly defines it as virtual.  If this weren’t the case, you wouldn’t be able to override it in the child class which defeats the purpose of an abstract method.
  2. virtual - An attempt was made in the abstract class to implement this method, but the child class has the option of overriding it and providing its own implementation.
  3. non-virtual - Again, an attempt was made at an implementation in the abstract class.  However, the child class cannot override this method.  If a child class defines a method with the same name, the method will not be associated with the interface implemented in the abstract class.  The method associated with the interface is the non-virtual method defined by the abstract class.

Java can do options 1 and 2, but it lacks option 3.  Java could define the method as final to prevent it from being overriden, but this is slightly different than non-virtual.  The final keyword is more along the lines of seal in C#.  By allowing an option 3, C# provides finer control over how interfaces are inherited.  If C# went the route of Java and permitted abstract classes to put off interface method definitions, these methods would need to be virtual by default.  However, this would be inconsistent with C# methods being non-virtual by default.

In a nutshell, the C# developer is forced in the abstract class to decide exactly which of the three options to assign to the interface method.  Anyway, that’s my best guess…

To receive updates on new articles, subscribe to CRF Design today!

Similar Posts:

Top 10 differences between Java and C#

My latest transition from Java to C# left me scratching my head and scrambling to find the differences.  Don’t get me wrong — they are very similar, but some key syntax and philosophical differences set these two languages apart.  Below are my top 10 differences that I wish someone told me before I pulled out yet more hair.

Gotcha #10 - Give me my standard output!
Gotcha #9 - Namespaces == Freedom
Gotcha #8 - What happened to super?
Gotcha #7 - Chaining constructors to a base constructor
Gotcha #6 - Dagnabit, how do I inherit?
Gotcha #5 - Why don’t constants remain constant?
Gotcha #4 - Where is ArrayList, Vector or Hashtable?
Gotcha #3 - Of Accessors and Mutators (Getters and Setters)
Gotcha #2 - I can’t override!?
And the #1 gotcha…

Gotcha #10 - Give me my standard output!

This may not seem like a big deal, but when I’m first getting my head in a language, I want to be able to debug.  With everything so new and shiny, I don’t want to hear about the debugger yet, I don’t care about the fancy message boxes, just tell me how to get something on standard output!

In C#, the code looks like this:

Console.WriteLine("your string here");

Gotcha #9 - Namespaces ==  Freedom

In Java, the package hierarchical structure mirrored the directory hierarchical structure.  This made sense to a degree, but then why didn’t Sun just auto-derive the package structure?  Anyway, Microsoft has freed us from this constraint.  The C# package structure is defined using namespaces (just like Java), but the namespaces do NOT have to reflect the directory structure.

Gotcha #8 - What happened to super?

Slight renaming of keywords drives me bonkers!  Substitute Java’s super keyword with base.

Gotcha #7 - Chaining constructors to a base constructor

In Java, I often created a set of constructors with differing parameters that all reference a common all-powerful constructor.  In other words, I created a set of overloaded constructors that basically just called a constructor that did the bulk of the work.  This is called constructor chaining and normally leads to easier to maintain code.  In Java, the this(…) statement is used to call the constructor.  In C#, this is done right up in the method signature.

public MyConstructor(int i) : this(i, -1)
{
    ...
}

public MyConstructor(int i, int j)
{
    ...
}

Gotcha #6 - Dagnabit, how do I inherit?

In Java, the keyword extends is used to inherit from a parent class, and the keyword implements is used to inherit an interface.  In C#, the distinction does not exist and it’s all done in the method signature.

public class MyClass : MyParentClass
{
    ...
}

Gotcha #5 - Why don’t constants remain constant?

Well of course they do!  Just not among different languages.  In Java, I normally defined global constants using public static final.  In C#, the static keyword does exist (final does not), but you can define constants like this:

public const MyConstant = 101;

When the constant needs to be initialized at run-time (for example in a constructor), use the readonly keyword instead of const.

Gotcha #4 - Where is ArrayList, Vector or Hashtable?

In Java, these guys were my staples.  Pre-built dynamic arrays and look-up tables decrease development time and makes my life a whole lot easier, but where are they in C#? C# has an ArrayList, but it doesn’t make use of generics. Instead, I like to use:

System.Collections.Generic.List<>

Unfortunately, List<> is not thread-safe (C#’s ArrayList and Java’s Vector are thread-safe). C# also has a Hashtable; the generic version is:

System.Collections.Generic.Dictionary<>

Gotcha #3 - Of Accessors and Mutators (Getters and Setters)

As long as methods exist in classes, accessors and mutators will exist.  However, C# largely replaces them with class properties. Instead of the traditional getSomeInteger() and setSomeInteger(), we use properties!

public class SomeClass
{
    int someInteger = 42;

    public int SomeInteger
    {
        get { return this.someInteger; }
        set { this.someInteger = value; }
    }

    public void Main(string[] args)
    {
        SomeClass c = new SomeClass();
        Console.WriteLine(c.SomeInteger);
        c.SomeInteger = 420;
    }
}

this.someInteger is a class variable, and value is the new integer.

Gotcha #2 - I can’t override!?

At this point, we’ve transcended the syntax differences and we’ve entered into more philosophical choices that the Microsoft team made. In Java, all methods are by default virtual and you can override them. In C#, all methods are non-virtual. To override a method in the parent class, make sure the method of the parent class is defined as virtual using the virtual keyword.

class MyParentClass
{
    public virtual void MyMethod() { ... }
}

In the child class, the method must use the override keyword.

class MyChildClass : MyParentClass
{
    public override void MyMethod() { ... }
}

And the #1 gotcha…

I remember when I first learned Java, and everyone was saying how Java made everything an object. How Java forced you to make classes for everything. This turns out to be partially true. It is necessary to make classes.  However, primitives are not objects. In C#, even what were considered primitives in Java are objects in C#.  Absolutely everything descends from System.Object.  This choice by the C# team allows for greater consistency and for such things as a cleaner implementation of automatic boxing/unboxing.

To receive updates on new articles, subscribe to CRF Design today!

Similar Posts: