In this lab, we will explore more advanced object-oriented programming concepts, focusing on encapsulation and complex class interactions. We'll use a practical example involving a Plant Nursery system to understand these concepts. This system will manage different types of plants, such as flowers, trees, and cacti, and demonstrate interactions such as planting, watering, and monitoring plant health.
By the end of this lab, you'll apply what you've learned to create your own "Zoo" management system for the Animal Kingdom program. This project will reinforce the concepts and show how they can be applied to different scenarios in programming.
Ensure that you are signed into your GitHub account
Join the GitHub Classroom and accept this assignment: Project 10 - Animal Kingdom
Clone the repository to your computer using GitHub Desktop or open it online using Codespaces
Encapsulation is one of the key principles of object-oriented programming (OOP). It involves combining data (attributes) and the methods (functions) that manipulate that data into a single unit known as a class. The main purpose of encapsulation is to safeguard the data from outside interference and misuse. Here's how encapsulation works and why it's beneficial:
Protect and Hide Data: Only the methods within the same class can directly access and modify the data (attributes). Outside access to these attributes is controlled through methods known as getters and setters. This prevents accidental or unauthorised changes, which helps maintain data integrity.
Hide Complexity: By keeping the data and methods that manipulate the data together, encapsulation makes the code more modular and easier to understand. You can think of a class as a toolbox that contains all the tools (methods) needed to manipulate the data (screws, nails, etc.).
Example in the Plant Program: In our Plant program, each plant type (like Flower, Tree, Cactus) encapsulates attributes specific to that type, such as colour for flowers and height for trees. Methods like grow() or bloom() directly manipulate these attributes without exposing the complexity to the outside world.
class Flower:
def __init__(self, name, colour):
self.__name = name # Private attribute
self.__colour = colour # Private attribute
def bloom(self):
return f"The {self.__colour} {self.__name} is blooming!"
def get_colour(self):
return self.__colour
def set_colour(self, colour):
self.__colour = colour
In this Flower class, the attributes name and colour are encapsulated within the class. The method bloom() uses these attributes to perform its function, which is to simulate the flower blooming.
Class Interactions refer to how instances of different classes (like Plant, Flower, Tree, Cactus in the Plant program, or various animals in the Zoo) interact with each other within a larger system. These interactions are crucial for building complex applications where different objects need to work together to achieve common goals.
In our previous labs, we learned about generalization, inheritance, and polymorphism. Now, we'll use that knowledge to manage a group of plant instances within a system, demonstrating encapsulation and class interactions. The Nursery class will act as a container and manager for various plants, encapsulating both the collection of plants and the operations performed on them.
class Nursery:
def __init__(self):
self.plants = []
We can design a method that takes an object of type Plant or any of its derived classes. it will then add it to the plants list.
def add_plant(self, plant):
self.plants.append(plant)
return f"{plant.name} added to the nursery."
We can design a method that simulates the action of watering all plants in the nursery.
This method demonstrates a common action applied to a collection of objects, showcasing how encapsulation helps manage group actions on multiple objects efficiently.
def water_plants(self):
for plant in self.plants:
print(f"Watering {plant.name}.")
Here we show:
The relationship between the Nursery and Plants
How Flower, Tree and Cactus inherit from Plant
To use the Nursery class effectively, instantiate it and add various plant objects, then call its methods to manage these plants:
Open lab1.py
Complete the following activities:
Paste your base class Animal and the derived classes from Lab 1 here.
Modify the classes to demonstrate polymorphism through method overriding.
Each derived class should override at least one method from the Animal class.
For instance, you might want to override a 'make_sound' method to reflect the specific sound each animal makes.
Create at least two instances of your derived classes
Call the overridden methods on the instances.
Commit and push your code