Best way to create classes that only differ by one method?

Question:

I am implementing multiple RL agents which share a lot of common attributes and methods but differ in only one. Namely the one that calculates the td_error. Out of the top of my head I can think of 3 options to implement this:

  1. Use an Agent abstract class (ABCMeta) and let the subclasses each implement all their methods.
  2. Use a normal base class Agent, implement all the common methods and just do pass on the one that is specific to each subclass.
  3. Use just one class Agent and use an attribute to specify the type of td_error to calculate and then just use if else to achieve the specific behavior.

Here is what I don’t like about each option:

  1. It seems I would need to repeat myself when implementing the common methods in each subclass.
  2. It would be possible to create instances of the base class Agent but it wouldn’t work since the specific function is not defined.
  3. It is ugly and seems very naive.

I have been presented with this situation before and I normally go with option 2. but I am pretty sure there is a more correct way of achieving this.

Asked By: Samuel Rodríguez

||

Answers:

You most definitely do not have to repeat yourself with Abstract class. If you define methods without decorating them as abstract, they will work just fine and can be used in child classes.

from abc import ABC, abstractmethod
 
class Polygon(ABC):
    
    def amPolygon(self):
        print("I am polygon")

    @abstractmethod
    def noofsides(self):
        raise NotImplementedError
 
class Triangle(Polygon):
 
    # overriding abstract method
    def noofsides(self):
        print("I have 3 sides")
 
class Pentagon(Polygon):
 
    # overriding abstract method
    def noofsides(self):
        print("I have 5 sides")

R = Pentagon()
R.amPolygon()
Answered By: matszwecja