Python - Classes
In Python, multiple inheritance is a feature that allows a class to inherit attributes and methods from more than one base class. This allows the derived class to have a combination of features from multiple classes, promoting code reuse and flexibility.
Let's demonstrate the concept of multiple inheritance with an example:
class Animal:
def speak(self):
return "Some generic sound"
class Mammal:
def give_birth(self):
return "Giving birth to live young"
class Dog(Animal, Mammal):
def bark(self):
return "Woof!"
# Creating an object of the derived class
dog = Dog()
# Accessing methods from multiple base classes
print(dog.speak())
print(dog.give_birth())
print(dog.bark())
In this example, the Animal
class has a speak
method, the Mammal
class has a give_birth
method, and the Dog
class is derived from both Animal
and Mammal
. The Dog
class can access methods from both base classes, demonstrating multiple inheritance.
Output:
Some generic sound Giving birth to live young Woof!
isinstance()
and issubclass()
functions in Python?
In Python, the isinstance()
function is used to check if an object is an instance of a particular class or a tuple of classes. The issubclass()
function is used to check if a class is a subclass of another class or a tuple of classes.
Let's illustrate the use of isinstance()
and issubclass()
with an example:
class Animal:
pass
class Mammal(Animal):
pass
class Dog(Mammal):
pass
# Creating an object of the Dog class
dog_instance = Dog()
# Using isinstance to check if an object is an instance of a class
is_dog_instance = isinstance(dog_instance, Dog)
is_mammal_instance = isinstance(dog_instance, Mammal)
is_animal_instance = isinstance(dog_instance, Animal)
# Using issubclass to check if a class is a subclass of another class
is_dog_subclass_of_mammal = issubclass(Dog, Mammal)
is_mammal_subclass_of_animal = issubclass(Mammal, Animal)
is_dog_subclass_of_animal = issubclass(Dog, Animal)
# Displaying the results
print(f"Is Dog an instance of Dog class? {is_dog_instance}")
print(f"Is Dog an instance of Mammal class? {is_mammal_instance}")
print(f"Is Dog an instance of Animal class? {is_animal_instance}")
print()
print(f"Is Dog a subclass of Mammal class? {is_dog_subclass_of_mammal}")
print(f"Is Mammal a subclass of Animal class? {is_mammal_subclass_of_animal}")
print(f"Is Dog a subclass of Animal class? {is_dog_subclass_of_animal}")
In this example, we have three classes (Animal
, Mammal
, and Dog
). We use isinstance()
to check if an object is an instance of a particular class, and issubclass()
to check if a class is a subclass of another class. The results are then displayed.
Output:
Is Dog an instance of Dog class? True Is Dog an instance of Mammal class? True Is Dog an instance of Animal class? True Is Dog a subclass of Mammal class? True Is Mammal a subclass of Animal class? True Is Dog a subclass of Animal class? True
In Python, abstract classes and methods are part of the abstract base classes (ABCs) module and provide a way to define a common interface for a group of related classes. An abstract class is a class that cannot be instantiated, and an abstract method is a method that must be implemented by any concrete (non-abstract) subclass. Abstract classes and methods help enforce a common structure among different classes.
Let's demonstrate the purpose of abstract classes and methods with an example:
from abc import ABC, abstractmethod
# Abstract class with abstract method
class Shape(ABC):
@abstractmethod
def area(self):
pass
# Concrete class implementing the abstract method
class Circle(Shape):
def __init__(self, radius):
self.radius = radius
def area(self):
return 3.14 * self.radius ** 2
# Concrete class implementing the abstract method
class Square(Shape):
def __init__(self, side):
self.side = side
def area(self):
return self.side ** 2
# Attempting to create an instance of the abstract class will result in a TypeError
# shape = Shape()
# Creating objects of concrete classes
circle = Circle(5)
square = Square(4)
# Calling the area method on concrete objects
circle_area = circle.area()
square_area = square.area()
# Displaying the results
print(f"Area of the circle: {circle_area}")
print(f"Area of the square: {square_area}")
In this example, the Shape
class is an abstract class with an abstract method area
. The Circle
and Square
classes are concrete classes that inherit from Shape
and implement the area
method. Attempting to create an instance of the abstract class will result in a TypeError
.
Output:
Area of the circle: 78.5 Area of the square: 16
In object-oriented programming, composition and inheritance are two ways to achieve code reuse and design relationships between classes. The key difference lies in how they establish relationships between classes and promote code reuse.
Composition:
class Engine:
def start(self):
return "Engine started"
class Car:
def __init__(self):
# Composition: Car has an Engine
self.engine = Engine()
def drive(self):
return f"Car is moving. {self.engine.start()}"
# Creating an object of the Car class
car = Car()
# Using composition to access functionalities of the Engine class
result = car.drive()
# Displaying the result
print(result)
In composition, a class is composed of other classes as parts. In the example, the Car
class has an instance of the Engine
class. The Car
class can access and use the functionalities of the Engine
class through composition.
Output:
Car is moving. Engine started
Inheritance:
class Animal:
def make_sound(self):
return "Some generic sound"
class Dog(Animal):
def bark(self):
return "Woof!"
# Creating an object of the Dog class
dog = Dog()
# Using inheritance to access functionalities of the Animal class
result = dog.make_sound()
# Displaying the result
print(result)
In inheritance, a class inherits attributes and methods from another class. In the example, the Dog
class inherits from the Animal
class. The Dog
class can access and use the functionalities of the Animal
class through inheritance.
Output:
Some generic sound
Comparison:
Composition allows for more flexibility and is often favored when designing relationships between classes, as it avoids some issues related to tight coupling. Inheritance promotes code reuse but can lead to a rigid class hierarchy, and changes in the base class can affect derived classes.