IS4010: AI-Enhanced Application Development

Week 6: Object-Oriented Programming

Brandon M. Greenwell

Session 1: Classes & objects

Shifting our thinking

  • So far, we have been writing procedural code: a series of instructions that run from top to bottom.
  • Object-oriented programming (oop) is a different way to structure our applications.
  • It helps us manage the complexity of large programs by modeling our code after real-world objects and their interactions.
  • Instead of a list of steps, we will think about creating blueprints for objects that have their own data and behaviors.

What is a class?

  • A class is a blueprint or a template for creating objects. It defines the properties and behaviors that all objects of that type will have.
  • An object (or instance) is a specific item created from that class blueprint. It has its own unique data.
  • Analogy: A CarFactory is the class. It defines that all cars will have a color and a model. Each individual Car that rolls off the assembly line is an object with its own specific color and model.

The __init__ method

  • The __init__ method is a special function called a constructor. It runs automatically whenever a new object is created.
  • Its job is to initialize the object’s attributes (its data).
  • The self parameter is a reference to the specific instance of the class being created. We use it to attach data to the object.
class Student:
    """Represents a student in a course."""
    def __init__(self, name: str, student_id: int):
        # These are attributes of the Student object
        self.name = name
        self.student_id = student_id
        self.is_enrolled = True

# Create two instances (objects) of the Student class
student_one = Student("Grace Hopper", 1001)
student_two = Student("Ada Lovelace", 1002)

The __str__ method

  • The __str__ method is another special “dunder” (double underscore) method.
  • Its purpose is to return a user-friendly, human-readable string that represents the object.
  • When you use print(my_object), python automatically calls this method behind the scenes.
  • This is great boilerplate code to ask your AI assistant to generate for you.
class Student:
    """Represents a student in a course."""
    def __init__(self, name: str, student_id: int):
        self.name = name
        self.student_id = student_id
    
    def __str__(self) -> str:
        """Returns a string representation of the student."""
        return f"Student Name: {self.name}, ID: {self.student_id}"

student_one = Student("Grace Hopper", 1001)
print(student_one)

Introducing lab 06 (part 1)

  • For the first part of this week’s lab, you will get to model a real-world object.
  • Your task is to create a python class for something like a Book, Movie, or Product.
  • You will use an AI assistant to help you generate the initial class structure, an __init__ method to store its attributes, and a descriptive __str__ method.

Session 2: Methods & inheritance

Giving objects behavior

  • Methods are functions that are defined inside a class.
  • They define what an object created from that class can do.
  • Like __init__, methods must always have self as their first parameter, allowing them to access and modify the object’s own attributes.
class Book:
    """Represents a book in a library."""
    def __init__(self, title: str, author: str):
        self.title = title
        self.author = author
        self.is_checked_out = False

    def check_out(self):
        """Marks the book as checked out."""
        self.is_checked_out = True
        print(f"'{self.title}' has been checked out.")

What is inheritance?

  • Inheritance is a core principle of oop that allows one class (the child) to inherit the attributes and methods of another class (the parent).
  • The primary benefit is code reuse. We can write common logic once in a parent class and then create multiple, specialized child classes that share it.
  • For example, Car, Truck, and Motorcycle could all inherit from a parent Vehicle class.

Implementing inheritance

  • We use the syntax class ChildClass(ParentClass): to define an inheritance relationship.
  • Inside the child class’s __init__ method, we must call super().__init__(...) to make sure the parent class’s constructor is also run.
  • The child class can then add its own unique attributes and methods.
class Book: # Parent class
    def __init__(self, title, author):
        self.title = title
        self.author = author

class EBook(Book): # Child class
    def __init__(self, title, author, file_format):
        super().__init__(title, author) # Call parent constructor
        self.file_format = file_format # Add a new attribute

Introducing lab 06 (part 2)

  • The second part of the lab builds on the first.
  • You will extend the class you created by adding methods that give it behavior and modify its state.
  • Then, you will create a new child class that inherits from your base class, adding its own unique attributes and methods.
  • Full instructions are in labs/lab06/README.md.