c# generics and inheritance - c#

I'm getting a compilation error on following code:
public abstract class DbHandler<T>
{
public abstract bool Save(T obj);
...
}
and its implementing class:
public class SpaghettiTableDb : DbHandler<SpaghettiTable>
{
public bool Save(SpaghettiTable obj)
{
return false;
}
...
}
The error is :
'SpaghettiTableDb' does not implement inherited abstract member 'SeatPicker.DbHandler<SeatPicker.SpaghettiTable>.Save(SeatPicker.SpaghettiTable)'
But I think it does, so I'm not sure why I'm receiving this error.
(SpaghettiTable is just a class with some properties, nothing more)
Any help?

You need to use the override keyword. Otherwise you're not implementing the abstract base class and just creating a "new" separate method on the subclass.
public override bool Save(SpaghettiTable obj)
{
return false;
}
Think of abstract methods just like virtual methods that you override. The only difference is that you force subclasses to provide an implementation of that method whereas virtual methods provide their own implementation that subclasses can optionally override with their own implementation.
EDIT: Additionally, if you want to make your life easier in Visual Studio, you can right-click (or ctrl+.) on the inheritance declaration and choose "implement abstract class" (or something like that, I don't have VS with me right now) which will automatically create all the overridden methods for you.
public class SpaghettiTableDb : DbHandler<SpaghettiTable> //right-click on "DbHandler"
Alternatively, in the empty code space within your class, you can start typing "override", then the IntelliSense will list all overridable members from the base class and when you pick one it will automatically write a default implementation for you.
EDIT:
Just to extend on what you have in your code, without the override keyword, you are creating a new method that belongs to your subclass and not overriding the base class. When you call that method but from the context of using the base class, it won't call your subclass implementation since it doesn't override the base method.
Consider the following classes. (I'm using virtual instead of abstract just so it compiles and have it simpler)
public class BaseClass
{
public virtual void Print()
{
Console.WriteLine("base print");
}
public virtual void AnotherPrint()
{
Console.WriteLine("base another print");
}
}
public class SubClass : BaseClass
{
public override void Print()
{
Console.WriteLine("sub print");
}
public void AnotherPrint()
{
Console.WriteLine("sub another print");
}
}
Note that SubClass.AnotherPrint does not override BaseClass.AnotherPrint.
And when you use code like:
SubClass mySub = new SubClass();
mySub.Print(); //sub print
mySub.AnotherPrint(); //sub another print
BaseClass myBase = mySub;
myBase.Print(); //sub print
myBase.AnotherPrint(); //base another print
Note that through the code, mySub and myBase both point to the same object, but one is typed as SubClass and the other as BaseClass. When the runtime calls myBase.Print(), it can easily check the inheritance of the classes and see that SubClass has overridden the Print method and calls the SubClass implementation. However, since SubClass.AnotherPrint wasn't explicitly marked with override, the runtime/compiler considers that to be a completely different method with no link to the BaseClass.AnotherPrint method. Thus the runtime sticks with the base class implementation. When your instance is typed as the SubClass though, the compiler does see that you're pointing to that new method and essentially not to the base implementation.

You need to use the override keyword when implementing abstract methods or overriding virtual methods.
public override bool Save(SpaghettiTable obj)
{
return false;
}

Related

Abstract Class must override an abstract method?

Let's say this abstract class:
abstract public class MyBase {
abstract public int GetValue();
<some concrete methods here>
}
Now I want to inherit that as another abstract class, implementing GetValue() but adding new abstract methods:
abstract public class MyBase2 : MyBase {
abstract public int GetValue2();
public override int GetValue() {
// some code here
return something;
}
}
Why do I have to specify override for MyBase2.GetValue()? Isn't MyBase.GetValue() already marked as abstract and thus will naturally be overridden by anything inheriting from MyBase?
Why do I have to specify override for MyBase2.GetValue()?
This is a paradigm which has been adopted by c++ as well.
The idea is: by explitly having the need to use the keywords override for virtual and abstract, you will ensure that you're not making a typo when doing the override. Because if you would mot see such a typo, the behaviour, escpecially on virtual would change significantly.
Having said that; I still find it strange that the new keyword for added methods is still optional and only emits a warning when omitted.
Since your MyBase2 class is also marked as abstract you should tell the compiler that GetValue() is implemented in this class instead of other class(es) higher in hierarchy (implementing MyBase2)

Why use sealed on a method or property whenever the current class IS a subclass

Why shall we use sealed keyword on a method or property whenever the current class once inherited from a super class? Suppose we made a class and tend to expose one or more of its methods to the object user but not letting it being inherited at all and use sealed to solve the issue. Then, why not? And what's the reason behind sealing just a current-inherited class's methods or properties?
As stated in the MSDN Docments on sealed:
You can also use the sealed modifier on a method or property that
overrides a virtual method or property in a base class. This enables
you to allow classes to derive from your class and prevent them from
overriding specific virtual methods or properties.
In other words, you can stop the overriding from happening further down the class inheritance hierarchy. As a programmer, you are basically saying that this particular method should have common functionality with all subclasses.
Here's a great code example from the same article:
class X
{
protected virtual void F() { Console.WriteLine("X.F"); }
protected virtual void F2() { Console.WriteLine("X.F2"); }
}
class Y : X
{
sealed protected override void F() { Console.WriteLine("Y.F"); }
protected override void F2() { Console.WriteLine("Y.F2"); }
}
class Z : Y
{
// Attempting to override F causes compiler error CS0239.
// protected override void F() { Console.WriteLine("C.F"); }
// Overriding F2 is allowed.
protected override void F2() { Console.WriteLine("Z.F2"); }
}
UPDATE Per Request For Additional Clarification
Here's a less abstract example of a possible application for a sealed method.
abstract class Car
{
public abstract void Make();
}
class Ford : Car
{
// We don't want someone inheriting from this class to change the
// 'Make' functionality - so we seal the method from being further
// overridden down the inheritance hierarchy
sealed public override void Make() { Console.WriteLine("Ford"); }
}
// This way there is no way (besides shadowing) someone inheriting from Ford
// can change the behavior of Make() - so these two types will contain the
// same behavior. Pretty nice, eh!?
class Focus : Ford
{
}
class Escape : Ford
{
}
There are 2 primary reasons for sealing a class or a method.
The first, and the most important one (probably) is that you disallow inheritance on the type or method in question. This can be important in some cases.
The second reason is that the compiler can apply optimizations it otherwise could not have done.
Doing a virtual method lookup is not a very costly affair, but it does incur some overhead. If the compiler knows that:
You're using the most specific class you can in the given situation
The given type or method is sealed
then in some cases it can compile a call to a method into a direct call to the correct method, and not a lookup through the virtual method table of the type. This will remove the overhead of the virtual method lookup in this situation.
As stated in the docs ( http://msdn.microsoft.com/en-us/library/88c54tsw.aspx ) this prevents a method from being virtual. It is useful because override keyword implies virtual. If you want to override a method but stop further overriding you can add sealed to the method definition.
If the class itself is sealed there is no reason to seal a specific method since the class cannot be inherited anyway.
You apply sealed to an overridden method (or property etc.) to disallow classes that derive from your class, overriding that method further.

Overriding Base Class abstract methods and hiding them in derived classes

I have two two types of base class;
public abstract class Base
{
public abstract object Work();
}
public abstract class AuthenticatedBase : Base
{
public abstract object Work(T request);
}
The authenticated class does some extra work to check a login beforehand. Then I have different classes extending from both base classes;
public class A : Base
{
public override object Work()
{
// Work here
}
}
public class B : AuthenticatedBase
{
public override object Work(T request)
{
// Work here
}
}
Basically, when I create a new class B that derives from AuthenticatedBase, Visual Studio says I need to implement Work() from the Base class even though I have an alternate implementation in AuthenticatedBase that I am overriding, admittedly with different parameters. What should I be doing so that I don't have to implement the Work() method from the base class in inherited classes?
Implement the parameterless Work method in your AuthenticatedBase and use the "sealed" keyword to stop it from showing on inheritors of AuthenticatedBase.
You have to implement it, there is no way around it. This is the case where multiple inheritance would come in handy.
You could use composition so that B has a reference to an A. Then B.Work() can call A.Work().
Alternatively, implement B.Work() so that it calls B.Work(T). Or even have Base.Work() be a virtual method with the base implementation from A.

virtual calls on overridden interface implementations

If I have two classes that both implement an interface, but also inherit, do I need to make the function virtual? eg given:
interface IDoSomething
{
void DoSomething();
}
class A : IDoSomething
{
public void DoSomething()
{
//do A
}
}
class B : A
{
public new void DoSomething()
{
//do B
}
}
Would the following code do A or B?
IDoSomething doer = new B();
doer.DoSomething(); //do A or do B?
I'm getting confused because I'm under the impression that all inteface calls are effectively virtual, but obviously I am using the new operator to hide the base definition.
Here is the explanation. Already available at stackoverflow forums.
Quoting Jeffrey Ritcher from CLR via CSharp 3rd Edition here
The CLR requires that interface methods be marked as virtual. If you
do not explicitly mark the method as virtual in your source code, the
compiler marks the method as virtual and sealed; this prevents a
derived class from overriding the interface method. If you explicitly
mark the method as virtual, the compiler marks the method as virtual
(and leaves it unsealed); this allows a derived class to override the
interface method. If an interface method is sealed, a derived class
cannot override the method. However, a derived class can re-inherit
the same interface and can provide its own implementation for the
interface’s methods.
class A : IDoSomething
{
public virtual void DoSomething()
{
//do A
}
}
class B : A
{
public override void DoSomething()
{
//do B
}
}
I prefer leppie's solution. If that's not an option:
class A : IDoSomething
{
void IDoSomething.DoSomething()
{
//do A
}
}
class B : A
{
void IDoSomething.DoSomething()
{
//do B
}
}
But note that this will hide the implementation, so you can't do ((A)doer).DoSomething().
If you can't change class A to either of these solutions, I don't think there's a sure way to override it in all cases. You could both explicitly implement the interface and make a public new method on B. That way if it's statically known as an IDoSomething or as a B it will use B's implementation, but if it's known as an A it will still use A's implementation.
Although C# and .net allow derived classes to re-implement interface methods, it is often better to have the base class use a virtual method to implement the interface, and have the derived class override that method, in any situation where a derived class might wish to augment, rather than entirely replace, the base-class implementation. In some languages like vb.net, this can be done directly regardless of whether a class exposes a public member with the same name and signature as the interface member being implemented. In other languages like C#, a public method which implements an interface can be marked unsealed and virtual (allowing a derived class to override it and have that override call base.Member(params) but an explicit interface implementation cannot. In such languages, the best one can do is something like:
class MyClass : MyInterface
{
void MyInterface.DoSomething(int param)
{
doSomething(param);
}
protected virtual void doSomething(int param)
{
...
}
}
class MyClass2 : MyClass
{
protected override void doSomething(int param)
{
...
base.doSomething(param);
...
}
}
In some cases, having the interface implementation wrap a virtual call can be advantageous, since it allows the base class to ensure that certain things happen before or after the overridden function. For example, a non-virtual interface implementation of Dispose could wrap a virtual Dispose method:
int DisposingFlag; // System.Boolean doesn't work with Interlocked.Exchange
void IDisposable.Dispose()
{
if (Threading.Interlocked.CompareExchange(DisposingFlag, 1, 0) == 0)
{
Dispose(true);
DisposingFlag = 2;
Threading.Thread.MemoryBarrier();
GC.SuppressFinalize(this);
}
}
public bool Disposed { get {return (DisposingFlag != 0);} }
public bool FullyDisposed { get {return (DisposingFlag > 1);} }
This will (unlike Microsoft's default wrapper) ensure that Dispose only gets called once, even if multiple threads try to call it simultaneously. Further, it makes a Disposed property available. Using Microsoft's wrapper, every derived class that wants a Disposed flag would have to define its own; even if the base-class Disposed flag were protected or public, it wouldn't be safe to use because it wouldn't get set until after derived classes had already begun cleanup. Setting DisposingFlag within the wrapper avoids that problem.

Why should an abstract class implement an abstract method of an abstract base class?

In the following example, the class Derived implements the abstract method method from class Main. But I can't think of a reason to fill in the method body in the abstract Derived class' implementation. Surely I should only implement abstract methods within real classes.
So how can I avoid doing it? What else can I do?
abstract class Main
{
public abstract void method();
}
abstract class Derived : Main
{
public override void method()
{
}
}
class RealClass : Derived
{
}
Usually if someone has specified that an abstract class has an abstract method, it's either because that class depends on that method for some of what it does, or it's because it's part of an expected API that it wouldn't make sense for the parent class to implement at this time. In either case, there must be an implementation once you get to a non-abstract implementation of the class.
Note also that if you are implementing an interface, you are required to state how that interface will be implemented, even if you just call the member abstract and pass the responsibility onto the subclass
public interface IPet {string GetNoise(); int CountLegs(); void Walk();}
public abstract class Pet : IPet
{
public string Name {get; set;}
public abstract string GetNoise(); // These must be here
public abstract int CountLegs();
public abstract void Walk();
}
When it comes to implementing the sub-class, you have a few choices depending on the circumstances. If your implementation is itself an abstract class, you shouldn't need to implement the abstract method.
public abstract class Quadruped : Pet
{
public override int CountLegs () { return 4; }
}
If your implementation is non-abstract, but the standard reason for the method in question really doesn't apply in your circumstance, you can do a no-op method (in the case of void methods), or return some dummy value, or even throw a NotImplementedException to indicate that the method should never have been called in the first place.
public class Fish : Pet
{
public override string GetNoise() {return "";} // dummy value: fish don't make noise
public override int CountLegs() {return 0;}
public override void Walk() {} // No-op
// public override void Walk() { throw new NotImplementedException("Fish can't walk"); }
}
Does that answer your question?
If there's no implementation of method in Derived then you can just make Derived abstract as well:
abstract class Derived : Main
{
}
class RealClass : Derived
{
public override void method() { ... }
}
EDIT: To clarify the comments - if there is no meaningful implementation of an abstract method in a subclass, then one does not need to be provided. This will however require that the derived class is itself abstract, and an implementation must be provided somewhere in the chain of descendant classes to some concrete subclass. I am not saying you should leave the implementation of method empty, as it is in the question, but rather you remove the override in Derived and mark the class abstract. This forces RealClass to provide an implementation (or itself be marked abstract).
All non-abstract descendant classes must provide concrete implementations of abstract methods. If you don't provide an implementation, then it's impossible to call that method.
If some concrete classes don't have an obvious proper implementation of a abstract method then your object design is incorrect. Maybe you should have an abstract class with some abstract methods (but not all). That class could have an both an abstract descendant and some concrete descendants.

Categories