Python - Classes
__str__
method in a class?
In Python, the __str__
method is used to define a human-readable representation of an object. When the str()
function is called on an object, or when the print()
function is used with the object, the __str__
method is automatically called. This method should return a string that represents the object in a clear and concise way.
Let's illustrate the purpose of the __str__
method with an example:
class Student:
def __init__(self, name, age, grade):
self.name = name
self.age = age
self.grade = grade
def __str__(self):
return f"Student: {self.name}, Age: {self.age}, Grade: {self.grade}"
# Creating an object of the Student class
student1 = Student("Alice", 20, "A")
# Calling the __str__ method implicitly
print(student1)
In this example, the Student
class has an __init__
method to initialize the name
, age
, and grade
attributes. The __str__
method returns a formatted string representing the student's information.
When we print the student1
object, the __str__
method is automatically called, providing a human-readable representation of the object.
Output:
Student: Alice, Age: 20, Grade: A
In Python, inheritance is a mechanism that allows a new class to inherit attributes and methods from an existing class. The existing class is referred to as the base class or parent class, and the new class is called the derived class or child class. Inheritance promotes code reuse and allows the child class to extend or override the functionality of the parent class.
Let's demonstrate the concept of inheritance with an example:
class Animal:
def __init__(self, name):
self.name = name
def speak(self):
return "Some generic sound"
# Derived class (Child class)
class Dog(Animal):
def bark(self):
return "Woof!"
# Derived class (Child class)
class Cat(Animal):
def meow(self):
return "Meow!"
# Creating objects of the derived classes
dog = Dog("Buddy")
cat = Cat("Whiskers")
# Accessing methods from the base class
print(f"{dog.name} says: {dog.speak()}")
print(f"{cat.name} says: {cat.speak()}")
# Accessing methods from the child classes
print(f"{dog.name} barks: {dog.bark()}")
print(f"{cat.name} meows: {cat.meow()}")
In this example, the Animal
class is the base class with a constructor and a speak
method. The Dog
and Cat
classes are derived classes that inherit from the Animal
class. The Dog
class introduces a new method bark
, and the Cat
class introduces a new method meow
.
We create objects of the derived classes and demonstrate the use of inherited methods from the base class as well as the new methods introduced in the derived classes.
Outputs:
Buddy says: Some generic sound Whiskers says: Some generic sound Buddy barks: Woof! Whiskers meows: Meow!
Method overriding in Python allows a derived class to provide a specific implementation for a method that is already defined in its base class. This allows the child class to customize or extend the behavior of the inherited method.
Let's demonstrate method overriding with an example:
class Shape:
def draw(self):
return "Drawing a generic shape"
# Derived class (Child class)
class Circle(Shape):
def draw(self):
return "Drawing a circle"
# Derived class (Child class)
class Square(Shape):
def draw(self):
return "Drawing a square"
# Creating objects of the derived classes
circle = Circle()
square = Square()
# Calling overridden methods
print(circle.draw())
print(square.draw())
In this example, the Shape
class has a method called draw
. The Circle
and Square
classes are derived from the Shape
class and override the draw
method with their own specific implementations.
When we create objects of the derived classes and call the draw
method, the overridden method in each class is executed, providing a specialized behavior.
Output:
Drawing a circle Drawing a square
super()
function in inheritance?
In Python, the super()
function is used to call a method from the parent class in the context of the derived class. It is often used in the constructor (__init__
) of the child class to invoke the constructor of the parent class. This allows the child class to perform its own initialization while reusing the functionality of the parent class.
Let's illustrate the significance of the super()
function with an example:
class Animal:
def __init__(self, name):
self.name = name
def make_sound(self):
return "Some generic sound"
# Derived class (Child class)
class Dog(Animal):
def __init__(self, name, breed):
# Using super() to call the constructor of the parent class
super().__init__(name)
self.breed = breed
def make_sound(self):
# Using super() to call the method from the parent class
parent_sound = super().make_sound()
return f"{self.name} ({self.breed}) barks: Woof! {parent_sound}"
# Creating an object of the Dog class
dog = Dog("Buddy", "Labrador")
# Calling overridden method
result = dog.make_sound()
# Displaying the result
print(result)
In this example, the Animal
class has a constructor and a method called make_sound
. The Dog
class is derived from Animal
and has its own constructor that uses super()
to call the constructor of the parent class. It also overrides the make_sound
method and uses super()
to invoke the method from the parent class while extending its behavior.
Output:
Buddy (Labrador) barks: Woof! Some generic sound