How to abstract/remove redundent methods in the following class sample - c#

I'm trying to remove the redundancy I have in my Enemy0, Enemy1, ... classes that inherit from my abstract Enemy class. This is all Monogame/XNA.
My abstract class looks like so:
public abstract class Enemy
{
public abstract Vector2 Position { get; }
public Enemy() {}
public abstract void Update(GameTime gameTime);
public abstract void Draw(SpriteBatch spriteBatch);
public abstract Part getLeftPart();
public abstract Part getRightPart();
public abstract Part getLeftLeftPart(); //This method only used in Boss0 classes
public abstract Part getRightRightPart(); //This method only used in Boss0 classes
}
Though my Enemy# classes vary in implementation, some methods are exactly the same/redundant and take up room (but have parameters relative to that class, eg the private variable _leftPartPos).
The problem occurs when I have 20 or so Enemy# classes and I decide to add an extra parameter to the Part object (which is used in getLeftPart()- I would have to also modify 20 of those classes that inherit the Enemy
public class Enemy0 : Enemy
{
private Texture2D _partTexture;
private Vector2 _leftpartPos;
private Vector2 _rightPartPos;
public override Vector2 Position
{
get { return _position; } // Reason for this get is to access inner variables
} // like _position.X = 10
private Vector2 _position;
public Enemy() {}
public abstract void Update(GameTime gameTime)
{
// Some varying functionality per inheriting class
}
public abstract void Draw(SpriteBatch spriteBatch)
{
// Some varying functionality per inheriting class
}
public override Part getLeftPart() // This always returns the same object (with
{ // different params)
return new Part(
_partTexture,
_leftPartPos,
SpriteEffects.FlipHorizontally);
}
public abstract Part getRightPart()
{
return new Part(
_partTexture,
_rightPartPos,
SpriteEffects.None);
}
public override Part getLeftLeftPart()
{
return null; // This only returns an instance in Boss0, Boss1, etc
}
public override Part getRightRightPart()
{
return null;
}
}
The reason I have this abstract class is so that I can initialize a List<Enemy> object and access its varied methods without having to cast each class as Enemy0, Enemy1, ...
Is there a way I can throw in the functionality of getLeftPart(), getRightPart(), ... into my abstract class? Is there a better approach for all this?

Declare them as virtual instead of abstract. That way you can provide a base implementation in the root class and override it in the child classes if they require different functionality.
public abstract class RootClass
{
public virtual void DoSomething()
{
Console.WriteLine("I'm doing something in the root class");
}
}
public class ChildClass1 : RootClass
{
public void SomethingElse()
{
DoSomething(); //Prints out "I'm doing something in the root class"
}
}
public class ChildClass2 : RootClass
{
public void SomethingElse()
{
DoSomething(); //Prints out "I'm doing something in ChildClass2
}
public override void DoSomething()
{
Console.WriteLine("I'm doing something in ChildClass2");
}
}
If you have to take variable numbers of parameters, declare the method with the params attribute, like:
public virtual void DoSomething(params object[] args)
This causes boxing, so be aware of the performance implications. If you need to do something more specific, try:
public virtual void DoSomething<T>(params T[] args)
But the only difference here is that all the parameters must be of the same type, or convertible to that type. If you only need one parameter of some type, use:
public virtual void DoSomething<T>(T arg)
or you can have two (or more types)
public virtual void DoSomething<T1, T2>(T1 arg1, T2 arg2)
etc, etc.

Related

Dependency injection with abstract class in .NET Core

I don't know how to use a dependency injection in an abstract class. Let me show you my problem in a simple example:
public abstract class Animal {
public abstract void Move();
public void Sleep()
{
restService.StartSleeping(1000); //how to get this service here?
}
}
public class Cat : Animal
{
public readonly IMotionService _motionService;
public Cat(IMotionService motionService)
{
_motionService = motionService;
}
public override void Move()
{
_motionService.Run();
}
}
public class Bird : Animal
{
public readonly IMotionService _motionService;
public Bird(IMotionService motionService)
{
_motionService = motionService;
}
public override void Move()
{
_motionService.Fly();
}
}
Every animal move in different way so the Move() function is implemented separately in every derived class. As you probably noticed the whole implementation comes from the motionService.
On the other hand all animals sleep in same way, so I want put the Sleep() implementation in a base abstract class to avoid a duplication code, but I can't use my restService with a Sleep implementation because I don't have idea how to inject a service class into an abstract class.
I thought about IServiceProvider but it should be injected too.
You pass it down like this:
public abstract class Animal
{
private readonly IRestService restService;
public Animal( IRestService restService )
{
this.restService = restService;
}
public abstract void Move();
public void Sleep()
{
restService.StartSleeping(1000);
}
}
public class Cat : Animal
{
// vv Should be private!
public readonly IMotionService _motionService;
public Cat(IMotionService motionService,
IRestService restService)
: base(restService) // pass on to base class ctor
{
_motionService = motionService;
}
public override void Move()
{
_motionService.Run();
}
}
// Same in `Bird` class
For reference: Using Constructors (C# Programming Guide)

Protected abstract or public abstract method in abstract class

Hi I have an abstract class in which I have some public methods and some abstract ones.
I have the public so that they implement the common methods for the derived classes.
What is confusing me is why I will want to define a public abstract method instead of protected abstract. That makes no sense to me to define a public abstract method in abstract class.... because if is an abstract will be overridden, in the derived classes, but the same is if is defined as public but somehow it makes more sense to define it as protected as we know that we will override that in the derived classes.
Is it wrong to define the method as public abstract in an abstract class? Which is better and why?
It depends on what you want to achieve. For example, you have a Television class that has 3 methods, TurnOn, TurnOff, and Draw.
You only want clients to TurnOn or TurnOff the TV but only its subclass should know what and how to Draw on the screen. So, Television will look more or less like below.
public abstract class Television
{
public abstract void TurnOn();
public abstract void TurnOff();
protected abstract void Draw();
}
Then each company has its own implementation.
public sealed class MyTelevision
: Television
{
public override void TurnOn()
{
Console.WriteLine("Turn on my tv");
}
public override void TurnOff()
{
Console.WriteLine("Turn off my tv");
}
protected override void Draw()
{
// code here.
}
}
Clients can TurnOn or TurnOff a TV but cannot Draw anything on the screen.
For the same reason you want a public method in an object :)
You just don't know the particular implementation at this stage.
It is common in classes with very high level of abstraction, middlewares for example.
Edit: It is 100% legal. You just need to be sure that it is functionality that you want to expose to the rest of the world in every concrete implementation. Entry point methods (ex: start, execute, parse..) are usually of this kind.
The Abstract Class itself has to be as accessible as the Classes, which inherit from it. So if the inherited Classes are Public, the Abstract Class has to be public too.
Public Abstract has the same Idea like other Public Methods: If you have a Abstract Class, you will pass this arround. So if this Method should get called from outside, it's public. If the method is just for communication between Child and Parent, protected is the way to go. Easy example, see the Main-Method as the user of the abstract class:
static void Main(string[] args)
{
Animal cat = new Cat();
Animal dog = new Dog();
cat.Eat();
dog.Eat();
cat.Move();
dog.Move();
}
public abstract class Animal
{
public abstract void Eat();
protected abstract void ComplexMoving();
public void Move()
{
ComplexMoving();
}
}
public class Dog : Animal
{
public override void Eat()
{
Debug.WriteLine("Dog says Namnam");
}
protected override void ComplexMoving()
{
Debug.WriteLine("Dog no stupid");
}
}
public class Cat: Animal
{
public override void Eat()
{
Debug.WriteLine("Cat says namnam");
}
protected override void ComplexMoving()
{
Debug.WriteLine("Cat does a slalom");
}
}
TLTR: because of Open-Close principle.
Why it makes sense to have abstract members protected instead of public is, from what I can see, to hide "implementation details". It is convenient to expose one single "entry point" if you want to ensure that the intent of which each abstract member is defined inside the class is preserved. Normally, it is the public method which will orchestrate when and what abstract members are called or accessed and in what particular order and under what circumstances, but the tradeoff for this layer of encapsulation is that you lose the extensibility property.
Explanation:
Suppose we create a library with multiple exception handler classes.
Initial implementation:
namespace MyLibrary;
public abstract class ExceptionHandlerBase
{
protected abstract void HandleException(Exception ex, Action operation);
public void Execute(Action operation)
{
try {
operation.Invoke();
} catch(Exception ex) {
this.HandleException(ex, operation);
}
}
}
public class InputExceptionHandler: ExceptionHandlerBase
{
protected override void HandleException(Exception ex, Action operation)
{
throw new Exception(
message: "Wrong input" // or whatever...
inner: ex);
}
}
public class DbExceptionHandler : ExceptionHandlerBase
{
protected override void HandleException(Exception ex, Action operation)
{
Console.WriteLine("Failed to connect to database. Retrying...");
operation.Invoke();
}
}
Now, if we want to extend the behavior of ExceptionHandlerBase we will see that we are limited because of that protected access modifier of ExceptionHandlerBase.HandleException method.
Let's try to add a hook before ExceptionHandlerBase.HandleException method:
class ExceptionHandlerWrapper : ExceptionHandlerBase
{
readonly ExceptionHandlerBase _base;
public ExceptionHandlerWrapper(ExceptionHandlerBase #base)
{
thos._base = #base;
}
protected override void HandleException(Exception ex, Action operation)
{
this.BeforeHandleException();
this._base.HandleException(ex, operation); // Compile error**
}
private void BeforeHandleException()
{
// do additional stuff
}
}
As you can see, there is a compilation error because ExceptionHandlerBase.HandleException is not accessible from outside the class that defines it.

Define base class constructor methods in derived classes

I am trying to create a comprehensive abstract BaseClass that defines the way in which all derived classes are created, but allows derived classes to specialize/aggregate the fields and methods used in the creation process. Here is a simplified example:
public abstract class BaseClass
{
public List<String> list;
public BaseClass()
{
defineList();
optionalDoSomething();
doSomething();
}
protected void defineList()
{
list = new List<String>();
}
protected void doSomething()
{
// do something w/ list here
}
protected void optionalDoSomething() {}
}
public class DerivedClass : BaseClass
{
protected void defineList()
{
base.defineList();
list.Add("something");
}
public DerivedClass() : base() { }
}
public class SecondDerivedClass : DerivedClass
{
protected void defineList()
{
base.defineList();
list.Add("somethingElse");
}
protected void optionalDoSomething()
{
// do something special
}
public SecondDerivedClass() : base() { }
}
This would free all derived classes from having to recreate the same initialization logic, and each derived class would only need to "overwrite" the necessary fields and methods used in the create process (and possibly elsewhere in the class).
The problem:
I cannot mark BaseClass' methods as virtual since you cannot call virtual methods in a base constructor (in any case, I would not want to use virtual methods since, for example, I would not want DerivedClass to use SecondDerivedClass' defineList method).
I can mark them abstract, but then I would not be able to put "default implementations" in BaseClass and each derived class would have to replicate/implement those defaults. Also, SecondDerived class would still need a way to "override" the implementations of DerivedClass.
It does not work to simply use the new key word "hide" less derived class' methods.
What is the correct way to obtain this pattern?
TLDR: as per my comment below:
If BaseClass is an abstract class with method A, and DerivedClass is a class derived from BaseClass (not necessarily a direct child of BaseClass), then calling A in BaseClass' constructor should call A() in every class in the inheritance hierarchy up to and including DerivedClass (but no further). We can assume that A (forced to be) defined on every intermediate class.
I think that you should refer to template-method-design-pattern
Define the skeleton of an algorithm in an operation, deferring some
steps to subclasses. Template Method lets subclasses redefine certain
steps of an algorithm without changing the algorithm's structure.
you can try something similar to this
abstract class AbstractClass
{
public List<String> list;
public abstract void PrimitiveOperation1();
public void TemplateMethod()
{
//initialize code that each class should perform
PrimitiveOperation1();
}
}
class DerivedClass: AbstractClass
{
public override void PrimitiveOperation1()
{
list.Add("something");
}
}
usage
AbstractClass abstractClass1 = new DerivedClass();
abstractClass1.TemplateMethod();
Try this solution, the implementation is implemented with protected virtual methods, so its not visible from the outside and not required in derived classes:
public abstract class BaseClass
{
public List<String> List { get; protected set; }
protected BaseClass()
{
defineList();
optionalDoSomething();
doSomething();
}
protected void defineList()
{
// default implementation here
List = new List<String>();
internalDefineList();
}
protected void doSomething()
{
// default implementation here
internalDoSomething();
}
protected void optionalDoSomething()
{
// default implementation here
internalOptionalSomething();
}
protected virtual void internalDefineList()
{
}
protected virtual void internalDoSomething()
{
}
protected virtual void internalOptionalSomething()
{
}
}
public class DerivedClass : BaseClass
{
protected override void internalDefineList()
{
var list = List;
}
protected override void internalDoSomething()
{
}
// this method is not required
/*
protected override void internalOptionalSomething()
{
}
*/
}
One way to achieve what you want is to add an explicit Initialize method to the base class and do the initializaiton logic there, e.g:
public abstract class BaseClass
{
public List<String> list;
public BaseClass()
{
}
public void Initialize()
{
defineList();
optionalDoSomething();
doSomething();
}
}

How to call a common function in a class instance? [duplicate]

This question already has answers here:
Return one of two possible objects of different types sharing a method
(6 answers)
Closed 8 years ago.
Let's say i have two classes:
class Batman
{
public void Robin(){...}
public void Jump(){...}
}
class Superman
{
public void Kryptonie(){...}
public void Jump(){...}
}
Now, I have an instance of those classes:
public object Crossover()
{
var batman = new Batman();
var superman = new Superman();
return superman;
}
I do not know instance of which class the Crossover will return, it could be Batman or Superman.
var someVariableName = Crossover(); //I don't know if this contains an instance of Superman or Batman;
//I do know that no matter which class instance is returned, it will always contain a function named Jump which i want to trigger:
someVariableName.Jump();
Now i know i could do something like:
if (someVariableName.GetType() == typeof(Superman))
{
((Superman) someVariableName).Jump()
}
But is there a way to trigger the Jump function without having to manually check for each type with if..else.., when i know that the instance of the class saved in that variable will always contain a Jump function?
Use an interface:
interface ISuperHero
{
void Jump();
}
class Batman : ISuperHero
{
public void Robin(){...}
public void Jump(){...}
}
class Superman : ISuperHero
{
public void Kryptonie(){...}
public void Jump(){...}
}
Then return the interface from your method:
public ISuperHero Crossover()
This is where interfaces become useful. Consider this interface:
public interface ISuperhero
{
void Jump();
}
And these implementations:
class Batman : ISuperhero
{
public void Robin(){...}
public void Jump(){...}
}
class Superman : ISuperhero
{
public void Kryptonie(){...}
public void Jump(){...}
}
They're individual implementations, but they share a common polymorphic interface. Your function can then return that interface:
public ISuperhero Crossover()
{
var batman = new Batman();
var superman = new Superman();
return superman;
}
Since that interface has a Jump() method, it can be called directly:
var someVariableName = Crossover();
someVariableName.Jump();
You could create a base class defining the method (or an interface, if it is just about the method definition). You can override the implementation in the deriving classes then.
abstract class ActionFigure
{
public abstract void Jump(); // just define it has a Jump method, but implement it in the deriving class
public void SomethingGeneral()
{
// no need for an override, just implement it here
}
}
class Batman : ActionFigure
{
public void Robin(){...}
public override void Jump(){...}
}
class Superman : ActionFigure
{
public void Kryptonie(){...}
public override void Jump(){...}
}

Template method pattern without inheritance

How can a variant of the Template Method pattern be implemented whereby the concrete class does not inherit from the base class, but the overall feature of the pattern is maintained. The reason it cannot inherit is that it's forced to inherit from another class and multiple-inheritance is unavailable.
For example, suppose the following Tempate Method pattern:
public abstract class BaseClass {
public void Alpha() {
Beta();
}
public abstract void Beta();
public void Gamma() {
Delta();
}
public abstract void Delta();
}
public ConcreteClass : BaseClass {
public override void Beta() {
Gamma();
}
public override void Delta() {
Console.WriteLine("Delta");
}
}
...
var object = new ConcreteClass();
object.Alpha(); // will outout "Delta"
How can I achieve the same result without ConcreteClass inheriting BaseClass?
Your base class could depend on an interface (or other type) that's injected via the constructor. Your template method(s) could then use the methods on this interface/type to achieve the pattern's desired outcome:
public class BaseClass
{
IDependent _dependent;
public BaseClass(IDependent dependent)
{
_dependent = dependent;
}
public void Alpha() {
_depdendent.Beta();
}
public void Gamma() {
_depdendent.Delta();
}
}
Effectively using composition rather than inheritance.
You can achieve this by providing a reference to the base class on method call:
public ConcreteClass {
public void Beta(BaseClass baseClass) {
baseClass.Gamma();
}
public void Delta() {
Console.WriteLine("Delta");
}
}

Categories

Resources