Please note: This is a conceptual question and not related to production specific code.
Suppose we have Class A with virtual method GetBonus(int value)
Next, we derive a class from this called Class B. In this Class B we override the method GetBonus.
Next, we derive a class from Class B called Class C.
Now class C can also override the GetBonus method of class A.
Question:
Whether Class C overrides the method definition of Class A or of the Class B?
In Class C, How can the overriding of the method of Class A be prevented ?
In Class C, How can the overriding of the method of Class B be prevented ?
I know that there is a SEALED keyword for sealing the virtual overridden methods. But above questions will help me clear my doubts.
Questions 2 and 3 boil down to the same thing basically, and sealed is indeed the answer here.
Perhaps you asked it a bit vague, but you can only prevent overriding of virtual methods in derived classes. Not in the derived class itself. In the end, for both questions 2 and 3, you have only one option:
class A
{
public virtual void GetBonus(int value) { }
}
class B : A
{
public sealed override void GetBonus(int value) { } // We seal this method
}
class C : B
{
public override void GetBonus(int value) // This line is invalid
// because it cannot override the sealed member from class B.
{ }
}
This will prevent method GetBonus from getting overridden in derived classes.
This sample also answers question 1. It gives a compilation error because class C's override of GetBonus is attempting to override the version provided by class B and not the one provided by A. This is true because overriding the one from A would obviously work as it isn't sealed.
according to https://msdn.microsoft.com/en-us/library/ms173149%28v=vs.110%29.aspx (take a look at picture)
when you override a virtual method and then derived that class in another class you inherit overriden implementation
class A
{
public virtual void GetBonus(int value)
{
//if you define this method as seald no one can override this
}
}
class B:A
{
public override void GetBonus(int value)
{
}
}
class C:B
{
public override void GetBonus(int value)
{
//here we override implementation of class B
}
}
}
Related
I was working on a certain problem and found some interesting problem inside.
Let me explain with an example (C# code)
public class A: IA
{
protected abstract void Append(LoggingEvent loggingEvent)
{
//Some definition
}
}
public class B: A
{
protected override void Append(LoggingEvent loggingEvent)
{
//override definition
}
}
public class MyClass: B
{
//Here I want to change the definition of Append method.
}
Class A and B are of a certain library and I don't have any control to change those classes.
Since none of the methods in the hierarchy here are sealed, you can just continue overriding the method yourself:
public class MyClass: B
{
protected override void Append(LoggingEvent loggingEvent)
{
// New logic goes here...
}
}
I have shared the solution below based as per my research, but made few following changes to the code you shared based on my perception, since the code in the question is not valid at few occasions.
Added an empty Interface IA, as Class A is not implementing any public method.
Defined Class A as abstract, as any non-abstract class cannot define a abstract method.
Removed the body for Append method inside Class A, as a abstract method cannot have a body.
public interface IA
{
}
public abstract class A : IA
{
protected abstract void Append();
}
public class B : A
{
protected override void Append()
{
//override definition
}
}
public class MyClass : B
{
//Here I want to change the definition of Append method.
//You can do is hide the method by creating a new method with the same name
public new void Append() { }
}
Answer : 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.
This question already has an answer here:
Can we declare sealed method in a class
(1 answer)
Closed 4 years ago.
Code Snippet 1 (Compilation Error) - A.M2() cannot be sealed because it is not an override
abstract class A
{
public abstract void M1();
public sealed void M2()
{
// Do Something
}
}
Code Snippet 2 (Works Fine)
abstract class A
{
public abstract void M1();
public virtual void M2()
{
}
}
class B : A
{
public sealed override void M1()
{
}
public sealed override void M2()
{
}
}
Question - If I am providing the implementation of a method in the Abstract class itself, why would C# not allow me to mark it Sealed, why would it want me to override in the sub class, there after mark it as sealed. I cannot understand this discrepancy
Sealed keyword can only be put on functions that are overridable.
That function you specified, is not declared as a virtual function, and hence is not overridable. Also it does not make any sense for a function to be declared "virtual" and "sealed" as sealed cancels out being "virtual"
Sealed only can be used hand in hand with the "override" keyword, and stops other classes from overriding the functions themselves.
It has nothing to do with an abstract class. You cannot make a method as sealed in any class until it is an override method in derived class.
If you had intentions for restricting it from override in derived class then you better use private access modifier.
And the reason why you could use sealed in derived class; I've an example of it below
You have three classes A,B,C where B overrides A and C derives from B -> B:A, C:B
abstract class A
{
public abstract void MyMethod();
}
class B : A
{
public sealed override void MyMethod()
{
}
}
class C : B
{
public override void MyMethod()
{
}
}
In above example we could override method of A in B class because it is not sealed. But if you override method of B in class C then it is not allowed due to sealed keyword.
It will restrict further overrides from class B. Thats where we can use sealed
I am working on a small project and I came across that problem.
The project output is a library containing an interface. I would like to implement that interface and seal the functions in it like this if possible:
public interface ITest
{
void SomeMethod();
}
class A : ITest
{
public sealed override SomeMethod()
{
}
}
The idea is to have the interface available to everyone and have some specialized class that implements it. The exception is that I want to make sure that if someone create a specialized class of type A, he/she won't be able to change the method's behavior.
The problem is you can't put the "override" keyword in there since the method isn't declared as "virtual" in the interface. And you can't declare it as "virtual" in the interface since it's not allowed. And you can't remove the "override" keyword since it's needed by "sealed".
Any workaround or brainstorming idea would be welcome, but if someone can come up with a solution that includes an interface, I'd be really happy to learn it!
Thanks!
EDIT: Forget this question! Like Ani said, I forgot that by default method in C# are sealed. Seems like it's always good to go back to the basics once in a while...
I may have completely misunderstood the question, but if your intention is to seal the method in A, you can just do:
class A : ITest
{
public void SomeMethod() { ... }
}
Unlike Java, methods in C# are sealed by default. Subclasses of A won't be able to override the method since it hasn't been marked virtual.
On the other hand, if your intention is to mark the method 'almost sealed' in the interface, so that it forces upon an implementing class to immediately seal it, that isn't possible. It isn't (and shouldn't be) the business of the interface to dictate such details of implementation - an interface is meant to represent a specification.
Use an abstract base class with internal visibility. This base class is not visible outside of the library but allows you to seal the method and the class still implements the interface.
public interface ITest
{
void SomeMethod();
}
internal abstract class SuperA : ITest
{
public abstract void SomeMethod();
}
class A : SuperA
{
public sealed override void SomeMethod()
{
}
}
Your understanding of sealed keyword is incorrect. As a method modifier, sealed is used to prevent a virtual method(defined in the base class) to be override in the next generation of derived classes. For example:
class Base
{
public virtual void M() { }
}
class Derived : Base
{
public sealed override void M() { }
}
class A : Derived
{
public override void M() { } //compile error, M is sealed in Derived
}
Developers can always use new modifier to define a method with the same name in the derived class, that hides the one defined in the base class.
if someone create a specialized class
of type A, he/she won't be able to
change the method's behavior.
If "specialized class" means a class derived from A, the answer is: he can always hide the method in A, but he can't change the method's behavior.
Why not use an abstract class like below.
Haven't tested it but this should work?
public abstract class Test
{
public virtual void SomeMethod() {}
//OR
public abstract void SomeMethod();//MSDN says:
//an abstract method is implicitly virtual
}
class A : Test
{
public sealed override SomeMethod()
{
}
}
Methods in C# are sealed by default.. Here is a sample
class Program
{
static void Main(string[] args)
{
A obj = new A();
obj.SomeMethod();
b ss = new b();
ss.SomeMethod();
Console.ReadLine();
}
}
public interface ITest { void SomeMethod(); }
class A : ITest { public void SomeMethod() {
Console.WriteLine("SomeMethod Called from Class A object");
} }
class b : A
{
//public override void SomeMethod()
//{
// Console.WriteLine("Called from Class B Object");
//}
}
I am a newbie in C#.I am reading about Sealed keyword.I have got about sealed class.I have read a line about Sealed method where we can make Sealed method also.The line was (By declaring method as sealed, we can avoid further overriding of this method.)
I have created a demo but didn't understand that the meaning of above line and sealed method use. Below is my code:-
using System;
namespace ConsoleApplication2
{
class Program:MyClass
{
public override sealed void Test()
{
Console.WriteLine("My class Program");
}
static void Main(string[] args)
{
Program obj = new Program();
obj.Test();
Console.ReadLine();
}
}
class MyClass
{
public virtual void Test()
{
Console.WriteLine("My class Test");
}
}
}
Please tell me why we use Sealed methods and what are the advantages of Sealed methods.
Well, you are testing with only two levels of inheritance, and you are not getting to the point that you're "further overriding" a method. If you make it three, you can see what sealed does:
class Base {
public virtual void Test() { ... }
}
class Subclass1 : Base {
public sealed override void Test() { ... }
}
class Subclass2 : Subclass1 {
public override void Test() { ... } // Does not compile!
// If `Subclass1.Test` was not sealed, it would've compiled correctly.
}
A sealed class is a class which cannot be a base class of another more derived class.
A sealed method in an unsealed class is a method which cannot be overridden in a derived class of this class.
Why do we use sealed methods? What are the advantages of sealed methods?
Well, why do you use virtual methods? To provide a point at which behaviour of a class can be customized. So why do you use sealed methods? To provide a point at which you are guaranteed that no further changes will occur in the behaviour of any derived class with respect to this method.
Points where the behaviour of a class can be customized are useful but dangerous. They are useful because they enable derived classes to change behaviour of the base class. They are dangerous... wait for it... because they enable derived classes to change behaviour of the base class. Virtual methods basically allow third parties to make your classes do crazy things that you never anticipated or tested.
I like writing code that does what I anticipate and what I tested. Sealing a method allows you to continue to allow parts of the class to be overridden while making the sealed methods have guaranteed, testable, stable behaviour that cannot be further customized.
Well, you'd only use "sealed" on a method if you didn't want any derived classes to further override your method. Methods are sealed by default, if they're not declared as virtual and not overriding another virtual method. (In Java, methods are virtual by default - to achieve "default" C# behaviour you have to mark a method as final.)
Personally I like to control inheritance carefully - I prefer whole classes to be sealed where possible. However, in some cases you still want to allow inheritance, but ensure that some methods aren't overridden further. One use might be to effectively template the method, e.g. for diagnostics:
public sealed override void Foo(int x)
{
Log("Foo called with argument: {0}", x);
FooImpl(x);
Log("Foo completed");
}
protected abstract void FooImpl(int x);
Now subclasses can't override Foo directly - they'd have to override FooImpl, so our behaviour will always be executed when other code calls Foo.
The templating could be for other reasons of course - for example to enforce certain aspects of argument validation.
In my experience sealed methods aren't used terribly often, but I'm glad the ability is there. (I just wish classes were sealed by default, but that's another conversation.)
Now if you declare a subclass of Program you won't be able to override the Test method, that's the point.
In most cases you won't need sealed methods but they can prove themselves useful when you're developing a base class for some plugin system that third-party developers have to extend in order to create their own plugin. You can keep some service data like plugin name and whether it is enabled and use sealed methods and properties to do it, so plugin developers won't mess with it. That's one case when sealed members come handy
Sealed Methods
Sealed method is used to define the overriding level of a virtual method.
Sealed keyword is always used with override keyword.
Practical demonstration of sealed method
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace sealed_method
{
class Program
{
public class BaseClass
{
public virtual void Display()
{
Console.WriteLine("Virtual method");
}
}
public class DerivedClass : BaseClass
{
// Now the display method have been sealed and can;t be overridden
public override sealed void Display()
{
Console.WriteLine("Sealed method");
}
}
//public class ThirdClass : DerivedClass
//{
// public override void Display()
// {
// Console.WriteLine("Here we try again to override display method which is not possible and will give error");
// }
//}
static void Main(string[] args)
{
DerivedClass ob1 = new DerivedClass();
ob1.Display();
Console.ReadLine();
}
}
}
First of all, let's start with a definition; sealed is a modifier which if applied to a class make it non-inheritable and if applied to virtual methods or properties makes them non-ovveridable.
public sealed class A { ... }
public class B
{
...
public sealed string Property { get; set; }
public sealed void Method() { ... }
}
An example of its usage is specialized class/method or property in which potential alterations can make them stop working as expected (for example, the Pens class of the System.Drawing namespace).
...
namespace System.Drawing
{
//
// Summary:
// Pens for all the standard colors. This class cannot be inherited.
public sealed class Pens
{
public static Pen Transparent { get; }
public static Pen Orchid { get; }
public static Pen OrangeRed { get; }
...
}
}
Because a sealed class cannot be inherited, it cannot be used as base class and by consequence, an abstract class cannot use the sealed modifier. It's also important to mention that structs are implicitly sealed.
Example
public class BaseClass {
public virtual string ShowMessage()
{
return "Hello world";
}
public virtual int MathematicalOperation(int x, int y)
{
return x + y;
}
}
public class DerivedClass : BaseClass {
public override int MathematicalOperation(int x, int y)
{
// since BaseClass has a method marked as virtual, DerivedClass can override it's behavior
return x - y;
}
public override sealed string ShowMessage()
{
// since BaseClass has a method marked as virtual, DerivedClass can override it's behavior but because it's sealed prevent classes that derive from it to override the method
return "Hello world sealed";
}
}
public class DerivedDerivedClass : DerivedClass
{
public override int MathematicalOperation(int x, int y)
{
// since BaseClass has a method marked as virtual, DerivedClass can override it's behavior
return x * y;
}
public override string ShowMessage() { ... } // compile error
}
public sealed class SealedClass: BaseClass {
public override int MathematicalOperation(int x, int y)
{
// since BaseClass has a method marked as virtual, DerivedClass can override it's behavior
return x * y;
}
public override string ShowMessage()
{
// since BaseClass has a method marked as virtual, DerivedClass can override it's behavior but because it's sealed prevent classes that derive from it to override the method
return "Hello world";
}
}
public class DerivedSealedClass : SealedClass
{
// compile error
}
Microsoft documentation
https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/sealed
C# has it because Java has an identical feature (final methods). I've never seen a legitimate use.
If you don't want to permit extension, the whole class should be marked sealed and not just one method.
public abstract class A
{
public abstract void Process();
}
public abstract class B : A
{
public abstract override void Process();
}
public class C : B
{
public override void Process()
{
Console.WriteLine("abc");
}
}
This code throws an Compilation Error: 'B' does not implement inherited abstract member 'A.Process()'.
Is there any way to do this?
Just leave out the method completely in class B. B inherits it anyway from A, and since B itself is abstract, you do not explicitly need to implement it again.
Works for me in VS2008; no errors, no warnings. BUT, there's no reason to have the 'override' in B. This code is equivalent:
public abstract class A
{
public abstract void Process();
}
public abstract class B : A
{
}
public class C : B
{
public override void Process()
{
Console.WriteLine("abc");
}
}
The place where I've seen this sometimes is overriding a non-abstract virtual method with an abstract method. For example:
public abstract class SomeBaseType
{
/* Override the ToString method inherited from Object with an abstract
* method. Non-abstract types derived from SomeBaseType will have to provide
* their own implementation of ToString() to override Object.ToString().
*/
public abstract override string ToString();
}
public class SomeType : SomeBaseType
{
public override string ToString()
{
return "This type *must* implement an override of ToString()";
}
}
Alon -
This makes no sense. First of all, this does actually compile fine. Secondly, the abstract method you declared in A is inherited (still abstract) into B. Therefore, you have no need to declare Process() in class B.
--
Mark