Whenever i override a method of a base class, other than my implementation of this method, i seem to have 3 choices.
1) Call base.Method(), and then provide my implementation.
2) Provide my implementation and then call base.Method()
3) Just provide my implementation.
Recently while using a library i have realized few bugs that were introduced because of not implementing the method as expected by the library. I am not sure if that is bad on part of library, or something wrong in my understanding.
I will take one example.
public class ViewManager {
public virtual void Customize(){
PrepareBaseView();
}
}
public class PostViewManager {
public override void Customize(){
base.Customize();
PreparePostView();
}
}
public class PreViewManager {
public override void Customize(){
PreparePreView();
base.Customize();
}
}
public class CustomViewManager {
public override void Customize(){
PrepareCustomView();
}
}
My question here is that how could a child class know (without taking a look at base class implementation) which order (or option) is being expected by the parent class?
Is there a way in which parent class could enforce one of the three alternates to all the deriving classes?
how could a child class know (without taking a look at base class implementation) which order (or option) is being expected by the parent class?
There is no way to "know" this when you are subclassing and overriding a method. Proper documentation is really the only option here.
Is there a way in which parent class could enforce one of the three alternates to all the deriving classes?
The only option here is to avoid the issue. Instead of allowing the subclass to override the method, it can be declared non-virtual, and call a virtual method in the appropriate place. For example, if you want to enforce that subclasses "call your version first", you could do:
public class BaseClass {
public void Method() // Non-virtual
{
// Do required work
// Call virtual method now...
this.OnMethod();
}
protected virtual void OnMethod()
{ // Do nothing
}
}
The subclasses can then "override" OnMethod, and provide functionality that happens after "method"'s work.
The reason this is required is that virtual methods are designed to allow a subclass to completely replace the implementation of the parent class. This is done on purpose. If you want to prevent this, it's better to make the method non-virtual.
This is why I feel virtual methods are dangerous when you ship them in a library. The truth is you never really know without looking at the base class, sometimes you have to fire up reflektor, read documentation or approach it with trial and error.
When writing code myself I've always tired to follow the rule that says:
Derived classes that override the protected virtual method are not required to call the base class implementation. The base class must continue to work correctly even if its implementation is not called.
This is taken from http://msdn.microsoft.com/en-us/library/ms229011.aspx, however this is for Event design though I believe I read this in the Framework Design Guidelines book (http://www.amazon.com/Framework-Design-Guidelines-Conventions-Libraries/dp/0321246756).
However, this is obviously not true, ASP.NET web forms for example require a base call on Page_Load.
So, long and short, it varies and unfortunately there is no instant way of knowing. If I'm in doubt I will omit the call initially.
The short answer is no. You can't enforce in what order the child calls the base method, or if it calls it at all.
Technically this information should be included in the base object's documentation. If you absolutely must have some code run before or after the child class' code than you can do the following:
1) Create a non-virtual function in the base class. Let's call it MyFunction
2) Create a protected virtual function in the base class. Let's call it _MyFunction
3) Have deriving classes extend the _MyFunction method.
4) Have MyFunction call _MyFunction and run the code it needs to run before or after calling it.
This method is ugly and would require a lot of extra code, so I recommend just putting a notice in the documentation.
The requirements of the base class should be documented by the library designer.
This issue is the reason why some libraries contain mainly sealed classes.
Related
I hope this isn't a duplicate but I can't find one via Google or SO search. If I want to force the accessibility for a method's implementation of an overridden method to be protected, is my only option to either create as abstract or protected virtual? I know that interfaces specify the declaration but leave the accessibility/scope to the class implementation but I'd like to be sure.
I'd like to know/be certain of if the only way to limit the scope of a method is via a abstract \ protected virtual to give semantics of "this applies to the class implementation or the child override implementation".
A code sample to illustrate. I know I can do the following and limit the scope of an implementation like so;
public class BaseClass
{
protected virtual void OnlyMeOrChildrenCanDoAction()
{
// leave empty as current class is structural/conceptual
// but child instances may need it
}
}
By doing the above I guarantee that child implementations can only override OnlyMeorChildrenCanDoAction()as protected but not public.
But is there another way of limiting to protected without resorting to abstract or protected virtual? An example of creating a method like this is Object.Finalize() as seen here.
Or, to invert the question somewhat, why would you create a method as protected virtual unless to ensure that any implementations were limited in scope? Or is there another way to do the same?
I think you're misunderstanding the meaning and use of virtual. You can only override a method in the parent class if it is declared virtual. The override method in the child class must have the same visibility as the method in the parent class.
Implementations of methods declared in interfaces are always public.
Declaring a method abstract has the same effect as declaring it virtual, except you do not implement it in your class and any concrete classes that derive from your class must implement it.
Technically, the compiler will not allow you to change the access modifiers of a method when overriding it from the parent, so the answer to the question is that by declaring a method as protected within a class, you are only making it available to derived classes (whether abstract or not is a separate concern and doesn't bear on the access level).
Keep in mind, however, that derived class would be free to expose the function in some other way such as calling the protected method from a public one and there is no way to prevent that.
As far as "why" you would have a protected abstract member, a great example can be seen in many implementations of the Template Method pattern. You may have an abstract base class that describes the structure of an algorithm and leave the specific steps of what happens inside the boundary of each step to derived classes. In this case, one way to implement would be to declare the base class as abstract, have a public method serve as the "entry point" for the algorithm, and define specific methods used within the algorithm as protected abstract methods to lay out what the responsibility of derived classes will be. This pattern does a nice job of leaving public only those things that are intended to be consumed by the world, but can present some challenges from a unit testing perspective which are sometimes addressed by raising the visibility of the helper methods from protected to internal.
You cannot use the c# language to prevent a derived class from implementing a public version of OnlyMeOrChildrenCanDoAction. Even if you mark it as protected virtual, the derived class can use the new keyword to cover the method and change its accessibility. For example:
public class BaseClass
{
protected virtual void OnlyMeOrChildrenCanDoAction()
{
// leave empty as current class is structural/conceptual
// but child instances may need it
}
}
public class DerivedClass : BaseClass
{
public new void OnlyMeOrChildrenCanDoAction()
{
Console.WriteLine("This is public.");
}
}
public class Program
{
public static void Main()
{
var b = new BaseClass();
//b.OnlyMeOrChildrenCanDoAction(); //Will not compile
var d = new DerivedClass();
d.OnlyMeOrChildrenCanDoAction(); //Look! It's public!
}
}
Output:
This is public.
Code available on DotNetFiddle.
If you want to protect the caller from calling OnlyMeOrChildrenCanDoAction, your best bet is for the caller to use only interfaces. If OnlyMeOrChildrenCanDoAction isn't in the interface, there is no way a caller could call it, even if a derived class decided to expose it as a public class member. This is good SOLID design anyway.
On the other hand, if you're not so much worried about the caller as you are worried about your own development team doing bad things, perhaps your best option is to use FxCop or some other source code rules engine integrated into your continuous build process. Developers could still add the method but you could set up a rule to cause it to fail the build if they do so.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
I have a class A which derives from class B:
public class B
{
protected void Run() // pass data here used by all 3 Run methods
{
BeforeRun();
RunInternal();
AfterRun();
}
private void RunInternal()
{
}
private void BeforeRun()
{
}
private void AfterRun()
{
}
}
public class A : B
{
}
What is the nearest achievement I can get to force the user who inherits from class B MUST call the base method Run() ?
Add protected, virtual, abstract, etc... where you want, I am free to do changes where you suggest.
You can't require someone to call a method, except for the constructor. But a class's behavior shouldn't be in the constructor or called from the constructor. A class shouldn't start doing something just because we instantiated it. It should do something when we call its methods.
When we design a class it typically has one or two methods which are the primary responsibility of that class. Whoever creates an instance of the class is going to call one or more of those methods because that's the only reason why the class exists.
Instead of adding another method and expecting others to call it, you design the class so that the primary methods cannot be overridden. The only public methods are in the base class. The methods that get overridden aren't public. That way the base class methods always get called, and if there's something you want the base class to always do, it always gets done.
That way other classes don't change the required base class behavior. They only extend it.
public abstract class TheBaseClass
{
public void DoSomething()
{
AlwaysDoThis();
InheritedClassBehavior();
}
private void AlwaysDoThis()
{
//This method in the base class always gets called.
//You don't need to explicitly require someone
//to call it.
}
protected abstract void InheritedClassBehavior();
}
public class TheInheritedClass : TheBaseClass
{
protected override void InheritedClassBehavior()
{
//The inherited class has its own behavior here.
//But this method can't be called directly because
//it's protected. Someone still has to call
//DoSomething() in the base class, so AlwaysDoThis()
//is always called.
}
}
InheritedClassBehavior is protected, so nothing can call it directly. The only way to call it is by calling DoSomething, which will always call the method in the base class, AlwaysDoThis().
InheritedClassBehavior is abstract, so inherited classes must implement it. Or you could make it virtual - it has an implementation in the base class but an inherited class can override it. (If there aren't any abstract methods then the base class doesn't need to be abstract. The base class would only be abstract if you want to prevent creating instances of the base class, only allowing creation of inherited classes.)
Your best option is to have a base implementation in A (so make it virtual), and only override it in the derived classes if they need to change the behavior of Run().
Anything that calls Run() will get the base implementation unless there has been an override supplied. There is no way you can force the override to call the base, classical OO simply doesn't work like that.
You should also be careful of calling a virtual method from a constructor - Resharper will warn you about this (because an override may get called, and this is unknown to the base implementation).
But other than that, there is no way within C# to force a derived class to call a particular method - a derived class extends the base class, so to force this sort of behavior would break basic OO concepts. Even if you put the calls into a constructor in the base class there is no guarantee that a derived class will invoke that constructor. You can force the base class to call the derived class (use an abstract base method, this must be implemented in the derived class), the derived method can then call back to a base method; but this in itself is a bit of a work around that is really a waste of time unless some of the derived classes are actually going to add some functionality to Run().
One other approach to consider is to use a product like PostSharp - it allows you to use attributes on methods to achieve a cross cutting pattern. This still doesn't force a derived class to call base implementations, but it may be a convenient way to achieve what you are wanting (cross cutting is used for auditing or logging patterns, where a specific method must be called when another method is invoked).
I am using C# with Unity3d.
When I use Monobehaviour and create an Update method, I don't need to use the override keyword.
When I create my own class and override a function, I do need to use the override keyword.
Why is that? Why do I not need the override keyword when creating the Update method?
I think your confusion comes from the fact that Unity does something special about these methods (Update, Start, Awake, etc). You can declare them as private and even then they will be called. That's not achievable using the language unless you use reflection, but I was told they don't use it, so I don't know what they do. And honestly, it doesn't matter. Because you can think as this being an exception to the language, that is, these methods will be called if you implement them. Simply that.
For all the rest, you have to follow the language. Here is a rough explanation:
You can or have to override a method if it is marked as abstract or virtual in the base class.
A method is abstract when the base class wants its children to implement it. A method is virtual when the base class offers an implementation of it but also offers an opportunity for the children to implement/modify that method.
So why can't all methods be "overridable"? To protect the base class developer's intention. You'd be changing the behaviour of a base class, you don't know if the base class developer would like you to do this. It's like a security lock. So that's why you have the three words abstract, virtual and override, to communicate the API intentions from the base class to their children.
You need to use the override, when you derive a class from another class and you need to change the code of a method of the base class that is virtual. This way the inheritted method of the base class can have a different behaviour -more suitable- for the derived class.
More generally, as it is stated in MSDN:
The override modifier is required to extend or modify the abstract or virtual implementation of an inherited method, property, indexer, or event.
I have a litte confusion regarding method overriding and the validity of OOP priciples.
I know everything regarding sealing, shadowing, overriding, virtual etc. but I came across a scenario, that just confused me. Suppose I have:
class classA
{
public virtual void sayhello()
{
Console.WriteLine("hello I'm A");
}
};
class classB :classA
{
public override void sayhello()
{
Console.WriteLine("hello I'm B");
}
};
class Program
{
static void Main(string[] args)
{
classB a = new classB();
a.sayhello();
}
}
According to everything I studied so far, a method declared as virtual or abstract (in abstract class) can be overriden using override keyword in child class. according to this, above code works perfect.
When I remove the virtual keyword, and then try to override the method using override keyword, then compiler gives error as:
cannot override inherited member 'inheritence.classA.sayhello()' because it is not marked virtual, abstract, or override
and then i removed the override key word, from child class, and provided the implementation as:
class classB :classA
{
public void sayhello()
{
Console.WriteLine("hello I'm B");
}
};
In this case, the method could be overrided. I'm able to override the method, which is not virtual or abstract. so, my question is:
1. Did it not violate the OOP principle? since I'm able to override the method, which is not marked as virtual in parent.
2. Why am I allowed to override the method this way? which is not even marked virtual?
3. Removing virtual keyword from classA method, it gave me the feeling of sealed method in classA, when I tried to override that method in classB. (as I mentioned the compiler error earlier). If i remove virtual, so that the child class may not override it, then WHY could the child class cleverly override it, removing its override keyword? Is this ONLY the case, sealed keyword is designed for?
I will like to tell you that you gave hidden the parent child method not overridden.
One more thing you might have not noted doing the same is seeing WARNING because in warning section it will be clearly mentioned that,
Warning 'line number' 'classB .sayhello' hides inherited member 'classA.sayhello'. Use the new
keyword if hiding was intended.
Your question,
Did it not violate the OOP principle? since I'm able to override the method, which is not marked as virtual in parent.
No surely it did not violate the OOP principle as you have hide the base class method.
Why am I allowed to override the method this way? which is not even marked virtual?
Because C# not only supports overriding but also method hiding and A hiding method has to be declared using the new keyword. For More Information read dotnet_polymorphism and overriding-vs-method-hiding
Is this ONLY the case, sealed keyword is designed for?
From MSDN sealed sealed keyword is designed to prevent derivation of class and to negate the virtual aspect of the virtual members.
When applied to a class, the sealed modifier prevents other classes from inheriting from it.
sealed modifier can be only applied to a method or property that overrides a virtual method or property in a base class. This prevent further overriding specific virtual methods or properties but it can never stop method-hiding. Read Non-overridable method for more information
Did it not violate the OOP principle? since I'm able to override the method, which is not marked as virtual in parent.
You did not override the parent method you have hidden the parent method.
so you can never access the parent method from the child class object as it was hidden by your child class method sayhello().
2.Why am I allowed to override the method this way? which is not even marked virtual?
because you can hide the parent methods with child implemetation.
I think this comes from C++ implementation, which used slicing (What is object slicing?).
While C# resembles mostly Java, in some cases (this one and the existence of value types) it follows the C++ way.
The reasoning after this is that, since your code calls method sayhello from an A variable, the programmer expects the logic of A.sayhello to be executed. It does not break OOP principles, since you are executing an A.sayhello implementation (so it must match the A.sayhello contract).
The difference with Java is not OOP vs not OOP, but that Java uses late binding (the actual method to be executed is decided at runtime based in a actual instance) while C# uses early binding (the method is decided at compile time) unless the method is virtual.
Personally I prefer late binding, while C# approach is correct from an OOP point of view, I find that usually the more specialized method should be used.
Well, it's quite simple in the end:
When overriding virtual methods, the concrete methods are resolved at runtime.
When using the new keyword (or leaving it out completely), you're doing a static replacement operation at compile time based on the type information that is available in your code.
These are two totally different things.
What you did is method hiding (as others already explained).
If you really want to do it you should add new keyword in method definition to make warning disappear and also as a documentation. So that other developers looking at your code know that you did it on purpose.
I want to know the reason behind the design of restricting Abstract Methods in Non Abstract Class (in C#).
I understand that the class instance won't have the definition and thus they wont be callable, but when static methods are defined,they are excluded from the instance too. Why abstract methods are not handled that way, any specific reason for the same?
They could be allowed in concrete class and the deriving class can be forced to implement methods, basically that is what, is done in case of abstract methods in an abstract class.
First, I think that what you're asking doesn't logically make sense. If you have an abstract method, it basically means that the method is unfinished (as #ChrisSinclair pointed out). But that also means the whole class is unfinished, so it also has to be abstract.
Or another way to put it: if you had an abstract method on a class that wasn't abstract, that would mean you had a method that cannot be called. But that means the method is not useful, you could remove it and it would all work the same.
Now, I'll try to be more concrete by using an example: imagine the following code:
Animal[] zoo = new Animal[] { new Monkey(), new Fish(), new Animal() };
foreach (Animal animal in zoo)
animal.MakeSound();
Here, Animal is the non-abstract base class (which is why I can put it directly into the array), Monkey and Fish are derived from Animal and MakeSound() is the abstract method. What should this code do? You didn't state that clearly, but I can imagine few options:
You can't call MakeSound() on a variable typed as Animal, you can call it only using a variable typed as one of the derived classes, so this is a compile error.
This is not a good solution, because the whole point of abstract is to be able to treat instances of derived classes as the base class, and still get behaviour that's specific to the derived class. If you want this, just put a normal (no abstract, virtual or override) method into each derived class and don't do anything with the base class.
You can't call MakeSound() on an object whose runtime type is actually Animal, so this is a runtime error (an exception).
This is also not a good solution. C# is a statically typed language and so it tries to catch errors like “you can't call this method” at compile time (with obvious exceptions like reflection and dynamic), so making this into a runtime error wouldn't fit with the rest of the language. Besides, you can do this easily by creating a virtual method in the base class that throws an exception.
To sum up, you want something that doesn't make much sense, and smells of bad design (a base class that behaves differently than its derived classes) and can be worked around quite easily. These are all signs of a feature that should not be implemented.
So, you want to allow
class C { abstract void M(); }
to compile. Suppose it did. What do you then want to happen when someone does
new C().M();
? You want an execution-time error? Well, in general C# prefers compile-time errors to execution-time errors. If you don't like that philosophy, there are other languages available...
I think you've answered your own question, an abstract method isn't defined initially. Therefore the class cannot be instanciated. You're saying it should ignore it, but by definition when adding an abstract method you're saying "every class created from this must implement this {abstract method}" hence the class where you define the abstract class must also be abstract because the abstract method is still undefined at that point.
The abstract class may contain abstract member. There is the only method declaration if any method has an abstract keyword we can't implement in the same class. So the abstract class is incompleted. That is why the object is not created for an abstract class.
Non-abstract class can't contain abstract member.
Example:
namespace InterviewPreparation
{
public abstract class baseclass
{
public abstract void method1(); //abstract method
public abstract void method2(); //abstract method
public void method3() { } //Non- abstract method----->It is necessary to implement here.
}
class childclass : baseclass
{
public override void method1() { }
public override void method2() { }
}
public class Program //Non Abstract Class
{
public static void Main()
{
baseclass b = new childclass(); //create instance
b.method1();
b.method2();
b.method3();
}
}
}
You can achieve what you want using "virtual" methods but using virtual methods can lead to more runtime business logic errors as a developer is not "forced" to implement the logic in the child class.
I think there's a valid point here. An abstract method is the perfect solution as it would "enforce" the requirement of defining the method body in children.
I have come across many many situations where the parent class had to (or it would be more efficient to) implement some logic but "Only" children could implement rest of the logic"
So if the opportunity was there I would happily mix abstract methods with complete methods.
#AakashM, I appreciate C# prefers compile time errors. So do I. And so does anybody. This is about thinking out-of-the-box.
And supporting this will not affect that.
Let's think out of the box here, rather than saying "hurrah" to big boy decisions.
C# compiler can detect and deny someone of using an abstract class directly because it uses the "abstract" keyword.
C# also knows to force any child class to implement any abstract methods. How? because of the use of the "abstract" keyword.
This is pretty simple to understand to anyone who has studied the internals of a programming language.
So, why can't C# detect an "abstract" keyword next to a method in a normal class and handle it at the COMPILE TIME.
The reason is it takes "reworking" and the effort is not worth supporting the small demand.
Specially in an industry that lacks people who think out of the boxes that big boys have given them.
It's still not clear why you would want that, but an alternative approach could be to force derived classes to provide a delegate instance. Something like this
class MyConcreteClass
{
readonly Func<int, DateTime, string> methodImpl;
// constructor requires a delegate instance
public MyConcreteClass(Func<int, DateTime, string> methodImpl)
{
if (methodImpl == null)
throw new ArgumentNullException();
this.methodImpl = methodImpl;
}
...
}
(The signature string MethodImpl(int, DateTime) is just an example, of course.)
Otherwise, I can recommend the other answers to explain why your wish probably isn't something which would make the world better.
So the answers above are correct: having abstract methods makes the class inherently abstract. If you cannot instance part of a class, then you cannot instance the class itself. However, the answers above didn't really discuss your options here.
First, this is mainly an issue for public static methods. If the methods aren't intended to be public, then you could have protected non-abstract methods, which are allowed in an abstract class declaration. So, you could just move these static methods to a separate static class without much issue.
As an alternative, you could keep those methods in the class, but then instead of having abstract methods, declare an interface. Essentially, you have a multiple-inheritance problem as you want the derived class to inherit from two conceptually different objects: a non-abstract parent with public static members, and an abstract parent with abstract methods. Unlike some other frameworks, C# does permit multiple inheritance. Instead, C# offers a formal interface declaration that is intended to fill this purpose. Moreover, the whole point of abstract methods, really, is just to impose a certain conceptual interface.
I have a scenario very similar to what the OP is trying to achieve. In my case the method that I want to make abstract would be a protected method and would only be known to the base class. So the "new C().M();" does not apply because the method in question is not public. I want to be able to instantiate and call public methods on the base class (therefore it needs to be non-abstract), but I need these public methods to call a protected implementation of the protected method in the child class and have no default implementation in the parent. In a manner of speaking, I need to force descendants to override the method. I don't know what the child class is at compile time due to dependency injection.
My solution was to follow the rules and use a concrete base class and a virtual protected method. For the default implementation, though, I throw a NotImplementedException with the error "The implementation for method name must be provided in the implementation of the child class."
protected virtual void MyProtectedMethod()
{
throw new NotImplementedException("The implementation for MyProtectedMethod must be provided in the implementation of the child class.");
}
In this way a default implementation can never be used and implementers of descendant implementations will quickly see that they missed an important step.