Reputation: 43
Need some help to solve this puzzle folks:
When creating a child class in Python and defining the init method, I would like to import all the attributes of the super/parent class except certain positional parameters and certain parameters (which are not defined inside parent classes' init method's list of positional or keyworded/non-keworded parameters but) defined within/inside the parent class init method with a default value.
Is there a way to prevent/avoid certain/specific parent class attributes to be imported in the child class upon initiation? I am aware that we can override methods in the child class which do not mimic parent class behaviors, but I am not aware how to do the same with attributes, so I was thinking if I could avoid them completely!
I will give an example of why I need a certain child class to mimic everything from its parent except certain attribute.
Consider a parent class "Car". The child class will be "ElectricCar". The parent class has an attribute defined called "liters_gasoline" with certain integer as its default value.
Now, I would like to inherit everything in the ElectricCar sub-class except that "liters_gasoline" parameter, because ElectricCars don't use fuel/gasoline. How to prevent this "liters_gasoline" parameter from being inherited in the child class? I don't want this parameter in child class!
How to do this?
Upvotes: 4
Views: 3859
Reputation: 1
One of the solutions that I found is.. like I don't know it is accurate or not.. but it works. eg. you have
class Person:
def __init__(self, name, age, height):
self.name = name
self.age = age
self.height = height
class Dog(Person):
def __init__(self, name, age, color, owner):
super().__init__(name, age, 0)
self.color = color
self.owner = owner
Upvotes: 0
Reputation: 1
If something inherits from a parent class it should have all the attributes of the parent class.
Upvotes: 0
Reputation: 10699
You are violating at least 2 principles there:
1. Interface segregation principle - fat interfaces
If you decide to define liters_gasoline
within the base class Car
, remember that:
no client should be forced to depend on methods it does not use.
Your plan is basically an example on how to contradict this rule. You are designing a fat interface, where your base class Car
requires you to have the liters_gasoline
and then later on, your subclass ElectricCar
doesn't need it as it shouldn't be part of its characteristics.
when an interface incorporates too many operations on some data into an interface, only to find that most of the objects cannot perform the given operations.
In analogy, I believe one of the more commonly known examples of this is designing a base class Bird
with the functionality of fly
which of course works for a subclass Eagle
but not for a subclass Penguin
.
2. Liskov substitution principle
If you decide to delete liters_gasoline
within the subclass ElectricCar
, remember that:
if S is a subtype of T, then objects of type T may be replaced with objects of type S (i.e., an object of type T may be substituted with any object of a subtype S) without altering any of the desirable properties of the program
Since you deleted the property liters_gasoline
of S (ElectricCar
), are you confident that it could still replace all objects of type T (Car
). The answer is no. Why?
Let's say I'm performing the following:
print(T.liters_gasoline)
And I substitute S to that T:
print(S.liters_gasoline) # Error, attribute doesn't exist.
Which means that your subtype S (ElectricCar
) can't anymore be substituted to all types of T (Car
).
As @joey mentioned, redesign your interface (base class Car
) to only include properties that are common for all types of Car
.
Should there be any unavoidable instances where your subclass doesn't need a particular attribute of the base class (most of the time is a clue that you have a fat interface), you can choose to just nullify its value e.g. self.some_attr_in_base = None
if you think a redesign wouldn't be necessary.
Related references:
Upvotes: 2
Reputation: 115
If something inherits from a parent class it should have all the attributes of the parent class. For example "liters_gasoline" should only be in the class of a gasoline car not an electric car.
Upvotes: 2