virtual void MyMethod()
{
DoOneThing();
}
I want to implement DoAnotherThing() along with DoOneThing() here-
override void MyMethod()
{
//DoOneThing() also.
DoAnotherThing();
}
Is it possible at all?
Here small example
abstract class Foo
{
public virtual void MyMethod()
{
Console.WriteLine("DoOneThing");
}
}
class MegaFoo : Foo
{
public override void MyMethod()
{
base.MyMethod(); // call Foo.MyMethod
Console.WriteLine("DoAnotherThing");
}
}
Related
Currently I have made a design where my BaseClass is the guideline of how my program has to behave. I have made an abstract method DoWork() , the inheritors have to implement this method.
The thing is Class C overrides Setup() so it doesn't need DoWork() anymore. Now I am left with a throw new NotImplementedException();
Question: Is there a way how to improve my design so I won't have those methods with NotImplementedException?
public abstract class BaseClass
{
public virtual void Setup()
{
DoWork();
FinnishWork();
Environment.Exit(0);
}
public abstract void DoWork();
public abstract void FinnishWork();
}
public class A : BaseClass
{
public override void DoWork()
{
Console.WriteLine('A');
}
public override void FinnishWork()
{
Console.WriteLine('FinnishA');
}
}
public class B : BaseClass
{
public override void DoWork()
{
Console.WriteLine('B');
}
public override void FinnishWork()
{
Console.WriteLine('FinnishB');
}
}
public class C : BaseClass
{
public override void Setup()
{
FinnishWork();
Console.WriteLine('C');
}
public override void DoWork()
{
throw new NotImplementedException();
}
public override void FinnishWork()
{
Console.WriteLine('FinnishC');
}
}
As class C doesn't implement DoWork() it shouldn't really inherit from your abstract class.
You can only inherit from one class, but you can implement many interfaces.
In many ways it is simpler to deal with interfaces than abstract classes. Base classes, whether abstract or not really come into their own if they perform some function that you may wish to provide to you inheriting classes. An abstract class with empty methods isn't any better than an interface.
Consider something like:
public interface IDoWork
{
void DoWork();
}
public interface IBase
{
void Setup();
void FinnishWork();
}
public abstract class BaseClass : IBase, IDoWork
{
public virtual void Setup()
{
DoWork();
FinnishWork();
Environment.Exit(0);
}
public abstract void FinnishWork();
public abstract void DoWork();
}
public class A : BaseClass
{
public override void DoWork()
{
Console.WriteLine('A');
}
public override void FinnishWork()
{
Console.WriteLine("FinnishA");
}
}
public class B : BaseClass
{
public override void DoWork()
{
Console.WriteLine('B');
}
public override void FinnishWork()
{
Console.WriteLine("FinnishB");
}
}
public class C : IBase
{
public void Setup()
{
FinnishWork();
Console.WriteLine('C');
}
public void FinnishWork()
{
Console.WriteLine("FinnishC");
}
}
Examples in use:
IBase instanceA = new A();
BaseClass instanceB = new B();
IBase instanceC = new C();
instanceA.Setup();
instanceB.Setup();
instanceC.Setup();
instanceB.DoWork();
You're inheriting in too few steps. You need BaseClassLite and BaseClassHeavy to make this work.
Start with this:
public abstract class BaseClassLite
{
public virtual void Setup()
{
FinnishWork();
Environment.Exit(0);
}
public abstract void FinnishWork();
}
public abstract class BaseClassHeavy : BaseClassLite
{
public override void Setup()
{
DoWork();
base.Setup();
}
public abstract void DoWork();
}
(Or give them more meaningful names.)
Then you implement your classes like this:
public class A : BaseClassHeavy
{
public override void DoWork()
{
Console.WriteLine("A");
}
public override void FinnishWork()
{
Console.WriteLine("FinnishA");
}
}
public class B : BaseClassHeavy
{
public override void DoWork()
{
Console.WriteLine("B");
}
public override void FinnishWork()
{
Console.WriteLine("FinnishB");
}
}
public class C : BaseClassLite
{
public override void Setup()
{
base.Setup();
Console.WriteLine("C");
}
public override void FinnishWork()
{
Console.WriteLine("FinnishC");
}
}
The idea to have a Setup method in BaseClass while having 2 abstracts methods to implement is good (it is even given a name: template method pattern).
However there is one problem lying in how Setup() is declared in BaseClass: you made it virtual which goes against the principle that you want to enforce:
BaseClass is the guideline of how my program has to behave
It is now possible to override it (like you did in C) and break the behavior you want to enforce.
First, remove virtual in BaseClass then override DoWork in C as follow:
public override void DoWork() { }
Having this kind of empty method is a sign of a flawed abstraction (does C really need to inherit from BaseClass ?) but I can't help more if you don't provide more context about the real meaning and names of these classes/methods.
Use a second base class to be inherited from class C:
public abstract class BaseBaseClass
{
public virtual void Setup()
{
FinnishWork();
Environment.Exit(0);
}
...
}
public abstract class BaseClass : BaseBaseClass
{
public abstract void DoWork();
...
}
public class C : BaseBaseClass {...}
I have implemented a method in the base class as following:
class A
{
protected void f1()
{
}
}
class A1 : A
{
public void f2()
{
//Simple Calling
f1();
//Calling using base pointer
base.f1();
}
}
What is the difference between the calling simply and calling using a base pointer ? What are the advantages of either of the ways?
In your example there is no difference. However, consider situation when f1 is virtual and it has another implementation in A1 class:
class A
{
protected virtual void f1()
{
Console.WriteLine("A");
}
}
class A1 : A
{
public void f2()
{
//Simple Calling - prints `A1`
f1();
//Calling using base pointer - prints `A`
base.f1();
}
protected override void f1()
{
Console.WriteLine("A1");
}
}
f1() is different than base.f1() then. The same situation appears when you use new keyword to hide base implementation within derived class:
protected new void f1()
{
Console.WriteLine("A1");
}
The difference between this.f1() (or simply f1()) and base.f1() becomes relevant when you override a virtual method:
class A
{
public virtual void F()
{
Console.WriteLine("A");
}
}
class B : A
{
public override void F()
{
Console.WriteLine("B");
}
void Test()
{
F(); // Prints "B"
this.F(); // Prints "B"
base.F(); // Prints "A"
}
}
It's only useful if you have overloaded/shadowed a method defined in the base class.
class A1 : A
{
public void f2()
{
//Simple Calling
f1();
//Calling using base pointer
base.f1();
}
protected new void f1()
{
// I won't be called
}
}
Also useful when you want to extend the functionality of a base method, but don't want to replicate it:
class A
{
public virtual void F()
{
Console.WriteLine("A");
}
}
class B : A
{
public override void F()
{
base.F();
Console.WriteLine("B");
}
void Test()
{
F(); // Prints "A B"
}
}
In this case, none. But imagine this:
class A
{
public virtual void F()
{
}
}
class B : A
{
public override void F()
{
Console.WriteLine("B");
}
public void F2()
{
F(); /*output: B*/
base.F() /*no output*/
}
}
That's where base starts to come in useful.
The base keyword is used to refer to the base class when chaining constructors or when you want to access a member (method, property, anything) in the base class that has been overridden or hidden in the current class.
For example,
class A {
protected virtual void Foo() {
Console.WriteLine("I'm A");
}
}
class B : A {
protected override void Foo() {
Console.WriteLine("I'm B");
}
public void Bar() {
Foo();
base.Foo();
}
}
With these definitions,
new B().Bar();
would output
I'm B
I'm A
Reference
if you override f1, base its needed to differentiate between them.
class A
{
protected virtual void f1() { }
}
class A1 : A
{
protected override void f1() { }
public void f2()
{
//Simple Calling
f1(); <--- this will call to overrided f1 in this class
//Calling using base pointer
base.f1();
}
}
I have the following code:
class ClassA
{
public virtual void DoSomething()
{
DoSomething(1); // when called from ClassB, it calls DoSomething from ClassA with an infinite recursion
}
public virtual void DoSomething(int someInt)
{
// do something
}
}
class ClassB : ClassA
{
public override void DoSomething()
{
DoSomething(1);
}
public override void DoSomething(int someInt)
{
base.DoSomething(someInt);
// do something
}
}
class Program
{
void someMethod()
{
ClassB instance = new ClassB();
instance.DoSomething(); // stack overflow caused by infinite recursion
}
}
My problem is that when I call ClassB.DoSomething(); and it calls base.DoSomething(someInt); I want the parent class which ClassB is derived to call ClassA's method instead of the overriden one.
Is there a way to do this in a clean way without copying/pasting repeated code?
You can modify the base class like so:
class ClassA
{
public virtual void DoSomething()
{
DoSomethingHelper(1); // when called from ClassB, it calls DoSomething from ClassA with an infinite recursion
}
public virtual void DoSomething(int someInt)
{
DoSomethingHelper(someInt);
}
private void DoSomethingHelper(int someInt)
{
// do something
}
}
By refactoring out the entire method into a private method you provide a means to call the current class' definition of the method while still providing a virtual method for the child class to access.
When you override the virtual method you can't call it without the base keyword, so you cannot cal if from that class. You can try using what Jon B said and use method shadowing instead of overriding.
class ClassA
{
public void DoSomething()
{
DoSomething(1);
}
public void DoSomething(int someInt)
{
Console.WriteLine("a");
}
}
class ClassB : ClassA
{
public new void DoSomething()
{
DoSomething(1);
}
public new void DoSomething(int someInt)
{
base.DoSomething();
}
}
the code below is saying a() cannot override a() as wee.a() is not marked virtual, abstract or override. Is there a a way around this? I need to have code inside the super method, but still want to override it!
public abstract class wee
{
public void a()
{
}
}
public class dee : wee
{
public override void a()
{
}
public void b()
{
}
}
You need to mark wee.a virtual or abstract.
Virtual:
public abstract class wee
{
public virtual void a()
{
}
}
public class dee : wee
{
public override void a()
{
}
public void b()
{
}
}
Abstract:
public abstract class wee
{
public abstract void a();
}
public class dee : wee
{
public override void a()
{
}
public void b()
{
}
}
It will not override the method, there is no way to do this without marking the base as such. If you don't want to modify the base as others have suggested, instead you can hide the base method like this:
public class dee : wee
{
public new void a()
{
}
public void b()
{
}
}
Mark wee.a() as virtual -- it allows you to provide a base implementation but gives the option to override that behavior in subclasses if needed.
// wee
public virtual void a() { // do stuff for base implementation }
// dee
public override void a() { // override behavior implemenation }
I have some classes layed out like this
class A
{
public virtual void Render()
{
}
}
class B : A
{
public override void Render()
{
// Prepare the object for rendering
SpecialRender();
// Do some cleanup
}
protected virtual void SpecialRender()
{
}
}
class C : B
{
protected override void SpecialRender()
{
// Do some cool stuff
}
}
Is it possible to prevent the C class from overriding the Render method, without breaking the following code?
A obj = new C();
obj.Render(); // calls B.Render -> c.SpecialRender
You can seal individual methods to prevent them from being overridable:
public sealed override void Render()
{
// Prepare the object for rendering
SpecialRender();
// Do some cleanup
}
Yes, you can use the sealed keyword in the B class's implementation of Render:
class B : A
{
public sealed override void Render()
{
// Prepare the object for rendering
SpecialRender();
// Do some cleanup
}
protected virtual void SpecialRender()
{
}
}
In B, do
protected override sealed void Render() { ... }
try sealed
class B : A
{
protected sealed override void SpecialRender()
{
// do stuff
}
}
class C : B
protected override void SpecialRender()
{
// not valid
}
}
Of course, I think C can get around it by being new.
An other (better ?) way is probablby using the new keyword to prevent a particular virtual method from being overiden:
class A
{
public virtual void Render()
{
}
}
class B : A
{
public override void Render()
{
// Prepare the object for rendering
SpecialRender();
// Do some cleanup
}
protected virtual void SpecialRender()
{
}
}
class B2 : B
{
public new void Render()
{
}
}
class C : B2
{
protected override void SpecialRender()
{
}
//public override void Render() // compiler error
//{
//}
}
yes. If you mark a method as Sealed then it can not be overriden in a derived class.