class X {
sealed protected virtual void F() {
Console.WriteLine("X.F");
}
sealed void F1();
protected virtual void F2() {
Console.WriteLine("X.F2");
}
}
In the above code there is compile time error :
X.F()' cannot be sealed because it is not an override
X.F1()' cannot be sealed because it is not an override
Does it mean we can only apply the sealed keyword whey we have to override some methods?
Well, sealed keyword prevents method from being overriden, and that's why it doesn't make sence
with virtual declaration - just remove virtual instead of declaring virtual sealed.
on abstract methods, since abstract methods must be overriden
on non-virtual methods, since these methods just can't be overriden
So the only option is override sealed which means override, but the last time:
public class A {
public virtual void SomeMethod() {;}
public virtual void SomeOtherMethod() {;}
}
public class B: A {
// Do not override this method any more
public override sealed void SomeMethod() {;}
public override void SomeOtherMethod() {;}
}
public class C: B {
// You can't override SomeMethod, since it declared as "sealed" in the base class
// public override void SomeMethod() {;}
// But you can override SomeOtherMethod() if you want
public override void SomeOtherMethod() {;}
}
Related
Don't get me wrong: I do not want to force an overriding method to call the base class like already asked 1000...times before :)
I wondered if there is any way to force the call of the base class implementation of a method inside the base class.
Example:
using System;
public class Program
{
public static void Main()
{
var c = new SubClass();
c.CallInfo();
}
internal class BaseClass {
protected virtual void Info(){
Console.WriteLine("BaseClass");
}
internal virtual void CallInfo() {
this.Info();
}
}
internal class SubClass : BaseClass {
protected override void Info() {
Console.WriteLine("SubClass");
}
internal override void CallInfo() {
base.CallInfo();
}
}
}
Output obviously would be SubClass. Is there any way to force the CallInfo method of BaseClass to call its own Info method so that the output would be BaseClass?
By marking your Info() method as virtual you are specifically asking for this type of inheritance behaviour to occur.
If you want to ensure that a method call in your base class is not overridden, you'll need to use a non-virtual method, e.g.
internal class BaseClass {
protected virtual void Info(){
this.FinalInfo();
}
protected void FinalInfo() {
Console.WriteLine("BaseClass");
}
internal virtual void CallInfo() {
this.FinalInfo();
}
}
No, you can't do that. The purpose of virtual methods is that derived classes can override the implementation and that the implementation is used even when called it from base classes.
If that causes problems then the method you want to run should not be a virtual method.
This would work, while it won't force an implementation by a subclass like virtual it'll allow you to override it.
public class Program
{
public static void Main()
{
var c = new SubClass();
c.CallInfo();
}
internal class BaseClass
{
protected void Info()
{
Console.WriteLine("BaseClass");
}
internal virtual void CallInfo()
{
this.Info();
}
}
internal class SubClass : BaseClass
{
protected new void Info()
{
Console.WriteLine("SubClass");
}
internal override void CallInfo()
{
base.CallInfo();
}
}
}
I have several classes which inherit from a BaseClass which has an abstract method called GetData. In one of them I want to basically inherit from again and provide use a new method called GetArticles which I call from GetData. Here's the code.
public abstract class BaseClass
{
internal abstract void GetData();
}
internal class FirstClass : BaseClass
{
internal override void GetData()
{
// calls GetArticles
}
protected void GetArticles()
{
}
}
internal class SecondClass : FirstClass
{
protected new void GetArticles()
{
}
}
GetArticles is never called in SecondClass. It calls the one in FirstClass, even though my object is of type SecondClass. I can't make GetArticles in FirstClass Abstract because I want to use FirstClass in its own right.
Any suggestions?
Your method has to marked as virtual in FirstClass and overriden using override keyword in SecondClass.
internal class FirstClass : BaseClass
{
internal override void GetData()
{
// calls GetArticles
}
protected virtual void GetArticles()
{
}
}
internal class SecondClass : FirstClass
{
protected override void GetArticles()
{
}
}
new modifier hides the underlying virtual method, which is not what you want. Check Knowing When to Use Override and New Keywords (C# Programming Guide) on MSDN.
Declare GetArticles in your FirstClass as virtual. In the second class remove new and add override
Make GetArticles virtual.
protected virtual void GetArticles()
{
}
Normal Class can not contain abstract method.Whereas abstract class can contain normal method.
If a normal class inherit abstract class and hold any abstract method than must be override due to inheritance in derived class.
I have an abstract class and two classes derivated of this principal class:
abstract class MainClass
{
public void DoSomething() {
if(isEdit())
Edit();
else if(isNew())
New();
else if(isDelete())
Delete();
else if(isSearch())
Search();
else if(isExit())
Exit();
}
public abstract void Edit();
public abstract void New();
public abstract void Delete();
public abstract void Search();
public abstract void Exit();
}
abstract class FirstClass : MainClass
{
public abstract void Edit();
public abstract void New();
public abstract void Delete();
}
abstract class SecondClass : MainClass
{
public abstract void Search();
public abstract void Exit();
}
When you need to extend from FirstClass Edit(), New() and Delete() must be declared, and methods Search() and Exit() can be declared but should not be mandatory. Is there any way to do that?
When you need to extend from FirstClass Edit(), New() and Delete() must be declared, and methods Search() and Exit() can be declared but should not be mandatory.
That is possible:
abstract class FirstClass : MainClass
{
//public abstract void Edit();
//public abstract void New();
//public abstract void Delete();
public override void Search() { }
public override void Exit() { }
}
Edit(), New() and Delete() are already declared as abstract (must override) in the MainClass so FirstClass should leave them alone.
Implement the optional methods as overrides:
abstract class FirstClass : MainClass
{
public override void Search(){}
public override void Exit(){}
}
Since they are implemented in MainClass, you don't need to implement in any inheriting class, but if you want to, you can override them.
Note that you do not need to redeclare Edit, New and Delete again - they are already inherited by FirstClass and will need to be implemented by any non-abstract inheritor of it.
The abstract keyword indicates that a method MUST be implemented by an inheriting class. The virtual keyword indicates that it MAY be implemented.
Mark Save() and Exit() as virtual and provide a default (possibly empty) implementation of them.
You can override the non-mandatory methods that have been declared in MainClass which is the baseclass for FirstClass, and provide default functionality for it:
abstract class FirstClass : MainClass
{
public override void Search(){}
public override void Exit() {}
}
The mandatory methods should not be declared in FirstClass, since they're already declared as abstract in the MainClass. They remain abstract in FirstClass
Override methods which could be optionally declared in child classes (other methods will be inherited from MainClass and stay abstract):
abstract class FirstClass : MainClass
{
public override void Search() { /* default implementation */ }
public override void Exit() { /* default implementation */ }
}
Then
class ThirdClass : FirstClass
{
// Must implement abstract methods
public override void Edit() { }
public override void New() { }
public override void Delete() { }
// Optionally override
public override void Exit() { /* custom implementation */ }
}
My situation is this:
public class InheritedClass : BaseClass
{
public override void SomeMethod()
{
AnotherMethod();
}
public override void AnotherMethod()
{
}
}
public class BaseClass
{
public virtual void SomeMethod()
{ }
public virtual void AnotherMethod()
{ }
}
So which method is called when I call InheritedClassInstance.SomeMethod? Does it call InheritedClassInstance.AnotherMethod, or the BaseClass's AnotherMethod?
It calls InheritedClassInstance.AnotherMethod()
If you wanted it to call the base class AnotherMethod() you would write base.AnotherMethod()
It will call the derived method on the inherited class unless you explicitly call the base method (base.AnotherMethod())
I have this situation that when AbstractMethod method is invoked from ImplementClass I want to enforce that MustBeCalled method in the AbstractClass is invoked. I’ve never come across this situation before. Thank you!
public abstract class AbstractClass
{
public abstract void AbstractMethod();
public void MustBeCalled()
{
//this must be called when AbstractMethod is invoked
}
}
public class ImplementClass : AbstractClass
{
public override void AbstractMethod()
{
//when called, base.MustBeCalled() must be called.
//how can i enforce this?
}
}
An option would be to have the Abstract class do the calling in this manner. Otherwise, there is no way in c# to require an inherited class to implement a method in a certain way.
public abstract class AbstractClass
{
public void PerformThisFunction()
{
MustBeCalled();
AbstractMethod();
}
public void MustBeCalled()
{
//this must be called when AbstractMethod is invoked
}
//could also be public if desired
protected abstract void AbstractMethod();
}
public class ImplementClass : AbstractClass
{
protected override void AbstractMethod()
{
//when called, base.MustBeCalled() must be called.
//how can i enforce this?
}
}
Doing this creates the desired public facing method in the abstract class, giving the abstract class over how and in what order things are called, while still allowing the concrete class to provide needed functionality.
How about
public abstract class AbstractClass
{
public void AbstractMethod()
{
MustBeCalled();
InternalAbstractMethod();
}
protected abstract void InternalAbstractMethod();
public void MustBeCalled()
{
//this must be called when AbstractMethod is invoked
}
}
public class ImplementClass : AbstractClass
{
protected override void InternalAbstractMethod()
{
//when called, base.MustBeCalled() must be called.
//how can i enforce this?
}
}
Why can't you just call the method in the AbstractMethod() of Implement class?
One thing the preceding solutions ignore is that ImplementClass can redefine MethodToBeCalled and not call MustBeCalled -
public abstract class AbstractClass
{
public abstract void AbstractMethod();
private void MustBeCalled()
{
//will be invoked by MethodToBeCalled();
Console.WriteLine("AbstractClass.MustBeCalled");
}
public void MethodToBeCalled()
{
MustBeCalled();
AbstractMethod();
}
}
public class ImplementClass : AbstractClass
{
public override void AbstractMethod()
{
Console.WriteLine("ImplementClass.InternalAbstractMethod");
}
public new void MethodToBeCalled() {
AbstractMethod();
}
}
If only C# allowed non-overridden methods to be sealed - like Java's final keyword!
The only way I can think of to overcome this is to use delegation rather than inheritance, because classes can be defined as sealed. And I'm using a namespace and the "internal" access modifier to prevent providing a new implementation on implementing classes. Also, the method to override must be defined as protected, otherwise users could call it directly.
namespace Something
{
public sealed class OuterClass
{
private AbstractInnerClass inner;
public OuterClass(AbstractInnerClass inner)
{
this.inner = inner;
}
public void MethodToBeCalled()
{
MustBeCalled();
inner.CalledByOuter();
}
public void MustBeCalled()
{
//this must be called when AbstractMethod is invoked
System.Console.WriteLine("OuterClass.MustBeCalled");
}
}
public abstract class AbstractInnerClass
{
internal void CalledByOuter()
{
AbstractMethod();
}
protected abstract void AbstractMethod();
}
}
public class ImplementInnerClass : Something.AbstractInnerClass
{
protected override void AbstractMethod()
{
//when called, base.MustBeCalled() must be called.
//how can i enforce this?
System.Console.WriteLine("ImplementInnerClass.AbstractMethod");
}
public new void CalledByOuter()
{
System.Console.WriteLine("doesn't work");
}
}