C# inheritance - c#

Let's say I have the following code:
interface ISomeInterface
{
void DoSomething();
void A();
void B();
}
public abstract class ASomeAbstractImpl : ISomeInterface
{
public abstract void A();
public abstract void B();
public void DoSomething()
{
// code here
}
}
public class SomeImpl : ASomeAbstractImpl
{
public override void A()
{
// code
}
public override void B()
{
// code
}
}
The problem is that i wish to have the ASomeAbstractImpl.DoSomething() method sealed (final) so no other class could implement it.
As the code is now SomeImpl could have a method called DoSomething() and that could be called (it would not override the method with the same name from the abstract class, because that's not marked as virtual), yet I would like to cut off the possibility of implementing such a method in SomeImpl class.
Is this possible?

Methods in C# are sealed by default. There is, however, nothing you can do to prevent method hiding (exposing a method with the same name in the derived class, commonly with new).
Or, for that matter, interface-reimplementation:
static void Main()
{
ISomeInterface si = new EvilClass();
si.DoSomething(); // mwahahah
}
public class EvilClass : ASomeAbstractImpl, ISomeInterface
{
public override void A() {}
public override void B() { }
void ISomeInterface.DoSomething()
{
Console.WriteLine("mwahahah");
}
}

All methods are sealed by default, but there's no way of preventing Member Hiding.
The C# compiler will issue a compiler warning whenever you hide a member, but apart from that, you can't prevent it.

A method which is not marked as virtual is sealed by default. In a derived class you have to mark a "overriding" method with the keyword new, else you'll get a compiler warning.
If the method of the super class is marked as virtual, you can seal it per sealed override.
http://msdn.microsoft.com/en-us/library/aa645769(VS.71).aspx

if SomeImpl class contains DoSemthing method, this means it hides the original one not override.

When dealing with interfaces and abstract classes its more about what you MUST do and not what you cannot do. So you can let the interface user know that these are the methods they must implement and with your abstract classes you can use the virtual keyword to let them know its OK to override a method. However you can't stop them from doing too much. Even if you purposefully don't use the virtual keyword they can still hide it with the new keyword.

Related

How do I call a super class method from sub class object which has overridden?

I've been reading about Polymorphism and I've been through something interesting.
I have created two classes: a super class and a derived class. As you can see derived class inherits from the super class and using its method.
In the derived class I have overridden the method of super class.
So my question is: I want to call the super class method from an object of a derived class
For example:
derivedClass a = new derivedClass()
a.method();
I want a.methood() to execute the superclass method.
Is that possible?
Summing up your question: You have a base class and a derived class. The derived class overrides a virtual method of the base class. Given an instance of the derived class, is it possible to force a call to the base class version of the method, instead of the derived class?
Short answer: From inside the class, yes. From outside the class, no.
Essentially what you wish to do here is a non virtual call to a virtual method. It is legal to do a non-virtual call to a base class method, but only from inside the class:
class B
{
public virtual void M() { Console.WriteLine("B.M"); }
}
class D : B
{
public override void M() { Console.WriteLine("D.M"); }
public void BM() { base.M(); }
}
...
D d = new D();
d.M(); // D.M
d.BM(); // B.M
Now, for advanced players there are sneaky ways to call B.M with an instance of D as the receiver, and I'm not going to tell you what they are. You should not attempt to do so. The CLR may flag such attempts as violations of its "verified code" rules. The rules of virtual overriding are there for your convenience and safety. Do not attempt to do an end-run around those rules.
From outside the derived class it is not possible. From within the derived class it is.
If you have these classes defined:
class A
{
public virtual void Method1() { Console.WriteLine("A"); }
}
class B : A
{
override public void Method1() { Console.WriteLine("B"); }
public void BaseMethod1() { base.Method1(); }
}
You can execute the following:
B b = new B();
b.Method1(); //Outputs "B"
b.BaseMethod1(); //Outputs "A"
((A)b).Method1(); //***Outputs "B" (even though you cast it as A)
If you change overide to new then the output of the last line is "A"
You can try calling base method as per your requirement, if there is some condition, according to which you want to call it, you can use that condition as well.
public class SubClass : SuperClass
{
public bool IsCallBaseClassMethod { get; set; }
public override void Method(){
if (IsCallBaseClassMethod)
{
base.Method();
}
}
}
Set the condition according to your requirement for the object and call the method for same object.
SubClass testObject = new SubClass();
testObject.IsCallBaseClassMethod = true;
testObject.Method();

c# generics and inheritance

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;
}

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.

how can we override method in child class without using "virtual" in parent class

This is a interview question. So is it possible to override a method without virtual specified in parent method?
They probably wanted you to say "Use the new keyword to hide the method." Which technically does not override the method. If you have
class Base
{
public void Bar() { Console.WriteLine("Base"); }
}
class Derived : Base
{
public new void Bar() { Console.WriteLine("Derived"); }
}
And then you wrote
Derived derived = new Derived();
derived.Bar();
((Base)derived).Bar();
You would see different results. So functions that use the base class would get the results for the base method, and functions that use the derived class would get the results for the new method.
Technically you cannot override the method. You can hide it, though, using the new keyword:
class Foo
{
public void Bar() {}
}
class FooChild : Foo
{
new public void Bar() {}
}
The catch is that when you call Bar() from the base class (or if you cast FooChild to Foo), it will execute the base class' code - not the "new" code.
If overriding non-virtual public methods was possible, we would have much more powerful mocking frameworks. No, it's not possible to override non-virtual members, only hide them using new keyword.
The following is not overriding. Also, please never do this for real. It's a "trick" to provide an alternative behaviour, though:
class Base
{
protected Action m_action;
public Base()
{
m_action = () => Console.WriteLine("Base Class");
}
public void NonVirtual()
{
m_action();
}
}
class Derived : Base
{
public Derived()
{
m_action = () => Console.WriteLine("Derived Class");
}
}
class Program
{
static void Main (string[] args)
{
Base baseClass = new Base();
Derived derivedClass = new Derived();
Base derivedAsBase = derivedClass;
Console.WriteLine("Calling Base:");
baseClass.NonVirtual();
Console.WriteLine("Calling Derived:");
derivedClass.NonVirtual();
Console.WriteLine("Calling Derived as Base:");
derivedAsBase.NonVirtual();
Console.ReadKey();
}
}
Result:
Calling Base:
Base Class
Calling Derived:
Derived Class
Calling Derived as Base:
Derived Class
Edit: Although I say it's a trick, it could be tidied up into the Strategy pattern or similar.
The "new" keyword can hide a method defined in a base class when you access that method through a compile-time reference of type T such that typeof(DerivedClass).IsAssignableFrom(typeof(T)). You can not truly override it, however. References that use the base type at compile time will always call the base method regardless of what you do in the definition of the derived class.
If I were asked that question in an interview, that's what I would say. If I were asking it, that's the answer I'd hope for. Anyone who thinks that "new" is the same as "override" and doesn't qualify their answer somehow doesn't understand what "virtual" means or how vtables work (conceptually or mechanically).
No, it would be function hiding.
this way we can do it using new keyword.
using System;
class Example
{
static void Main()
{
Foo f = new Foo();
f.M();
Foo b = new Bar();
b.M();
}
}
class Foo
{
public void M()
{
Console.WriteLine("Foo.M");
}
}
class Bar : Foo
{
public new void M()
{
Console.WriteLine("Bar.M");
}
}

Is it possible to override a non-virtual method?

Is there any way to override a non-virtual method? or something that gives similar results (other than creating a new method to call the desired method)?
I would like to override a method from Microsoft.Xna.Framework.Graphics.GraphicsDevice with unit testing in mind.
No, you cannot override a non-virtual method. The closest thing you can do is hide the method by creating a new method with the same name but this is not advisable as it breaks good design principles.
But even hiding a method won't give you execution time polymorphic dispatch of method calls like a true virtual method call would. Consider this example:
using System;
class Example
{
static void Main()
{
Foo f = new Foo();
f.M();
Foo b = new Bar();
b.M();
}
}
class Foo
{
public void M()
{
Console.WriteLine("Foo.M");
}
}
class Bar : Foo
{
public new void M()
{
Console.WriteLine("Bar.M");
}
}
In this example both calls to the M method print Foo.M. As you can see this approach does allow you to have a new implementation for a method as long as the reference to that object is of the correct derived type but hiding a base method does break polymorphism.
I would recommend that you do not hide base methods in this manner.
I tend to side with those who favor C#'s default behavior that methods are non-virtual by default (as opposed to Java). I would go even further and say that classes should also be sealed by default. Inheritance is hard to design for properly and the fact that there is a method that is not marked to be virtual indicates that the author of that method never intended for the method to be overridden.
Edit: "execution time polymorphic dispatch":
What I mean by this is the default behavior that happens at execution time when you call virtual methods. Let's say for example that in my previous code example, rather than defining a non-virtual method, I did in fact define a virtual method and a true overridden method as well.
If I were to call b.Foo in that case, the CLR would correctly determine the type of object that the b reference points to as Bar and would dispatch the call to M appropriately.
No you can't.
You can only override a virtual method - see the MSDN here:
In C#, derived classes can contain methods with the same name as base class methods.
The base class method must be defined virtual.
You can't override non-virtual method of any class in C# (without hacking CLR), but you can override any method of interface the class implements.
Consider we have non-sealed
class GraphicsDevice: IGraphicsDevice {
public void DoWork() {
Console.WriteLine("GraphicsDevice.DoWork()");
}
}
// with its interface
interface IGraphicsDevice {
void DoWork();
}
// You can't just override DoWork in a child class,
// but if you replace usage of GraphicsDevice to IGraphicsDevice,
// then you can override this method (and, actually, the whole interface).
class MyDevice: GraphicsDevice, IGraphicsDevice {
public new void DoWork() {
Console.WriteLine("MyDevice.DoWork()");
base.DoWork();
}
}
And here's demo
class Program {
static void Main(string[] args) {
IGraphicsDevice real = new GraphicsDevice();
var myObj = new MyDevice();
// demo that interface override works
GraphicsDevice myCastedToBase = myObj;
IGraphicsDevice my = myCastedToBase;
// obvious
Console.WriteLine("Using real GraphicsDevice:");
real.DoWork();
// override
Console.WriteLine("Using overriden GraphicsDevice:");
my.DoWork();
}
}
If the base class isn't sealed then you can inherit from it and write a new method that hides the base one (use the "new" keyword in the method declaration). Otherwise no, you cannot override it because it was never the original authors intent for it to be overridden, hence why it isn't virtual.
I think you're getting overloading and overriding confused, overloading means you have two or more methods with the same name but different sets of parameters while overriding means you have a different implementation for a method in a derived class (thereby replacing or modifying the behaviour in it's base class).
If a method is virtual, you can override it using the override keyword in the derrived class. However, non-virtual methods can only hide the base implementation by using the new keyword in place of the override keyword. The non-virtual route is useless if the caller accesses the method via a variable typed as the base type as the compiler would use a static dispatch to the base method (meaning the code in your derrived class would never be called).
There is never anything preventing you from adding an overload to an existing class, but only code that knows about your class would be able to access it.
The answer to this question is not entirely No. It depends on how you structure your inheritance and access the instances of your classes. If your design meets the following, you would be able to override non-virtual method from base class with the new modifier:
The method is declared in an interface that your classes inherit from
You are accessing the class instances using the interface
Take example of the following:
interface ITest { void Test(); }
class A : ITest { public void Test(){Console.WriteLine("A");} }
class B : A { public new void Test(){Console.WriteLine("B");} }
ITest x = new B();
x.Test(); // output "A"
calling x.Test() will output "A" to the console. However if you re-declare the interface in the definition of class B, x.Test() will output B instead.
interface ITest { void Test(); }
class A : ITest { public void Test(){Console.WriteLine("A");} }
class B : A, ITest { public new void Test(){Console.WriteLine("B");} }
ITest x = new B();
x.Test(); // output "B"
In the case you are inheriting from a non-derived class, you could simply create an abstract super class and inherit from it downstream instead.
Is there any way to override a non-virtual method? or something that gives similar results (other than creating a new method to call the desired method)?
You cannot override a non-virtual method. However you can use the new modifier keyword to get similar results:
class Class0
{
public int Test()
{
return 0;
}
}
class Class1 : Class0
{
public new int Test()
{
return 1;
}
}
. . .
// result of 1
Console.WriteLine(new Class1().Test());
You will also want to make sure that the access modifier is also the same, otherwise you will not get inheritance down the line. If another class inherits from Class1 the new keyword in Class1 will not affect objects inheriting from it, unless the access modifier is the same.
If the access modifier is not the same:
class Class0
{
protected int Test()
{
return 0;
}
}
class Class1 : Class0
{
// different access modifier
new int Test()
{
return 1;
}
}
class Class2 : Class1
{
public int Result()
{
return Test();
}
}
. . .
// result of 0
Console.WriteLine(new Class2().Result());
...versus if the access modifier is the same:
class Class0
{
protected int Test()
{
return 0;
}
}
class Class1 : Class0
{
// same access modifier
protected new int Test()
{
return 1;
}
}
class Class2 : Class1
{
public int Result()
{
return Test();
}
}
. . .
// result of 1
Console.WriteLine(new Class2().Result());
As pointed out in a previous answer, this is not a good design principle.
There is a way of achieving this using abstract class and abstract method.
Consider
Class Base
{
void MethodToBeTested()
{
...
}
void Method1()
{
}
void Method2()
{
}
...
}
Now, if you wish to have different versions of method MethodToBeTested(), then
change Class Base to an abstract class and method MethodToBeTested() as an abstract method
abstract Class Base
{
abstract void MethodToBeTested();
void Method1()
{
}
void Method2()
{
}
...
}
With abstract void MethodToBeTested() comes an issue; the implementation is gone.
Hence create a class DefaultBaseImplementation : Base to have the default implementation.
And create another class UnitTestImplementation : Base to have unit test implementation.
With these 2 new classes, the base class functionality can be overridden.
Class DefaultBaseImplementation : Base
{
override void MethodToBeTested()
{
//Base (default) implementation goes here
}
}
Class UnitTestImplementation : Base
{
override void MethodToBeTested()
{
//Unit test implementation goes here
}
}
Now you have 2 classes implementing (overriding) MethodToBeTested().
You can instantiate the (derived) class as required (i.e. either with base implementation or with unit test implementation).

Categories