Class inheritance, forcing new classes to implement certain functions - c#

Ok so i'm messing around with a few things, specifically interfaces.
Say I have a class 'Cat' with its base as 'Animal' Animal has a method in it like so
public virtual void Walk()
{
// Do walking stuff
}
So Cat would override it with:
public override void Walk()
{
// Do cat specific walking stuff
}
Simple right?
Here's my question though, is there a way to force cat to override the base Walk() method? So if another developer added a Dog class they would be forced to implement their own Walk method (even if it was just base.Walk()) ?
So interfaces kind of solves this, this is what i've tried
Cat : Animal : Interface
Animal has to implement the Walk method, but Cat doesn't
Cat : Animal, Interface
Cat has to implement the Walk method, but if the developer doesn't add or forgets the ',Interface' then it will 'break' it.
can someone give me some pointer as to go about this ?
Thanks.
Edit 1
Here's what I am aiming for, i hope it makes it clearer.
public class Animal
{
public Animal()
{
Console.WriteLine("Animal");
}
public virtual void Walk()
{
}
}
public class Cat : Animal
{
public Cat() : base()
{
Console.WriteLine("Cat");
}
public override void Walk()
{
}
}
class Dog : Animal
{
public Dog()
{
}
public override void Walk()
{
// Dog implementation
// and / or calls base method
base.Walk();
}
}
This would create an error
class Dog : Animal
{
public Dog()
{
}
}

This is when you want to mark the base class and the base method as abstract.
abstract class Animal
{
public abstract void Walk();
}
Derived classes will have to implement Walk in order to be instantiated.
class Cat : Animal
{
public override void Walk() { }
}
Note: this change makes Animal not instantiable on its own, all references to it would be via more derived classes.
Animal animal = new Cat();
Here's my question though, is there a way to force cat to override the
base Walk() method? So if another developer added a Dog class they
would be forced to implement their own Walk method (even if it was
just base.Walk()) ?
This is where you have a disconnect, or opposing goals. To force children to implement a method, you mark it abstract. To allow the child to elect to use the base implementation, it would need to be virtual, which would then make it optional to override. Even if you were to basically use a template method pattern and make parts of the algorithm abstract to push the implementation into lower classes, the problem remains the same: you cannot force an override while also leaving a default implementation.*
You need to determine if you want to have a base implementation, in part or in whole.
*You chould theoretically have abstract void Walk(); protected void WalkImpl() { } in the base, which would allow the children to choose to invoke WalkImpl if they didn't want to provide their own implementation.
class Cat : Animal
{
protected override void Walk() { base.WalkImpl(); }
}
I'm not sure how I feel about this, however. You're basically making the derived classes' authors' lives more difficult by forcing an override while still allowing them to use a default behavior. If the default behavior can be used, simply go with virtual and trust authors of derived classes to override when they feel it is appropriate.

Related

Is it possible to require a derived class to implement a virtual method from base class?

I want a method to do a consistent thing in base class while derived classes can have it do something different (hence it being virtual), while requiring it be implemented in derived classes as if it were abstract. It being required would prevent forgetfulness of implementing it among myself and others working on it.
To break it down (this code is for a Unity project):
// Base
public abstract class Attack : MonoBehaviour
{
public virtual void AttackFinished()
{
Entity.StateController.SwitchToState<IdleState>();
}
}
// Child
public class PlayerSwordAttack : Attack
{
// I want this implementation to be required, not optional
// while having it still do the stuff it does in base
public override void AttackFinished()
{
base.AttackFinished();
// Extra stuff
}
}
In this case, I want PlayerSwordAttack or any other child classes to require implementing AttackFinished() without it being abstract.
Tl;dr: Essentially I want public abstract virtual void AttackFinished() which isn't possible as far as I know, but I hope to learn of a way to do it.
Given that I haven't found this question posted here or anywhere else, I'm expecting the answer to be "don't be silly, it's impossible" but thought I'd ask, since a friend of mine has had the same question.
Just break it down into two methods. One is non-virtual, non-abstract, so is not overridable. This will call the abstract method that derived classes are forced to implement.
public abstract class Attack
{
public void AttackFinished()
{
Entity.StateController.SwitchToState<IdleState>();
OnAttackFinished();
}
protected abstract void OnAttackFinished();
}
public class PlayerSwordAttack : Attack
{
protected override void OnAttackFinished()
{
// Extra stuff
}
}
Note that this is like forcing base.AttackFinished in your original code to be called in the derived classes' implementations. If you want derived classes to opt out of this, you can add an additional property:
public abstract class Attack
{
public void AttackFinished()
{
if (ShouldChangeStateAfterAttack) {
Entity.StateController.SwitchToState<IdleState>();
}
OnAttackFinished();
}
protected abstract void OnAttackFinished();
// could also be virtual instead to provide a default implementation
protected abstract bool ShouldChangeStateAfterAttack { get; }
}
public class PlayerSwordAttack : Attack
{
protected override void OnAttackFinished()
{
// Extra stuff
}
protected override bool ShouldChangeStateAfterAttack => false;
}
base.AttackFinished in your original code could also be called independently, from anywhere in the derived class. If you also want that, simply extract the line Entity.StateController.SwitchToState<IdleState>(); as another method.

Inherit from a base class and provide the inheritance type to overridden method

I have a base class with a method that can be overridden. If I inherit a class from this base class how can I make the method return the inherited type?
Like:
public class ClassA : BaseClass
{
public override ClassA TestMethod(...)
{
// ...
}
}
Do I need to provide a type manually to the base class ? Or can I make it provide that type automatically?
You could use a generic type to do it.
public class BaseClass<T> where T : BaseClass<T> {
public abstract T TestMethod(...);
}
public class ClassA : BaseClass<ClassA>
{
public override ClassA TestMethod(...)
{
// ...
}
}
Why do you need it? Might lead to better suiting answers...
The feature you want has a name; this is return type covariance.
The reasons it is not supported in C# are here:
Why C# doesn't allow inheritance of return type when implementing an Interface
The other answers are all suggesting that you use the C# version of the curiously recurring template pattern to solve your problem. My opinion is that the pattern makes more problems than it solves. See my article on that subject for more details:
http://blogs.msdn.com/b/ericlippert/archive/2011/02/03/curiouser-and-curiouser.aspx
A better way to solve this problem is to use this pattern:
abstract class Animal
{
protected abstract Animal ProtectedGetMother();
public Animal GetMother()
{
return this.ProtectedGetMother();
}
}
class Cat : Animal
{
protected override Animal ProtectedGetMother()
{
do the work particular to cats here
make sure you return a Cat
}
public new Cat GetMother()
{
return (Cat)this.ProtectedGetMother();
}
}
The problem is that you cannot override a virtual method with a different return type. So don't. Make a brand new method with a different return type and make the virtual method an implementation detail of the class hierarchy.
This technique is approximately one billion times easier to understand than this Cat : Animal<Cat> "a cat is an animal of cat" nonsense.
You can do this in a generic way:
public abstract class Base
{
public abstract T AbstractTestMethod<T>() where T : Base;
public virtual T VirtualTestMethod<T>() where T : Base, new()
{
return new T();
}
}
public class ClassA : Base
{
public override ClassA AbstractTestMethod<ClassA>()
{
return new ClassA();
}
public override ClassA VirtualTestMethod<ClassA>()
{
return new ClassA();
}
}
Using virtual methods behaves not as strict as using abstract methods. Using the abstract way you can force developers to implement the method on their own. Using the virtual way you can tell them something like "meet my constraints and feel free to use the default behaviour".

Reimplementation of inherited interface methods

I did not fully understand using Interfaces, so I have to ask :-)
I use a BaseClass, which implements the IBaseClass interface.These interface only contains one declaration :
public interface IBaseClass
{
void Refresh ();
}
So I have implement a Refresh method in my Baseclass :
public void Refresh ()
{
Console.WriteLine("Refresh");
}
Now I want to use some classes which extends from these Baseclass and implements the IBaseClass interface :
public class ChildClass : BaseClass,IBaseClass
{
}
But cause of the implementation of "Refresh" into my BaseClass I does not have to implement the method again. What should I do, to force the implementation of "Refresh" into all childs of BaseClass as well as all childclasses of childclass.
Thanks kooki
You cannot force derived classes to re-implement the method in the way that you have specified. You have three options:
Do not define refresh in the base class. The interface will force child classes to implement it.
Eschew the interface if its only purpose was to force implementation and declare the base class as abstract as well as refresh, for which you would not give an implementation.
Define refresh in the base class as virtual. This allows overrides but will not force them. This is how ToString() works.
This is all assuming that your base class is larger than a single method. If indeed your code is exactly what you posted then Oded's answer is the best choice.
Simple. Don't supply a base class implementation, and you will have to implement the method in every inheriting class.
One way to achieve that is to make BaseClass abstract:
public abstract BaseClass : IBaseClass
{
public abstract void Refresh();
}
What should I do, to force the implementation of "Refresh" into all childs of BaseClass as well as all childclasses of childclass.
Like this:
interface IBase
{
void Refresh();
}
abstract class BaseClass : IBase
{
public abstract void Refresh();
}
class ChildClass : BaseClass
{
public override void Refresh()
{
// Your code
}
}
You can even omit the interface (my rule of thumb: if an interface gets implemented by exactly one class, dump the interface. Don't cling on to interfacitis. An abstract class quite much represents an interface, see also Interface vs Abstract Class (general OO)).
If you do need an implementation in the base class, build it as such:
(abstract) class BaseClass ( : IBase)
{
public virtual void Refresh()
{
// Your code
}
}
Which you can then call from your derived classes:
public override void Refresh()
{
// Your code
// optionally, to call the base implementation:
base.Refresh();
}
If you want to supply a default implementation, do it in your base class by marking it as virtual, so you can override that implementation in subclasses if you want.
Otherwise mark the method as abstract in your base class, so your subclasses are forced to implement the method themselves.
Lets take a look at this step-by-step.
1: You have an interface which defines your code contract defined like so:
public interface IBase
{
void Refresh();
}
2: You have a base class which implements your interface. (you will notice that the implementation for refresh is virtual. This allows you to override this method in derived classes).
class Base : IBase
{
public virtual void Refresh()
{
//Implementation
}
}
3: You have a super class which derives from Base. (you will notice that the derived class does not need to explicitly implement IBase as it's done at a lower level. I'll show you that you can test the integrity of this).
class Child : Base
{
public override void Refresh()
{
base.Refresh(); //You can call this here if you need to perform the super objects Refresh() before yor own.
//Add your implementation here.
}
}
At this point you might be thinking; "Ok, well then how is Child implementing IBase?". The answer is that it is implemented indirectly through Base, and because Child inherits Base, it also gets the implementation for IBase.
Therefore if you were to write:
IBase instance = new Child();
This is perfectly legal because essentially, Child derives from IBase indirectly.
If you wanted to test this, you can do this in your code:
bool canAssign = typeof(IBase).IsAssignableFrom(typeof(Child));
//canAssign should be true as Child can be assigned from IBase.
May be New Keyword can help u in that;
namespace ConsoleApplication1
{
interface IBase
{
void Referesh();
}
public class Base1 : IBase
{
public void Referesh()
{
Console.WriteLine("Hi");
}
}
public class Class1 : Base1, IBase
{
public new void Referesh()
{
Console.WriteLine("Bye");
}
}
class Program
{
static void Main(string[] args)
{
Class1 obj = new Class1();
obj.Referesh();
Console.ReadKey();
}
}
}

Why does overriding a method only occur after I implement an interface?

I've been reading through the book Working Effectively with Legacy Code and I've been playing around with the concept of overriding difficult to test methods in unit tests via the creation of a fake. I put together an example of what I thought would work and it ended up behaving differently than I had been expecting. I think I've just discovered a hole in my understanding of how inheritance and method overloading works in C# and I was wondering if someone could help me understand what's going on here.
I've got the following interface:
public interface IAnimal
{
void MakeSound();
void Move();
}
I then create an implementation of the animal interface as follows:
public class Dog : IAnimal
{
public void MakeSound()
{
Console.WriteLine("Woof");
}
public void Move()
{
Console.WriteLine("Moved");
}
}
When I use this class as follows:
IAnimal myanimal = new Dog();
myanimal.MakeSound();
myanimal.Move();
I get the following output:
Woof
Moved
Now, lets pretend that I'm needing to unit test the Dog class but one of the methods, MakeSound(), needs to be overridden because it is making the class difficult to test for some reason.
I create a fake dog by extending the Dog class and creating a method for MakeSound
public class FakeDog : Dog
{
public void MakeSound()
{
Console.WriteLine("Bark");
}
}
When I use this class as follows:
IAnimal myanimal = new FakeDog();
myanimal.MakeSound();
myanimal.Move();
I get the following output:
Woof
Moved
I had been expecting it to have been:
Bark
Moved
However, if I then have the FakeDog class implement the animal interface and use it:
public class FakeDog : Dog, IAnimal
{
public void MakeSound()
{
Console.WriteLine("Bark");
}
}
I get the following output:
Bark
Moved
I'm just wanting to understand the reason why this now overrides the method as I had been expecting when I had just been extended the Dog class. Can anyone set me straight on this?
In the first case you're creating a new method which hides the original implementation of IAnimal.MakeSound. You should have seen a warning suggesting that you use the new keyword to make this explicit.
In the second case you're re-implementing IAnimal. Implementing an interface doesn't require the override keyword (although it might have been nice if the language designers had required that).
To avoid re-implementing the interface, you could make MakeSound virtual in Dog, and then explicitly override it in FakeDog. At that point there's only one possible resolution involved, and everything is simpler to understand. I try to avoid reimplementation and method hiding whenever possible.
(Sorry for answering with a question, but you might genuinely find this experiment informative) What happens when you implement dog as follows:
public class Dog : IAnimal
{
public virtual void MakeSound()
{
Console.WriteLine("Woof");
}
//...
Note the "virtual"
You need to declare the MakeSound method as virtual in the Dog class and override it in the FakeDog class:
public class Dog : IAnimal
{
public virtual void MakeSound()
{
Console.WriteLine("Woof");
}
public virtual void Move()
{
Console.WriteLine("Moved");
}
}
public class FakeDog : Dog
{
public override void MakeSound()
{
Console.WriteLine("Bark");
}
}

Writing a generic API for a type 'family'

I'm working with a smallish type hierarchy, something like the following, and lets say there won't ever be any other Animal types in my sad safari-less world (I'm not at all worried about resilience to expanding):
public abstract class Animal {};
public sealed class Dog : Animal {};
public sealed class Cat : Animal {};
public sealed class Turtle : Animal {};
public sealed class Bird : Animal {};
I'd like to treat all of the animals similarly as far as the API is concerned, but obviously they respond just a little differently in the below situations:
public class AnimalCare {
public void Feed<T> (T pet) where T: Animal;
public T PickUp<T> (PetStore store);
}
At first blush the idea of performing feedings without putting a feed method on the Animal class (sorry, I know the example is reaching at this point, but lets pretend for the sake of argument that AnimalCare is the view to my Animal models and I'm pretty adamant about separation of concerns) would suggest a visitor. But what I would really like to do is let the above be the only sort of API consumers of AnimalCare need to worry about, while I do something like the following:
public class AnimalCare {
public void Feed<T> (T pet) where T : Animal;
public T PickUp<T> (PetStore store);
public void Feed<Dog> (Dog rover)
{
// dump out alpo, lift toilet seat
}
public void Feed<Turtle> (Turtle franklin)
{
// do turtles eat? let him figure it out himself.
} // ...etc.
public Dog PickUp<Dog> (PetStore store)
{
// get bone, tennis ball, leash
}
public Bird PickUp<Bird> (PetStore store)
{
// make sure not dead, nailed to perch
} // ...etc.
}
And so on. I know the first part (the Feed () methods) are fine to just overload without even needing generics, but that still leaves me with an awkward implementation for PickUp (since its not legal to implement as I've sketched it above), something miserable like PickUpDog//PickUpBird etc. I would very much like to avoid having a separate "view" for consumers of AnimalCare and its like-minded friends to have to be concerned with.
I've been playing around with nesting specialized classes and other bizarre attempts at composition or interface refactoring, but I can't seem to get it right and I'm stuck. Is there a clean way to do something like what I want, or am I resigned to implementing an AnimalCare for each concrete Animal?
EDIT
Joel's point about factory/repository made me think some more. Let's instead call the methods of interest a little more reasonable:
public class AnimalPresentation {
public void Show (Dog dog);
public void Show (Cat cat);
//..etc.
public Animal Get (PetStore store);
}
That would have made more sense in the first place I suppose. The type of Animal to be gotten out of PetStore isn't known at the time Get is called, but in the general implementation of Get, once the type is determined, it branches to the specific overload. Is specific subtypes of PetStore the best/only way forward here?
I think the problem with AnimalCare is that it is essentially a factory for Animal instances, or at least access to an Animal repository. So maybe your PickUp function should return an Animal object instead of a specific type.
Alternatively, could you not base AnimalCare on a specific type (AnimalCare<T>) ? The example is little hard to gauge in terms of actual intention, so apologies if these ideas don't seem to hit the mark.
edit
You might consider something like this:
First you have an interface IAnimal with your animals on there. They don't know about any methods. Then create a new interface like
interface IAnimalCareClient<T>
{
void Init(T animal);
void Feed();
T Pickup(PetStore store);
}
Then create clients for every animal type like
class DogClient : IAnimalCareClient<Dog>
{
void Init(Dog animal) { //bla }
void Feed() {}
Dog Pickup(PetStore store) { //bla again }
}
Your clients should then be stored in some list, and the types can reside in various dll's etc. You just need to grab a reference.
Then just
class AnimalCare
{
void Feed<T>(T animal)
{
//GrabWorkerFromStack<T>() should return the type IAnimalCareClient<T>
IAnimalCareClient<T> worker = Activator.CreateInstance(GrabWorkerFromStack<T>());
worker.Init(animal);
worker.Feed();
}
}
original answer
Basically you want to lay the responsibility at the animal itself, as you cannot force your AnimalCare class to implement all properties for all animals. Then becomes something simple like:
interface IAnimal
{
void Feed();
IAnimal Pickup(PetStore store);
}
class Dog : IAnimal
{
void Feed() { /* feed */ }
IAnimal Pickup(PetStore store) { /* grab animal and return */ }
}
class AnimalCare
{
void Feed(IAnimal animal)
{
animal.Feed();
}
T Pickup<T>(T animal, PetStore store) where T: IAnimal
{
return (T)animal.Pickup(store);
}
}
You can use interfaces, I don't know what specific requirements there is, but if an animal may have one trait that might be shared with other animals, but doesn't have to an interface is a good start.
For example:
interface IFeedable
{
void Feed();
}
interface IMammal<TChild>
where TChild: IMammal<TChild>
{
IEnumerable<TChild> Reproduce();
}
class Dog: IFeedable, IMammal<Puppy>
{
// ...
}
I use interfaces all the time (probably overusing them), especially in a case as this were normal inheritance might not be the best way.

Categories