4

When a subclass inherits from a superclass, must the subclass have all the arguments that the superclass has? E.g.: "Vehicle(colour, wheels, size)" is the superclass. Can I have a subclass that inherits everything from Vehicle except the "size" attribute/argument?

This is the parent class:

class LagStudent:

    def __init__(self, name, dept, cgpa, is_a_scholar):
        self.name = name
        self.dept = dept
        self.cgpa = cgpa
        self.is_a_scholar = is_a_scholar

Below are two subclasses:

class CovStudent(LagStudent):

    def __init__(self, name, dept, cgpa, is_a_scholar, honours):
        super().__init__(name, dept, cgpa, is_a_scholar)
        self.honours = honours


class OxStudent(CovStudent):

    def __init__(self, name, dept, cgpa, is_a_scholar):
        super().__init__(name, dept, cgpa, is_a_scholar) 

When I run the following...

student4 = OxStudent("Mark", "Mathematics", 4.62, True)
print(student4.is_a_scholar)

It gives Error:

TypeError: init() missing 1 required positional argument: 'honours'

5
  • The question is not clear: how should subclass methods behave then? They can't call parent Vehicle methods as they require size as arg. Commented Apr 19, 2019 at 16:39
  • If you are talking only about object initialisation then the answer is yes, you can have SubVehicle(Vehicle) with __init__(colour, wheels) overridden that sets self.size to some neccesary value. Commented Apr 19, 2019 at 16:40
  • Yes of course you can. The question is, should you? Commented Apr 19, 2019 at 16:55
  • Why does OxStudent inherit from CovStudent here and not LagStudent? Commented Apr 20, 2019 at 12:55
  • "Can I have a subclass that inherits everything from Vehicle except the "size" attribute/argument?" - no. This would be a definitely bad design. Please read about the Liskov substitution principle. "It is based on the concept of "substitutability" – a principle in object-oriented programming stating that an object (such as a class) may be replaced by a sub-object (such as a class that extends the first class) without breaking the program." (Wikipedia) A subclass of A is "kind of A", and you should expect it to have all properties and methods of A (maybe some more, but it's not that important). Commented Aug 30, 2023 at 10:37

2 Answers 2

5

We define the Vehicle superclass as follows, and Bicycle subclass as follows

class Vehicle:

    def __init__(self, colour, wheels, size):

        self.colour = colour
        self.wheels = wheels
        self.size = size

class Cycle(Vehicle):

    def __init__(self, colour, wheels, size):

        super().__init__(colour, wheels, 'small')

Here you can see that the Cycle subclass just takes in colors and wheels and passes it onto the superclass, and has a hardcoded size=small attribute. The subclass constructor calls the constructor of the superclass

To check what's going on, we can try as follows:

veh = Cycle('Black', 2)
print(veh.colour)
print(veh.wheels)
print(veh.size)
#Black
#2
#small

Update Based on OP's comment of not wanting to have a size attribute, you can assign a default value to the size attribute in the superclass, e.g. size=None and you won't need to pass it while instantiating the subclass.

class Vehicle:

    def __init__(self, colour, wheels, size=None):

        self.colour = colour
        self.wheels = wheels
        self.size = size

class Cycle(Vehicle):

    def __init__(self, colour, wheels):

        super().__init__(colour, wheels)

You can then call this as follows

veh = Cycle('Black', 2)
print(veh.colour)
print(veh.wheels)
print(veh.size)
#Black
#2
#None

You can see that the value of size is None, which is the default value we picked since we did not pass size explicitly, if we would have passed it, we would have got a value for the size attribute

Sign up to request clarification or add additional context in comments.

11 Comments

Ok, so what I mean is: What if I don't want the Cycle to have a "size" attribute. Is it possible to omit it when constructing the class, or is it compulsory that I include it even if I don't want instances of that class to possess the "size" attribute?
Okay I have updated my answer to include that scenario!
This is what I mean. The issue now is that the program doesn't run. It gives this error: in init super().__init__(colour, wheels) TypeError: __init__() missing 1 required positional argument: 'size'
Can you show which class are you instantiating and how are you instantiating it
I've edited my original question. Please see whether you get what I mean. Thanks.
|
1

A subclass certainly can have a different signature for the __init__ method from its superclass. It just needs to call the __init__ method of its superclass with what that method expects:

class Vehicle:
    def __init__(self, colour, wheels, size):
        self.colour = colour
        self.wheels = wheels
        self.size = size

class Car(Vehicle):
    def __init__(self, colour, wheels):
        super().__init__(colour, wheels, 'small')

print(Car('white', 4).size)

This outputs:

small

2 Comments

Thanks for the response, but what I really want to know is: What if I don't want the "Car" class to have a "size" attribute? Is it possible to omit it in both the class construction and inheritance initialisation?
@Goriola, then it's not really a subclass, is it?

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.