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.
Related
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");
}
}
I've found in the Troelsen's book, that operator sealed can be used on the members of the class to protect virtual methods from the override.
But if I don't want to override a virtual methods, what sense to make it virtual?
You might have a situation like this:
public class A
{
public virtual void MyMethod()
{
//...
}
}
public class B : A
{
public override void MyMethod()
{
//...
}
}
public class C : B
{
public override void MyMethod()
{
//...
}
}
But what if you want for the inheriting class C NOT to be able to override B's MyMethod, while still allowing B to override A's? Then you can do:
public class B : A
{
public sealed override void MyMethod()
{
//...
}
}
With this change made, you can no longer override the method in C.
In this context, consider the following example:
public class A
{
public virtual void SomeMethod() { }
}
public class B : A
{
public sealed override void SomeMethod() { }
}
public class C : B
{
public override void SomeMethod() { }
}
In this example, without the use of the sealed keyword on SomeMethod in class B, class C would be able to override it because it's original declaration was as virtual. The sealed keyword in this context generates a compiler error. See the MSDN for more information.
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();
}
}
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 need to call automatically base class method when calling overriden one (like constructors call base). For example:
class A
{
public void Fun()
{
Console.Write("Class A!");
}
}
class B : A
{
public void Fun()
{
Console.Write("Class B!");
}
}
I want to see on the screen
Class A! Class B!
when executing next code:
B b = new B();
b.Fun();
Could anyone tell me please what need to change in example code or how better to write to get required result? Thanks.
If you don't want to call it explicitly and therefore ensure A.Fun() is called in the derived class, you could use something called the template method pattern:
class A
{
public void Fun()
{
Console.Write("Class A!");
FunProtected();
}
protected virtual void FunProtected()
{
}
}
class B : A
{
protected override void FunProtected()
{
Console.Write("Class B!");
}
}
This would give you:
new A().Fun() -> "Class A!"
new B().Fun() -> "Class A! Class B!"
If you want such behavior you will need to change platform/language. .NET doesn't automatically call the base method. You need to call it explicitly. Also your method needs to be virtual or you will be hiding it in the derived class:
class A
{
public virtual void Fun()
{
Console.Write("Class A!");
}
}
class B : A
{
public override void Fun()
{
// call the base method which will print Class A!
base.Fun();
Console.Write("Class B!");
}
}
Now when you do this:
B b = new B();
b.Fun();
you will get the required result.
Can still be so:
interface IFun
{
void Fun();
}
abstract class A : IFun
{
void IFun.Fun()
{
Console.Write("Class A!");
Fun();
}
protected abstract void Fun();
}
class B : A
{
protected override void Fun()
{
Console.Write("Class B!");
}
}
IFun b = new B();
b.Fun();
This works if object reference is IFun.
Just for reference, you could use a wrapper pattern that puts an A inside a B. Here is a crude example!
interface IFunClass {
void Fun();
}
class A : IFunClass {
public void IFunClass.Fun() {
Console.Write("Class A!");
}
}
class B : IFunClass {
public B(IFunClass f) {
this.m_SomethingFun = f;
}
public void IFunClass.Fun() {
this.m_SomethingFun.Fun();
Console.Write("Class B!");
}
private IFunClass m_SomethingFun;
}
A a = new A();
B b = new B(a);
b.Fun() // will call a.Fun() first inside b.Fun()