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:
- 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.
- 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.
- 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#
- Hibernate is missing in Windows XP
- Portrait vs Landscape, CRF Design for a Tablet PC
- Overload the array square bracket operator in C#
- Using TZEdit on Windows SP, SP2, SP3 for Daylight Saving Time (DST)
Quick and dirty “dirty checking” for Windows form, C#
While designing a CRF, little short-cuts can save you lots and lots of time. This time-saver is straight-forward code-wise and should fit right into your C# code without much modification.
During CRF design time, I often have CRFs that have dozens and dozens of input controls (radio buttons, dropdowns, listboxes, textboxes…). I’d like to add OnChange handlers to all of these input controls so that I know when a change has been made. Basically, what it comes down to is I want to know when the form is dirty, but I don’t want to add all the handlers by hand. Fortunately, I didn’t have to and neither do you!
The code below is a recursive function which traverses the Control tree. Whenever it locates a control that can be classified as an input control, it attaches an event handler.
void AddOnChangeHandlerToInputControls(Control ctrl)
{
foreach (Control subctrl in ctrl.Controls)
{
if (subctrl is TextBox)
((TextBox)subctrl).TextChanged +=
new EventHandler(InputControls_OnChange);
else if(subctrl is CheckBox)
((CheckBox)subctrl).CheckedChanged +=
new EventHandler(InputControls_OnChange);
else if(subctrl is RadioButton)
((RadioButton)subctrl).CheckedChanged +=
new EventHandler(InputControls_OnChange);
else if(subctrl is ListBox)
((ListBox)subctrl).SelectedIndexChanged +=
new EventHandler(InputControls_OnChange);
else if(subctrl is ComboBox)
((ComboBox)subctrl).SelectedIndexChanged +=
new EventHandler(InputControls_OnChange);
else
{
if (subctrl.Controls.Count > 0)
this.AddOnChangeHandlerToInputControls(subctrl);
}
}
}
Keep in mind the recursion is necessary, because the Controls property field only lists a control’s immediate children. Those immediate children may have children of their own. That’s right… exactly like a family tree! The use of recursion creates an elegant way to traverse the control’s control tree.
I’ve only picked up on the simplest input controls. It should be straight-forward to extend this for other controls like a DateTimePicker or a CheckedListBox (although the CheckedListBox is a little tricky because it uses a different type of event handler).
void InputControls_OnChange(object sender, ItemCheckEventArgs e)
{
// Do something to indicate the form is dirty like:
// this.formIsDirty = true;
}
All the event handler does is set a flag which indicates the form is dirty. How you process the dirty flag is up to you, and there you have it! Hopefully, you’ve saved a few hours of manually adding event handlers!
To receive updates on new articles, subscribe to CRF Design today!
Similar Posts:
- Portrait vs Landscape, CRF Design for a Tablet PC
- Benefits of form versioning
- Remap keys, map caps lock to control button
- Top 10 differences between Java and C#
- Dealing with mid-study changes (data model)
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() { ... }
}
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!











