Calling a base abstract method in an override of that method - c#

If I have the following:
e.g.
public abstract class ClassA
{
protected abstract void ValidateTransaction();
}
public abstract class ClassB : ClassA
{
protected override void ValidateTransaction()
{
// some custom logic here
}
}
public class ClassC : ClassB
{
protected override void ValidateTransaction()
{
base.ValidateTransaction();
// some additional custom logic here
}
}
So I did not find usages on ClassC's ValidateTransaction. I don't see it being called anywhere.
So then I guess how does this work? I mean it's calling the method at the top of the stack here (calls the ClassB's override method and then includes logic in my ClassC's override of ClassB's method?)
This doesn't make sense to me why or how this works or the intention here.
UPDATED
Ok so I did find a spot where ClassA's PerformTransaction() method is called from a lot of sub classes in our project.
So ClassA now looks like this with more details for you here:
public abstract class ClassA
{
public void PerformTransaction()
{
ValidateTransaction();
// and calls some other code here.
}
protected abstract void ValidateTransaction();
}
Ok then we still have:
public abstract class ClassB : ClassA
{
protected override void ValidateTransaction()
{
// some custom logic here
}
}
public class ClassC : ClassB
{
protected override void ValidateTransaction()
{
base.ValidateTransaction();
// some additional custom logic here
}
}
public class SomeAbritraryClass : ClassC
{
ClassA.PerformTransaction();
...
}
so ClassA.PerformTransaction() is being called in some classes that inherit ClassC.

Well, it calls ClassC's override method... which happens to call ClassB's implementation. It's not "including" the logic of ClassB's implementation directly within the compiled code of ClassC, or anything like that - it's just another method call.
It's not entirely clear what's confusing you - the behaviour, the design intention, or what Find Usages is showing you.
Note that despite your subject line, you're not calling a "base abstract method" - you're calling the implementation of that method. The compiler knows that ClassC derives from ClassB, which is providing an implementation of the method, so it's making that call explicitly. You couldn't do the same thing from ClassB itself, because then base.ValidateTransaction really would be trying to call an abstract base method.
Fun fact: despite this calling a virtual method, it's a non-virtual method call: the compiler knows the exact implementation to use, and bakes that into the call. If it was a virtual call, you'd end up back in the ClassC implementation as that overrides it :)

When the C class override is called, it will first call into B's override and execute some logic there, which will then be extended by C's logic.
They could for all I know be working with the same variables, data. I don't know, cause I don't have all the data.

So then I guess how does this work? I mean it's calling the method at the top of the stack here (calls the ClassB's override method and then includes logic in my ClassC's override of ClassB's method?)
Yes, that's basically what happens. When you call ValidateTransaction on an instance of ClassC, it's method is run. It, then, explicitly executes the base class (ClassB) method, then adds its own additional validation.
You're probably not finding direct usages of ClassB.ValidateTransaction() because there are no instances of ClassB (defined as ClassB) on which this is called. However, any ClassC call will be indirectly using ClassB.ValidateTransaction() through the base.ValidateTransaction() line.

Related

Method overriding works without using virtual/override properties [duplicate]

This question already has answers here:
Difference between shadowing and overriding in C#?
(6 answers)
Closed 3 years ago.
I am a bit confused about overriding vs. hiding a method in C#. Practical uses of each would also be appreciated, as well as an explanation for when one would use each.
I am confused about overriding - why do we override? What I have learnt so far is that by overring we can provide desired implementation to a method of a derived class, without changing the signature.
If I don't override the method of the superclass and I make changes to the method in the sub class, will that make changes to the super class method ?
I am also confused about the following - what does this demonstrate?
class A
{
virtual m1()
{
console.writeline("Bye to all");
}
}
class B : A
{
override m1()
{
console.writeLine("Hi to all");
}
}
class C
{
A a = new A();
B b = new B();
a = b; (what is this)
a.m1(); // what this will print and why?
b = a; // what happens here?
}
Consider:
public class BaseClass
{
public void WriteNum()
{
Console.WriteLine(12);
}
public virtual void WriteStr()
{
Console.WriteLine("abc");
}
}
public class DerivedClass : BaseClass
{
public new void WriteNum()
{
Console.WriteLine(42);
}
public override void WriteStr()
{
Console.WriteLine("xyz");
}
}
/* ... */
BaseClass isReallyBase = new BaseClass();
BaseClass isReallyDerived = new DerivedClass();
DerivedClass isClearlyDerived = new DerivedClass();
isReallyBase.WriteNum(); // writes 12
isReallyBase.WriteStr(); // writes abc
isReallyDerived.WriteNum(); // writes 12
isReallyDerived.WriteStr(); // writes xyz
isClearlyDerived.WriteNum(); // writes 42
isClearlyDerived.writeStr(); // writes xyz
Overriding is the classic OO way in which a derived class can have more specific behaviour than a base class (in some languages you've no choice but to do so). When a virtual method is called on an object, then the most derived version of the method is called. Hence even though we are dealing with isReallyDerived as a BaseClass then functionality defined in DerivedClass is used.
Hiding means that we have a completely different method. When we call WriteNum() on isReallyDerived then there's no way of knowing that there is a different WriteNum() on DerivedClass so it isn't called. It can only be called when we are dealing with the object as a DerivedClass.
Most of the time hiding is bad. Generally, either you should have a method as virtual if its likely to be changed in a derived class, and override it in the derived class. There are however two things it is useful for:
Forward compatibility. If DerivedClass had a DoStuff() method, and then later on BaseClass was changed to add a DoStuff() method, (remember that they may be written by different people and exist in different assemblies) then a ban on member hiding would have suddenly made DerivedClass buggy without it changing. Also, if the new DoStuff() on BaseClass was virtual, then automatically making that on DerivedClass an override of it could lead to the pre-existing method being called when it shouldn't. Hence it's good that hiding is the default (we use new to make it clear we definitely want to hide, but leaving it out hides and emits a warning on compilation).
Poor-man's covariance. Consider a Clone() method on BaseClass that returns a new BaseClass that's a copy of that created. In the override on DerivedClass this will create a DerivedClass but return it as a BaseClass, which isn't as useful. What we could do is to have a virtual protected CreateClone() that is overridden. In BaseClass we have a Clone() that returns the result of this - and all is well - in DerivedClass we hide this with a new Clone() that returns a DerivedClass. Calling Clone() on BaseClass will always return a BaseClass reference, which will be a BaseClass value or a DerivedClass value as appropriate. Calling Clone() on DerivedClass will return a DerivedClass value, which is what we'd want in that context. There are other variants of this principle, however it should be noted that they are all pretty rare.
An important thing to note with the second case, is that we've used hiding precisely to remove surprises to the calling code, as the person using DerivedClass might reasonably expect its Clone() to return a DerivedClass. The results of any of the ways it could be called are kept consistent with each other. Most cases of hiding risk introducing surprises, which is why they are generally frowned upon. This one is justified precisely because it solves the very problem that hiding often introduces.
In all, hiding is sometimes necessary, infrequently useful, but generally bad, so be very wary of it.
Overriding is when you provide a new override implementation of a method in a descendant class when that method is defined in the base class as virtual.
Hiding is when you provide a new implementation of a method in a descendant class when that method is not defined in the base class as virtual, or when your new implementation does not specify override.
Hiding is very often bad; you should generally try not to do it if you can avoid it at all. Hiding can cause unexpected things to happen, because Hidden methods are only used when called on a variable of the actual type you defined, not if using a base class reference... on the other hand, Virtual methods which are overridden will end up with the proper method version being called, even when called using the base class reference on a child class.
For instance, consider these classes:
public class BaseClass
{
public virtual void Method1() //Virtual method
{
Console.WriteLine("Running BaseClass Method1");
}
public void Method2() //Not a virtual method
{
Console.WriteLine("Running BaseClass Method2");
}
}
public class InheritedClass : BaseClass
{
public override void Method1() //Overriding the base virtual method.
{
Console.WriteLine("Running InheritedClass Method1");
}
public new void Method2() //Can't override the base method; must 'new' it.
{
Console.WriteLine("Running InheritedClass Method2");
}
}
Let's call it like this, with an instance of InheritedClass, in a matching reference:
InheritedClass inherited = new InheritedClass();
inherited.Method1();
inherited.Method2();
This returns what you should expect; both methods say they are running the InheritedClass versions.
Running InheritedClass Method1
Running InheritedClass Method2
This code creates an instance of the same, InheritedClass, but stores it in a BaseClass reference:
BaseClass baseRef = new InheritedClass();
baseRef.Method1();
baseRef.Method2();
Normally, under OOP principles, you should expect the same output as the above example. But you don't get the same output:
Running InheritedClass Method1
Running BaseClass Method2
When you wrote the InheritedClass code, you may have wanted all calls to Method2() to run the code you wrote in it. Normally, this would be how it works - assuming you are working with a virtual method that you have overridden. But because you are using a new/hidden method, it calls the version on the reference you are using, instead.
If that's the behavior you truly want, then; there you go. But I would strongly suggest that if that's what you want, there may be a larger architectural issue with the code.
Method Overriding is simpley override a default implementation of a base class method in the derived class.
Method Hiding : You can make use of 'new' keyword before a virtual method in a derived class
as
class Foo
{
public virtual void foo1()
{
}
}
class Bar:Foo
{
public new virtual void foo1()
{
}
}
now if you make another class Bar1 which is derived from Bar , you can override foo1 which is defind in Bar.

Why a member method of class is called before the Constructor

Generally, Constructor is the very first thing to be executed in class when it's instantiated.
But in following case, A member methods of the class are executed first & then the constructor.
Why is it so?
A Code Scenario :
namespace AbsPractice
{
class Program
{
static void Main(string[] args)
{
SavingsCustomer sc = new SavingsCustomer();
CorporateCustomer cc = new CorporateCustomer();
}
}
public abstract class Customer
{
protected Customer()
{
Console.WriteLine("Constructor of Abstract Customer");
Print();
}
protected abstract void Print();
}
public class SavingsCustomer : Customer
{
public SavingsCustomer()
{
Console.WriteLine("Constructor of SavingsCustomer");
}
protected override void Print()
{
Console.WriteLine("Print() Method of SavingsCustomer");
}
}
public class CorporateCustomer : Customer
{
public CorporateCustomer()
{
Console.WriteLine("Constructor of CorporateCustomer");
}
protected override void Print()
{
Console.WriteLine("Print() Method of CorporateCustomer");
}
}
}
That's because when you call SavingsCustomer ctor, first of all its base class ctor is called; in Customer ctor you call Print that's an overridden method.
So basicly before SavingsCustomer ctor instructions are executed, Customer ctor must be completely called.
Note that when you call Print from Customer, SavingsCustomer.Print() is executed.
This is the expected behaviour; if you want your classes to behave differently, you must change their logic. Maybe you shouldn't call an abstract method from base constructor, just to avoid what you're seeing now...
You should never, never do this unless you have a very good reason.
Calling a virtual method from a constructor is a disaster waiting to happen.
In C# object construction follows the class hierarchy order; that is, when a constructor is invoked, the most base class constructor is called first, then the immediately derived class constructor, then the next, etc. etc. (if I'm not mistaken, in C++ it's the other way around which can lead to even more confusion).
So when you call a virtual method from a constructor what really happens is that the virtual method, if overridden (which in your case is a guarantee), will be executed before the implementing class constructor is invoked. This means that the method could be executed before the object's state has been correctly initialized (normally via the constructor; if the method does not depend on any object state then this pattern is not an issue although I'd still not recommend it).
If it is absolutely necessary to use this pattern, good practices recommend implementing an Initialize() method and do any virtual calls form there. Enforcing consumers to call Initialize before using the object is a trivial task and you guarantee that the object's state will always be valid when the virtual call is made.
Tricky question.When You Create an object like this
SavingsCustomer sc = new SavingsCustomer();
It invokes constructor of Customer[base of class SavingsCustomer],means Customer()
- which inturn invoke Print() from class SavingsCustomer as it is abstract in Customer Class.
Eventhough it is a member function of SavingsCustomer it can be called from Customer class before calling constructor of SavingsCustomer Becuase Print() is declared as abstract method so it is shared by these two classes.
Same happens in the following declaration
CorporateCustomer cc = new CorporateCustomer();
Print() from CorporateCustomer class is called since SavingsCustomer.Print() is overrided

Object oriented design issues - abstract, derived/implementing types - a use case scenario

I have no practical experience with OO design, thus I am hesitant as to the solution I adopted for the following problem:
I have to process network text files that come from N different sources, in different formats - with the processing consisting in the classical reading, computations, and insertion into database.
The solution I devised was to create a class that defines all functionalities/behaviors that are core/file-format-independent, and create derived classes from the latter where each contain the appropriate format-reading logic, according to the file-type the given class handles.
All files are read via File.ReadAllLines(), what differs is mapping fields from the file into the main object's variables. So I did this by defining an event in the base class, that is called after File.ReadAllLines(), and all derived classes attach their mapping logic to the inherited event.
But I understand this solution is not correct design-wise. First of all, there is no meaning in instantiating the base class, so it should be abstract. The reason I did not make it abstract is that the construction code for all the derived objects is the same, so I defined it as the base constructor. Should I declare an "Initialize" method in the abstract class and simply call it in every derived class's constructor? (looks weird...)
Perhaps interfaces? I don't see how using an interface would give me any benefits here, besides it will not solve this "constructor" problem...
What is the correct solution?
Code demonstration of my scenario:
public delegate void myDelegate(object parameter);
class Base
{
#region Attributes
...
#endregion
public Base(object p)
{
//initialization code
...
}
#region Methods
protected void m1() { }
protected void m2() { }
...
#endregion
public event myDelegate myEvent;
}
class Child1
{
public Child1(object o) : base(o)
{
this.myEvent += new myDelegate(ChildMethod);
}
public void ChildMethod(object o)
{
...
}
}
First of all, there is no meaning in instantiating the base class, so it should be abstract. The reason I did not make it abstract is that the construction code for all the derived objects is the same, so I defined it as the base constructor.
You still can make the base class abstract yet have common constructor logic in the base class constructor. I see in your code you've already figured out how to call the base class constructor; that's all you need to do.
abstract class Base {
public Base(object o) { }
public abstract void M();
}
class Derived : Base {
public Derived(object o) : base(o) { }
public override void M() { }
}

Overriding vs method hiding [duplicate]

This question already has answers here:
Difference between shadowing and overriding in C#?
(7 answers)
Closed 3 years ago.
I am a bit confused about overriding vs. hiding a method in C#. Practical uses of each would also be appreciated, as well as an explanation for when one would use each.
I am confused about overriding - why do we override? What I have learnt so far is that by overring we can provide desired implementation to a method of a derived class, without changing the signature.
If I don't override the method of the superclass and I make changes to the method in the sub class, will that make changes to the super class method ?
I am also confused about the following - what does this demonstrate?
class A
{
virtual m1()
{
console.writeline("Bye to all");
}
}
class B : A
{
override m1()
{
console.writeLine("Hi to all");
}
}
class C
{
A a = new A();
B b = new B();
a = b; (what is this)
a.m1(); // what this will print and why?
b = a; // what happens here?
}
Consider:
public class BaseClass
{
public void WriteNum()
{
Console.WriteLine(12);
}
public virtual void WriteStr()
{
Console.WriteLine("abc");
}
}
public class DerivedClass : BaseClass
{
public new void WriteNum()
{
Console.WriteLine(42);
}
public override void WriteStr()
{
Console.WriteLine("xyz");
}
}
/* ... */
BaseClass isReallyBase = new BaseClass();
BaseClass isReallyDerived = new DerivedClass();
DerivedClass isClearlyDerived = new DerivedClass();
isReallyBase.WriteNum(); // writes 12
isReallyBase.WriteStr(); // writes abc
isReallyDerived.WriteNum(); // writes 12
isReallyDerived.WriteStr(); // writes xyz
isClearlyDerived.WriteNum(); // writes 42
isClearlyDerived.writeStr(); // writes xyz
Overriding is the classic OO way in which a derived class can have more specific behaviour than a base class (in some languages you've no choice but to do so). When a virtual method is called on an object, then the most derived version of the method is called. Hence even though we are dealing with isReallyDerived as a BaseClass then functionality defined in DerivedClass is used.
Hiding means that we have a completely different method. When we call WriteNum() on isReallyDerived then there's no way of knowing that there is a different WriteNum() on DerivedClass so it isn't called. It can only be called when we are dealing with the object as a DerivedClass.
Most of the time hiding is bad. Generally, either you should have a method as virtual if its likely to be changed in a derived class, and override it in the derived class. There are however two things it is useful for:
Forward compatibility. If DerivedClass had a DoStuff() method, and then later on BaseClass was changed to add a DoStuff() method, (remember that they may be written by different people and exist in different assemblies) then a ban on member hiding would have suddenly made DerivedClass buggy without it changing. Also, if the new DoStuff() on BaseClass was virtual, then automatically making that on DerivedClass an override of it could lead to the pre-existing method being called when it shouldn't. Hence it's good that hiding is the default (we use new to make it clear we definitely want to hide, but leaving it out hides and emits a warning on compilation).
Poor-man's covariance. Consider a Clone() method on BaseClass that returns a new BaseClass that's a copy of that created. In the override on DerivedClass this will create a DerivedClass but return it as a BaseClass, which isn't as useful. What we could do is to have a virtual protected CreateClone() that is overridden. In BaseClass we have a Clone() that returns the result of this - and all is well - in DerivedClass we hide this with a new Clone() that returns a DerivedClass. Calling Clone() on BaseClass will always return a BaseClass reference, which will be a BaseClass value or a DerivedClass value as appropriate. Calling Clone() on DerivedClass will return a DerivedClass value, which is what we'd want in that context. There are other variants of this principle, however it should be noted that they are all pretty rare.
An important thing to note with the second case, is that we've used hiding precisely to remove surprises to the calling code, as the person using DerivedClass might reasonably expect its Clone() to return a DerivedClass. The results of any of the ways it could be called are kept consistent with each other. Most cases of hiding risk introducing surprises, which is why they are generally frowned upon. This one is justified precisely because it solves the very problem that hiding often introduces.
In all, hiding is sometimes necessary, infrequently useful, but generally bad, so be very wary of it.
Overriding is when you provide a new override implementation of a method in a descendant class when that method is defined in the base class as virtual.
Hiding is when you provide a new implementation of a method in a descendant class when that method is not defined in the base class as virtual, or when your new implementation does not specify override.
Hiding is very often bad; you should generally try not to do it if you can avoid it at all. Hiding can cause unexpected things to happen, because Hidden methods are only used when called on a variable of the actual type you defined, not if using a base class reference... on the other hand, Virtual methods which are overridden will end up with the proper method version being called, even when called using the base class reference on a child class.
For instance, consider these classes:
public class BaseClass
{
public virtual void Method1() //Virtual method
{
Console.WriteLine("Running BaseClass Method1");
}
public void Method2() //Not a virtual method
{
Console.WriteLine("Running BaseClass Method2");
}
}
public class InheritedClass : BaseClass
{
public override void Method1() //Overriding the base virtual method.
{
Console.WriteLine("Running InheritedClass Method1");
}
public new void Method2() //Can't override the base method; must 'new' it.
{
Console.WriteLine("Running InheritedClass Method2");
}
}
Let's call it like this, with an instance of InheritedClass, in a matching reference:
InheritedClass inherited = new InheritedClass();
inherited.Method1();
inherited.Method2();
This returns what you should expect; both methods say they are running the InheritedClass versions.
Running InheritedClass Method1
Running InheritedClass Method2
This code creates an instance of the same, InheritedClass, but stores it in a BaseClass reference:
BaseClass baseRef = new InheritedClass();
baseRef.Method1();
baseRef.Method2();
Normally, under OOP principles, you should expect the same output as the above example. But you don't get the same output:
Running InheritedClass Method1
Running BaseClass Method2
When you wrote the InheritedClass code, you may have wanted all calls to Method2() to run the code you wrote in it. Normally, this would be how it works - assuming you are working with a virtual method that you have overridden. But because you are using a new/hidden method, it calls the version on the reference you are using, instead.
If that's the behavior you truly want, then; there you go. But I would strongly suggest that if that's what you want, there may be a larger architectural issue with the code.
Method Overriding is simpley override a default implementation of a base class method in the derived class.
Method Hiding : You can make use of 'new' keyword before a virtual method in a derived class
as
class Foo
{
public virtual void foo1()
{
}
}
class Bar:Foo
{
public new virtual void foo1()
{
}
}
now if you make another class Bar1 which is derived from Bar , you can override foo1 which is defind in Bar.

Force base method call

Is there a construct in Java or C# that forces inheriting classes to call the base implementation? You can call super() or base() but is it possible to have it throw a compile-time error if it isn't called? That would be very convenient..
--edit--
I am mainly curious about overriding methods.
There isn't and shouldn't be anything to do that.
The closest thing I can think of off hand if something like having this in the base class:
public virtual void BeforeFoo(){}
public void Foo()
{
this.BeforeFoo();
//do some stuff
this.AfterFoo();
}
public virtual void AfterFoo(){}
And allow the inheriting class override BeforeFoo and/or AfterFoo
Not in Java. It might be possible in C#, but someone else will have to speak to that.
If I understand correctly you want this:
class A {
public void foo() {
// Do superclass stuff
}
}
class B extends A {
public void foo() {
super.foo();
// Do subclass stuff
}
}
What you can do in Java to enforce usage of the superclass foo is something like:
class A {
public final void foo() {
// Do stuff
...
// Then delegate to subclass
fooImpl();
}
protected abstract void fooImpl();
}
class B extends A {
protected void fooImpl() {
// Do subclass stuff
}
}
It's ugly, but it achieves what you want. Otherwise you'll just have to be careful to make sure you call the superclass method.
Maybe you could tinker with your design to fix the problem, rather than using a technical solution. It might not be possible but is probably worth thinking about.
EDIT: Maybe I misunderstood the question. Are you talking about only constructors or methods in general? I assumed methods in general.
The following example throws an InvalidOperationException when the base functionality is not inherited when overriding a method.
This might be useful for scenarios where the method is invoked by some internal API.
i.e. where Foo() is not designed to be invoked directly:
public abstract class ExampleBase {
private bool _baseInvoked;
internal protected virtual void Foo() {
_baseInvoked = true;
// IMPORTANT: This must always be executed!
}
internal void InvokeFoo() {
Foo();
if (!_baseInvoked)
throw new InvalidOperationException("Custom classes must invoke `base.Foo()` when method is overridden.");
}
}
Works:
public class ExampleA : ExampleBase {
protected override void Foo() {
base.Foo();
}
}
Yells:
public class ExampleB : ExampleBase {
protected override void Foo() {
}
}
I use the following technique. Notice that the Hello() method is protected, so it can't be called from outside...
public abstract class Animal
{
protected abstract void Hello();
public void SayHello()
{
//Do some mandatory thing
Console.WriteLine("something mandatory");
Hello();
Console.WriteLine();
}
}
public class Dog : Animal
{
protected override void Hello()
{
Console.WriteLine("woof");
}
}
public class Cat : Animal
{
protected override void Hello()
{
Console.WriteLine("meow");
}
}
Example usage:
static void Main(string[] args)
{
var animals = new List<Animal>()
{
new Cat(),
new Dog(),
new Dog(),
new Dog()
};
animals.ForEach(animal => animal.SayHello());
Console.ReadKey();
}
Which produces:
You may want to look at this (call super antipatern) http://en.wikipedia.org/wiki/Call_super
If I understand correctly you want to enforce that your base class behaviour is not overriden, but still be able to extend it, then I'd use the template method design pattern and in C# don't include the virtual keyword in the method definition.
No. It is not possible. If you have to have a function that does some pre or post action do something like this:
internal class Class1
{
internal virtual void SomeFunc()
{
// no guarantee this code will run
}
internal void MakeSureICanDoSomething()
{
// do pre stuff I have to do
ThisCodeMayNotRun();
// do post stuff I have to do
}
internal virtual void ThisCodeMayNotRun()
{
// this code may or may not run depending on
// the derived class
}
}
I didn't read ALL the replies here; however, I was considering the same question. After reviewing what I REALLY wanted to do, it seemed to me that if I want to FORCE the call to the base method that I should not have declared the base method virtual (override-able) in the first place.
Don't force a base call. Make the parent method do what you want, while calling an overridable (eg: abstract) protected method in its body.
Don't think there's any feasible solution built-in. I'm sure there's separate code analysis tools that can do that, though.
EDIT Misread construct as constructor. Leaving up as CW since it fits a very limited subset of the problem.
In C# you can force this behavior by defining a single constructor having at least one parameter in the base type. This removes the default constructor and forces derived types to explcitly call the specified base or they get a compilation error.
class Parent {
protected Parent(int id) {
}
}
class Child : Parent {
// Does not compile
public Child() {}
// Also does not compile
public Child(int id) { }
// Compiles
public Child() :base(42) {}
}
In java, the compiler can only enforce this in the case of Constructors.
A constructor must be called all the way up the inheritance chain .. ie if Dog extends Animal extends Thing, the constructor for Dog must call a constructor for Animal must call a constructor for Thing.
This is not the case for regular methods, where the programmer must explicitly call a super implementation if necessary.
The only way to enforce some base implementation code to be run is to split override-able code into a separate method call:
public class Super
{
public final void doIt()
{
// cannot be overridden
doItSub();
}
protected void doItSub()
{
// override this
}
}
public class Sub extends Super
{
protected void doItSub()
{
// override logic
}
}
I stumbled on to this post and didn't necessarily like any particular answer, so I figured I would provide my own ...
There is no way in C# to enforce that the base method is called. Therefore coding as such is considered an anti-pattern since a follow-up developer may not realize they must call the base method else the class will be in an incomplete or bad state.
However, I have found circumstances where this type of functionality is required and can be fulfilled accordingly. Usually the derived class needs a resource of the base class. In order to get the resource, which normally might be exposed via a property, it is instead exposed via a method. The derived class has no choice but to call the method to get the resource, therefore ensuring that the base class method is executed.
The next logical question one might ask is why not put it in the constructor instead? The reason is that it may be an order of operations issue. At the time the class is constructed, there may be some inputs still missing.
Does this get away from the question? Yes and no. Yes, it does force the derived class to call a particular base class method. No, it does not do this with the override keyword. Could this be helpful to an individual looking for an answer to this post, maybe.
I'm not preaching this as gospel, and if individuals see a downside to this approach, I would love to hear about it.
On the Android platform there is a Java annotation called 'CallSuper' that enforces the calling of the base method at compile time (although this check is quite basic). Probably the same type of mechanism can be easily implemented in Java in the same exact way. https://developer.android.com/reference/androidx/annotation/CallSuper

Categories

Resources