Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Access child class variable in parent class

Tags:

python

oop

class

Is it correct to access variables from a child class in a parent class? Is this a good OOP approach? I don't need to create instances of Animal class, but if I will, the make_sound method will raise AttributeError, which is bothering me.

class Animal:
    def make_sound(self):
        print(self.sound)

class Cat(Animal):
    sound = 'meow'

class Dog(Animal):
    sound = 'bark'

cat = Cat()
cat.make_sound()

dog = Dog()
dog.make_sound()
like image 611
ryche Avatar asked Mar 22 '18 18:03

ryche


People also ask

Can a parent class access child class variable?

The reference holding the child class object reference will not be able to access the members (functions or variables) of the child class. This is because the parent reference variable can only access fields that are in the parent class.

Can a parent class hold child class object?

The parent class can hold reference to both the parent and child objects. If a parent class variable holds reference of the child class, and the value is present in both the classes, in general, the reference belongs to the parent class variable. This is due to the run-time polymorphism characteristic in Java.

Do child classes inherit class variables?

Classes called child classes or subclasses inherit methods and variables from parent classes or base classes. We can think of a parent class called Parent that has class variables for last_name , height , and eye_color that the child class Child will inherit from the Parent .


1 Answers

There's nothing inherently wrong with this approach. It really depends on the scope and significance of this class, and where its being used. Building a parent class to use implicitly defined attributes is quick, and in many cases perfectly OK. But, sometimes those implicit attributes can get out of hand, and you might want to ensure that anyone making new subclasses has to define those attributes.

There are a couple approaches to this. Some of this may not work depending on what version of Python you are using. I believe the usage of ABC like this works in Python 3.4+.

Python (and many OO languages) have the concept of an Abstract Base Class. This is a class that can never be instantiated, and it enforces that any subclasses must implement methods or properties defined as abtract in order to be instantiated.

Here's how you could provide a make_sound method, and still be 100% sure that anyone subclassing Animal is indeed making that sound.

from abc import ABC, abstractmethod


class Animal(ABC):

    def make_sound(self):
        print(self.sound)

    @property
    @abstractmethod
    def sound(self):
        """ return the sound the animal makes """


class Dog(Animal):

    @property
    def sound(self):
        return "bark"


class Cat(Animal):

    sound = "meow"


class Thing(Animal):
    """ Not an animal """

dog = Dog()
dog.make_sound()
cat = Cat()
cat.make_sound()
# thing = Thing()   this will raise a TypeError, complaining that its abstract
# animal = Animal()   as will this

This shows the many different ways to do this. Using the @property decorator allows you to set instance variables, or more complex logic, that affect it. Setting sound in the class is (somewhat) like setting a static member in a Java class. Since all cats meow, this probably makes sense in this case.

like image 160
Keozon Avatar answered Oct 07 '22 05:10

Keozon