c# inheritance general then specific - c#

class base_c
{
public virtual void a() {}
public virtual void b() {}
public virtual void c() {}
public virtual void d() {}
}
class other_c : base_c
{
public void a() {}
public new void b() {}
public override void c() {}
public override void d() {base.d();}
}
class Program
{
static void Main()
{
base_c game2 = new other_c();
game2.a();
game2.b();
game2.c();
game2.d();
}
}
'd' has the desired behaviour that the more general base_c function occurs as well as the more specific other_c, although it would nice if the order was the other way round. To see this in effect, use the debugger and step though the program.
Is 'd' the best way to achieve this result?
Although it could be changed in this example "base_c game2 = ..." must remain base_c and cannot be changed to other_c.

Yes, if your intent is for the child class to extend the inherited behavior in method D, then the pattern is to call base.d() in the child's override of d.
If your intent is to replace the inherited behavior (not extend), then you would not call the base method.
You also have the choice of whether to call the base method first before doing anything in your overriding method, or call the base in the middle or after your code in your overriding method.
All of these are valid techniques in the appropriate situations.

Related

How to call a base method that is declared as abstract override

In C# it's possible to mark a virtual method abstract to force inherited class to implement it.
class A
{
public virtual void Method()
{
Console.WriteLine("A method call");
}
}
abstract class B : A
{
// Class inherited from B are forced to implement Method.
public abstract override void Method();
}
I would like to call the A implementation of Method from a class inherited from B.
class C : B
{
public override void Method()
{
// I would like to call A implementation of Method like this:
// base.base.Method();
}
}
The best way I find to do this is to add a protected method "MethodCore" in A implementation and call it when needed.
class A
{
public virtual void Method()
{
MethodCore();
}
protected void MethodCore()
{
Console.WriteLine("A method call");
}
}
abstract class B : A
{
public abstract override void Method();
}
class C : B
{
public override void Method()
{
MethodCore();
}
}
Is there any other way to do this ?
The best way I find to do this is to add a protected method "MethodCore" in A implementation and call it when needed.
Yes. Since you can't call an abstract method using base, all possible solutions are going to require you to eventually call Method in A using an A instance.
That said, it looks like you are looking for a way to provide a default implementation of Method in B such that any subclass of B that does not implement the method should simply use the implementation present in A. A better solution would be to not mark Method as abstract in B. Instead, make Method in B redirect to Method in A using base.Method()
abstract class B : A {
// Class inherited from B are forced to implement Method.
public virtual void Method() {
base.Method()//calls Method in A
}
}
This way, any subclass of B that wants to call Method from A can simply say base.Method().

C#: Override inherited method, but not for the whole class

I'm just playing around a bit with inheritance and/or polymorphism in C#, and since my OOP skills are very, very basic I'm wondering if this is possible:
I have a class which inherits a method from a base class:
class BaseClass {
public void Init () {
// Do basic stuff.
}
}
class LoginTest : BaseClass {
public void StraightMethod () {
// Do stuff based on the actions in the inherited Init() method from BaseClass.
}
public void ExceptionMethod () {
// Do stuff where I don't want to do the actions in the inherited method.
// That is, skip or override the Init() method in the BaseClass class.
}
}
I know I can override the Init() method for the whole class, but is it possible to override it, or the code in it, for just the ExceptionMethod() method? These methods are run exclusively, so that for example one initialization of the LoginTest class will only run LoginClass.ExceptionMethod(), while another one might run LoginClass.StraightMethod().
And yes, I know that good design will eliminate the need for things like this. But first of all, I'm not doing software engineering here, so being pragmatic is often OK without ruining some design or other principles. Second, this is more a question of whether or not something can be done, rather than the wiseness of it.
Note that these classes and methods are UnitTest methods, so the Init() method is a [TestInitialize] method. Hence, it's called automatically when LoginTest inherits from the BaseClass.
No, you can't selectively override the Init method, but by making the Init method virtual, you can specify which version of the method you want to call with the base and this keywords:
class BaseClass
{
// This method must become virtual
public virtual void Init()
{
// Do basic stuff.
}
}
class LoginTest : BaseClass
{
public override void Init()
{
// Other stuff
}
public void StraightMethod()
{
// Do stuff based on the actions in the inherited Init() method from BaseClass.
base.Init();
}
public void ExceptionMethod()
{
// Do stuff where I don't want to do the actions in the inherited method.
// That is, skip or override the Init() method in the BaseClass class.
this.Init();
}
}
The method isn't virtual, so it's not possible to override it at all, ever.
You can't conditionally override the method, but you can call each one individually (if you provide the base functionality in the base class).
class BaseClass {
public virtual void Init () {
// Do basic stuff.
}
}
class LoginTest : Baseclass {
public override void Init() {
//do overridden stuff
}
public void StraightMehthod () {
this.Init(); // Call the overridden
}
public void ExceptionMethod () {
base.Init(); // Call the base specifically
}
}
As you have said though, this is probably not something you want to do as someone using this code will be very confused by the behavior.
You also have the option to do this.
class BaseClass
{
public void Init()
{
// Do basic stuff.
Console.WriteLine("BaseClass.Init");
}
}
class LoginTest : BaseClass
{
public void StraightMehthod()
{
// Do stuff based on the actions in the inherited Init() method from BaseClass.
base.Init();
}
public void ExceptionMethod()
{
// Do stuff where I don't want to do the actions in the inherited method.
this.Init();
// That is, skip or override the Init() method in the BaseClass class.
}
private new void Init()
{
Console.WriteLine("LoginTest.Init");
}
}

base.Method() with multiple levels of inheritance not being called?

I've searched and not been able to find any solution to my problem. My scenario is very simple:
public class A
{
public virtual void MethodOne()
{
Console.log( "A" );
}
}
public class B : A
{
public override void MethodOne()
{
base.MethodOne();
Console.log( "B" );
}
}
public class C : B
{
public override void MethodOne()
{
base.MethodOne();
Console.log( "C" );
}
}
What I am trying to do is have an instance of class C (we'll name it 'instanceC') call both the overridden method of its parent, and its grandparent. So I'd expect this:
instanceC.MethodOne();
// Output:
// "A"
// "B"
// "C"
But instead am getting this:
instanceC.MethodOne();
// Output
// "A"
// "C"
with class B's method being skipped over. Is this not possible? I thought this is the whole point of inheritance/polymorphism. Thanks in advance!
Your example works as expected for me. I see A B C. I think your most likely issue is that C doesn't extend B. However, let me suggest an arguably safer pattern while we're on the subject. You seem to want all overrides of MethodOne to execute code from their base classes. Great, inheritance is a good pattern for this. However, with this pattern you cannot force inheritors to execute the base logic because you cannot force them to call base.MethodOne(). Even if they do callbase.MethodOne(), you cannot ensure the order of the logic. Will they call base.MethodOne() at the beginning of the method, middle of the method, or end of the method? Often, in these types of patterns you want sub classes to execute all the base logic at the beginning of the function. The following pattern forces inheritors to execute base logic in the order base classes expect. It's technically less flexible but safer because inheritors must extend the base classes in a way that the base classes specify.
public class A
{
//Don't make this method virtual because you don't actually want inheritors
//to be able to override this functionality. Instead, you want inheritors
//to be able to append to this functionality.
public void MethodOne()
{
Console.WriteLine( "A" );
MethodToBeOverriddenOne();
}
//Expose a place where inheritors can add extra functionality
protected virtual void MethodToBeOverriddenOne() { }
}
public class B : A
{
//Seal the method because you don't actually want inheritors
//to be able to override this functionality. Instead, you want inheritors
//to be able to append to this functionality.
protected sealed override void MethodToBeOverriddenOne()
{
Console.WriteLine("B");
MethodToBeOverriddenTwo();
}
//Expose a place where inheritors can add extra functionality
protected virtual void MethodToBeOverriddenTwo() { }
}
public class C : B
{
protected sealed override void MethodToBeOverriddenTwo()
{
Console.WriteLine("C");
}
}
The example you posted works perfectly, whatever you are doing in your actual code is different than what you posted.
Here is your code running on ideone working as exactly like you wanted.
using System;
public class Test
{
public static void Main()
{
var c = new C();
c.MethodOne();
}
}
public class A
{
public virtual void MethodOne()
{
Console.WriteLine( "A" );
}
}
public class B : A
{
public override void MethodOne()
{
base.MethodOne();
Console.WriteLine( "B" );
}
}
public class C : B
{
public override void MethodOne()
{
base.MethodOne();
Console.WriteLine( "C" );
}
}

Can a child class implement the same interface as its parent?

I've never encountered this issue before today and was wondering what convention/best practice for accomplish this kind of behavior would be.
Basic setup is this:
public interface IDispatch {
void Dispatch();
}
public class Foo : IDispatch {
void IDispatch.Dispatch() {
DoSomething();
}
}
public class Bar : Foo {
...
}
Bar needs to subclass Foo because it shares all the same properties as Bar plus introduces 2 new ones that I need to encounter for. The problem I have is that Foo also needs a slightly different implementation of Dispatch(). Normally it would be overridden but thats not valid for an interface method so is it fine to just have Bar implement IDispatch as well so my class definition looks like this:
public class Bar : Foo, IDispatch { .... }
and then just do an explicit implementation of that interface method in Bar as well? My compiler doesn't seem to complain when I try to do it this way but I wasn't sure if it would cause any runtime issues resolving which implementation to use down the road or if there was a better way to accomplish something like this.
Also worth mentioning that at my workplace we use code generation from UML models which enforces that all class design must be done from a model first. The code generation tool is what causes interface methods to be implemented explicitly (don't want to debate the pros and cons of this its just what I'm forced to deal with right now so having an implicit implementation is not an option)
You could, alternatively, do this one of two ways:
First, don't implement the interface explicitly:
public class Foo : IDispatch {
public virtual void Dispatch() {
whatever();
}
}
public class Bar : Foo {
public override void Dispatch() {
whateverElse();
}
}
Second, implement it explicitly but add a function that the child class can override:
public class Foo : IDispatch {
void IDispatch.Dispatch() {
this.Dispatch();
}
protected virtual void Dispatch() {
whatever();
}
}
public class Bar : Foo {
protected override void Dispatch() {
whateverElse();
}
}
Yes, you can explicitly redeclare that you want to implement IDispatch, and implement it explicitly again in Bar.
However, you won't be able to call the original implementation in Foo. If you need to do that, you'll need to change Foo either to use implicit interface implementation with a virtual method (which can be overridden and then called with base.Dispatch() in Bar) or make the Foo implementation call a protected virtual method which again you'd override in Bar.
Bar already implements IDispatch if it is subclass of Foo, no need to explicitly state that. If you want to implement only one method of interface in a different way, do sth like this:
IDispatch { void Method(); }
Foo : IDispatch { public virtual void Method() { implementation1 } }
Bar : Foo { public override void Method() { implementation2 } }
You don't have to do the IDispatch.Dispatch - so long as a method called Dispatch is in your class you will have implemented the interface.
You can do this, it builds for me:
public class Foo : IDispatch
{
public virtual void Dispatch()
{
}
}
public class Bar : Foo
{
public override void Dispatch()
{
base.Dispatch();
}
}
I do prefer to explicitly implement interfaces. It's easier for people unfamiliar with your code base to understand what's an interface vs class specific logic.
You can still accomplish class inheritance while explicitly implementing interfaces. You just need to have the base class implement the interface, and have that implementation call into a virtual function which can be extended. Here's an example:
interface Inter
{
void Call();
}
class A : Inter
{
//Explicitly implemented interface
void Inter.Call()
{
this.Call();
}
public virtual void Call() { Console.WriteLine("Base call in A"); }
}
class B : A
{
public override void Call()
{
Console.WriteLine( "Called B" );
}
}
class Program
{
static void Main( string[] args )
{
var a = new A(); //Base class
var aa = (Inter)a; //Interface only
a.Call();
aa.Call();
var b = new B(); //Child class
var bb = (Inter)b; //Interface only of Child class
b.Call();
bb.Call();
//See the output before the console program closes
Console.ReadLine();
}
}
Program output:
Base call in A
Base call in A
Called B
Called B

I would like to override a method in C#, but I have a different signature

The base class user should access the original method
class A
public init()
The derived class user should aceess ONLY the derived method.
class B
public init(int info)
I cannot use "override" bc there's a different signature.
What options do I have so that the derived class user does not see two methods.
Notes.
All in all I just need two classes that share some code. Inheritance is not a must.
But simplicity for the user of B is a priority.
This is a big code smell (and violates some basic OOP tenets) and, to the best of my knowledge, can not be done in any language. In OOP, an instance of B is an instance of A; this is polymorphism. So if A has a public method named init accepting no parameters, then so does B.
What are you trying to do this for?
Edit: Now that you've added the edit that states that inheritance is not a must, just use composition to share code. Give B a private instance of A, for example.
According to the Liskov principle you simply cannot do that, because it would violate this principle. The best thing you can to is override init() in the derived class and make it throw an exception every time it's invoked, stating that the user should use init(int info) and rely on the test to catch the errors.
Why you can't simple replace the init() method or even make it protected?
The Liskov principle states (rephrased) that where an instance of class A is required, an isntance of class B extends A can be passed.
If a method expects A and wants to call init() on it and you pass B (which extends A) to it with a protected init() the method will fail. This is the reason why the code will not even compile.
What you're asking for is impossible, due to the nature of the type system. Any instance of B can be thought of as an A, so you can call any of A's methods (including Init()). The best you can do is overload Init() in B and throw an exception to catch this at runtime.
public class B
{
void Init()
{
throw new NotSupportedException();
}
}
Contrary to some answers/comments here, what you are asking for would have a real use if it existed:
class Derived : Base
{
This can be seen by considering the workaround:
class Derived
{
private Base _base = new Base();
In other words, it's not really a base class at all, but a hidden part of the implementation.
The downside with this workaround is: what Base has an abstract method that you have to supply? You have to write this:
class Derived
{
class ActualDerived : Base
{
// override abstract method(s)
}
private Base _base = new ActualDerived();
This is the whole point of private inheritance (as found in C++) - it's for situations when you want to inherit the implementation but not the "interface" (in the informal sense).
But in C#, it's not available.
Presumabely A and B have something in common. Can you factor that out into a different base class?
public class Base
{
... common stuff ...
}
public class A : Base
{
public void Init()
{
}
}
public class B : Base
{
public void Init(int info)
{
}
}
if you need polymorphism then references to Base or, better yet, Thomas' interface are the way to go.
Instead of inheritance, use an interface as a "middle man":
public interface IAllThatYouNeed
{
public void DoSomeStuff();
}
public class A : IAllThatYouNeed
{
public void Init() {
// do stuff
}
}
public class B : IAllThatYouNeed
{
public void Init(int info) {
// do stuff
}
}
it looks like it's not yet possible
i tried to do something like this:
public class B : A
{
private override void Init() { }
public void Init(int x)
{ }
}
but Init() it's still visible from the A class
There is no perfect solution here. Some possible ways to do it:
An approach would be to make A.Init() virtual, override it in B and make it throw a NotImplementedException/InvalidOperationException.
Init() stays visible, but the user finds out very quickly that it is not to be used (make it explicit that Init(int info) is to be used in the XML documentation and in the message of the exception).
If you don't care about the inheritance part and just want to use the functionalities of class A in class B, don't have B deriving from A and make B instantiate A and use its functionalities.
Edit:
You can use an interface implementing the common operations in order to retain inheritance while avoiding to implement Init() in B:
public interface IOperations
{
void DoStuff();
void Foo();
}
public class A : IOperations
{
public void Init()
{
// Do class A init stuff
}
#region IOperations Members
public void DoStuff()
{
// ...
}
public void Foo()
{
// ...
}
#endregion
}
public class B : IOperations
{
A _operations = new A();
public void Init(int initData)
{
_operations.Init();
// Do class B init stuff
}
#region IOperations Members
public void DoStuff()
{
_operations.DoStuff();
}
public void Foo()
{
_operations.Foo();
}
#endregion
}
This can be made even better by using a factory:
public static class OperationsFactory
{
public static IOperations CreateOperations()
{
A result = new A();
result.Init();
return result;
}
public static IOperations CreateOperations(int initData)
{
B result = new B();
result.Init(initData);
return result;
}
}
This way instantiation code is well encapsulated, the difference between the two Init() methods is hidden from the user code.

Categories