Skip to main content

Class Inheritance and Method Override

As we dig deeper into the world of object oriented programming and classes we will find more ways to reduce lines of code and further improve readability and maintainability for the next programmer.  Class Inheritance is a good way to break up your classes into manageable chunks of code.  The concepts here are somewhat confusing so I will use another example employing a filesystem crawler.

In our crawler we would first implement a definition of what a file is and how we can modify it.  Since this will be the most basic of files we only define things that apply to all file types.

import os	# use this to provide some details about a file

class File():
  """Represents a single file"""
  def __init__(self, path):
    self.path = path
    
  @property
  def fileSize(self):
    """Return number of bytes this file is"""
    return os.path.getsize(self.path)

With this defined we can now "subclass" this to add more functionality to our code.  Rather than just returning a file size we could provide details about an image file.  In the "Image" class you can see that we used the "File" class as an argument.  Additionally, you can see a special function called within the "__init__" method.  This calls the "__init__" of the super class, in this case the "File" class.  Now when you instantiate an "Image" class you have access to the "File" class properties also.

import os
import PIL

class File():
    def __init__(self, path):
        self.path = path

    @property
    def fileSize(self):
        return os.path.getsize(self.path)

class Image(File):
    def __init__(self, path):
        super().__init__(path)

    @property
    def size(self):
      """Returns a Tuple of width,height"""
        image = PIL.Image.open(self.path)
        return image.size

Example of using the "Image" class

someImageFile = Image("something.jpg")  # Instantiate the object
print(someImageFile.fileSize)			# Get details from the file system
print(someImageFile.size)				# Get details from the image
Method Overriding

In this example what if we only wanted to report file size of an image in MB rather than bytes?  This is where you can override a method provided in the super class with a customized version which only applies to its subclass.  All you need to do is define a function in the subclass that is named exactly as the superclass and write your custom code within it.

import os
import PIL

class File():
    def __init__(self, path):
        self.path = path

    @property
    def fileSize(self):
        return os.path.getsize(self.path)

class Image(File):
    def __init__(self, path):
        super().__init__(path)

    def fileSize(self):
        return os.path.getsize(self.path) / 1000

    @property
    def size(self):
        image = PIL.Image.open("sample.png")
        return image.size