TiimeIrre
TiimeIrre

Reputation: 223

How to inherit values from a parent class without specifying the attributes in a child class

I have a task to recreate a human parent-children connection via OOP and inheritance. So, there are classes for father and mother, and there is also a class for children, which should inherit firstly from the father class, then from the mother class (also I inserted some additional attributes, absent in parents' classes).

The task is:

Create classes "father" and "mother" with some attributes equal and some of them - different; then create a "child" class that would be inherited from both previous classes to make their equal attributes be inherited by "child" class from the "father" class (this is about priority). Create an object of the "child" class and return its attributes in the output.

Code (unfinished):

class Father:
    def __init__(self, surname, name, age, size):
        self.surname = surname
        self.name = name
        self.age = age
        if size in range(5, 31):
            self.__d_size = size

    @property
    def d_size(self):
        return self.__d_size

    @d_size.setter
    def d_size(self, size):
        if size in range(5, 31):
            self.__d_size = size


class Mother:
    def __init__(self, surname, name, age, size):
        self.surname = surname
        self.name = name
        self.age = age
        if size in range(1, 7):
            self.__b_size = size

    @property
    def b_size(self):
        return self.__b_size

    @b_size.setter
    def b_size(self, size):
        if size in range(1, 7):
            self.__b_size = size


class Child(Father, Mother):

    @property
    def gender(self):  
        # don't bother guessing the principle of the formula and what do "d" and "b" mean here
        if (super().d_size + super().b_size) % 2 != 0:
            gender = "male"
        else:
            gender = "female"
        return gender

    @property
    def patronymic(self):
        if self.gender == "male":
            return super().name + "vich"
        else:
            return super().name + "vna"

    @property
    def full_name(self):
        return f"{self.surname} {self.name} {self.patronymic}, {self.age} years old, {self.gender}"


if __name__ == '__main__':
    alex = Father('Romanov', 'Alexey', 46, 20)
    nata = Mother('Naryshkina', 'Natalya', 24, 3)
    peter = Child('Peter', 3, 5)  # <- surname isn't meant to be specified here
    peter.full_name  # expected output here is "Romanov Peter Alexeyvich, 3 years old, male"

Questions:

  1. Is there a possibility for the Child class to inherit a surname value from the Father's class without a need to specify it while creating an object of the Child class? Because from the point of common logic it seems redundant to specify the surname for the Child object, if it is obvious that Father surname is inherited. I suspect that something has to be added here, but I don't know whether it requires to redefine __init__ in Child class or something else to be done.
  2. I'm slightly lost in searching of a better method to validate values given for attributes before the creation of an object. Here in parents' classes I've implemented it in two ways: directly in __init__ via if and then in @property. Because some values here have to make at least some sense, as the one hardly can bear children before turning 12 y.o., so I could also insert here an embedded check for a value assigned to self.age attribute. But I'm not sure how to do it better. I guess that @property works only for changing of the value of an already existing and initialised attribute; so, it wouldn't be helpful in my case.

Upvotes: -1

Views: 69

Answers (1)

TiimeIrre
TiimeIrre

Reputation: 223

I've properly looked through relatable topics here and have come to the conclusion that it is hardly possible to implement without specifying the parent classes as parameters in the Child class' __init__. And yep, this way the whole inheritance thing is not very useful here (but that was a requirement of the task).

The code that was accepted by curators:

class Father:
    def __init__(self, surname, name, age):
        self.surname = surname
        self.name = name
        self.age = age

    @property
    def eyes(self):
        return "brown"


class Mother:
    def __init__(self, surname, name, age, skin):
        self.surname = surname
        self.name = name
        self.age = age
        self.skin = skin

    @property
    def eyes(self):
        return "grey"


class Child(Father, Mother):
    def __init__(self, surname, name, age, father, mother):
        self.father = father
        self.mother = mother
        super().__init__(surname, name, age)

    @property
    def gender(self):
        if self.name not in ["Nikita", "Foma"] and self.name[-1] != "a":
            return "male"
        else:
            return "female"

    @property
    def patronymic(self):
        if self.gender == "male":
            return self.father.name + "vich"
        else:
            return self.father.name + "vna"

    @property
    def full_name(self):
        return f"{self.surname} {self.name} {self.patronymic}, {self.age} years old, {self.gender}, {self.eyes}-eyed"


if __name__ == '__main__':
    alex = Father('Romanov', 'Alexey', 46)
    nata = Mother('Naryshkina', 'Natalya', 25, "white")
    peter = Child('Romanov','Peter', 3, alex, nata)
    print(alex.__dict__)
    print(nata.__dict__)
    print(peter.__dict__)
    print(peter.gender)
    print(peter.eyes)
    print(peter.full_name)

Upvotes: 0

Related Questions