Interview Questions, Answers and Tutorials

Duck typing and interfaces

Duck typing and interfaces

Imagine you’re playing a game where you have different toys: a toy car, a toy boat, and a toy airplane. They all have something in common: you can play with them. You don’t care if it’s a car, a boat, or a plane; as long as it can be played with, it’s a toy to you.

This is similar to how duck typing works in Python. The name “duck typing” comes from the saying: “If it looks like a duck, swims like a duck, and quacks like a duck, then it probably is a duck.” In Python, if an object can perform the required actions (methods), then it can be used, regardless of what type of object it actually is.

Example of Duck Typing

Let’s look at a simple example:

class Dog:
    def sound(self):
        return "Bark!"

class Cat:
    def sound(self):
        return "Meow!"

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

dog = Dog()
cat = Cat()

make_sound(dog)  # Output: Bark!
make_sound(cat)  # Output: Meow!

In this example, both the ‘Dogand ‘Catclasses have a ‘soundmethod. The ‘make_sound‘ function doesn’t care whether it’s dealing with a dog or a cat; it just calls the sound method. As long as the object passed to it has a ‘soundmethod, it works.

Introduction to Interfaces

Now, let’s talk about interfaces. An interface is like a promise that certain methods will be present in a class. It’s like a checklist that classes have to follow. Python doesn’t have formal interfaces like some other programming languages, but we can create similar structures using abstract base classes (ABCs).

An abstract base class is a class that can’t be instantiated on its own and requires subclasses to implement certain methods.

Example of an Interface Using Abstract Base Classes

Let’s create an interface for an animal that has to have a ‘soundmethod:

from abc import ABC, abstractmethod

class Animal(ABC):
    @abstractmethod
    def sound(self):
        pass

class Dog(Animal):
    def sound(self):
        return "Bark!"

class Cat(Animal):
    def sound(self):
        return "Meow!"

# This will work
dog = Dog()
cat = Cat()
print(dog.sound())  # Output: Bark!
print(cat.sound())  # Output: Meow!

# This will raise an error because Animal is an abstract class
# and can't be instantiated
# animal = Animal()

Here, ‘Animal' is an abstract base class with an abstract method ‘sound‘. Any subclass of ‘Animalmust implement the ‘soundmethod.

Practice Questions

  1. Question: Create a class ‘Birdthat inherits from the ‘Animalabstract base class and implement the ‘soundmethod to return “Chirp!”.

Solution:

class Bird(Animal):
    def sound(self):
        return "Chirp!"

bird = Bird()
print(bird.sound())  # Output: Chirp!

    1. Question: Write a function ‘animal_sounds‘ that takes a list of ‘Animalobjects and prints the sound of each one.

    Solution:

      def animal_sounds(animals):
          for animal in animals:
              print(animal.sound())
      
      animals = [Dog(), Cat(), Bird()]
      animal_sounds(animals)
      # Output:
      # Bark!
      # Meow!
      # Chirp!
      

      1. Question: Create a class ‘Fishthat should also inherit from ‘Animal‘, but it should have a ‘sound‘ method that returns “Blub!” and demonstrates it with the ‘animal_sounds‘ function.

      Solution:

      class Fish(Animal):
          def sound(self):
              return "Blub!"
      
      fish = Fish()
      animals.append(fish)
      animal_sounds(animals)
      # Output:
      # Bark!
      # Meow!
      # Chirp!
      # Blub!
      

        Duck typing and interfaces are powerful concepts in Python that allow for flexible and reusable code. Duck typing lets you use objects as long as they have the required methods, while interfaces (using abstract base classes) provide a way to define a contract that classes must follow. By understanding and using these concepts, you can write more robust and maintainable Python programs.