In the following example code, I want every car
object to be composed of brake_system
and engine_system
objects, which are stored as attributes on the car.
To implement this, I've defined Car
, BreakSystem
and EngineSystem
as abstract classes. Every subclass of Car
is required to define its respective BreakSystem
and EngineSystem
subclasses as class attributes.
Are there any potential problems with this approach? Or are there other design patterns better suited to handle nested abstractions?
from abc import ABC, abstractmethod
class Car(ABC):
"""
every car object should have an Engine object and a BrakeSystem object
"""
def __init__(self):
self.engine_system = self._engine_type()
self.brake_system = self._brake_type()
@property
@abstractmethod
def _engine_type(self):
raise NotImplementedError()
@property
@abstractmethod
def _brake_type(self):
raise NotImplementedError()
class EngineSystem(ABC):
pass
class BrakeSystem(ABC):
pass
class FooBrakeSystem(BrakeSystem):
pass
class FooEngineSystem(EngineSystem):
pass
class FooCar(Car):
_engine_type = FooEngineSystem
_brake_type = FooBrakeSystem
if __name__ == '__main__':
obj = FooCar()
It does not matter whether your class is abstract or concrete, as long as the nested class is either public , protected or the subclass is in the same package and the inner class is package private (default access modifier), the subclass will have access to it.
You can have more than one inner class in a class. As we defined earlier, it's easy to implement multiple inner classes. class Outer: """Outer Class""" def __init__(self): ## Instantiating the 'Inner' class self.
Nested Class can be used whenever you want to create more than once instance of the class or whenever you want to make that type more available. Nested Class increases the encapsulations as well as it will lead to more readable and maintainable code.
You can only inherit the implementation of one class by directly deriving from it. You can implement multiple interfaces, but you can't inherit the implementation of multiple classes.
I want every car object to be composed of
brake_system
andengine_system
objects
You have abstract classes for the systems
class EngineSystem(ABC):
pass
class BrakeSystem(ABC):
pass
A car has to consists of two systems:
class Car:
def __init__(self, engine: EngineSystem, brake: BrakeSystem):
self._engine_system = engine
self._brake_system = brake
@property
def engine_type(self) -> EngineSystem:
return self._engine_system
@property
def brake_type(self) -> BrakeSystem:
return self._engine_system
And now, if you need to create a specific car
tesla = Car(ElectroEngine(), Disks())
# or even
class Tesla(Car):
def __init__(self):
super().__init__(ElectroEngine(), Disks())
tesla = Tesla()
This approach allows you to create a car
as a composition of its systems.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With