In object-oriented programming, objects often don't exist in isolation. They interact with other objects to perform more complex tasks. Understanding these interactions is crucial for building robust and scalable applications.

When we have multiple objects on the screen, we might want to develop some interactions between them. For this, we will discuss different approaches to developing class interactions. Depending on the data structures that we have implemented, we will see that there will be different approaches toward interactivity between objects.

Let's consider a simple interaction:

#Let's create a book class
class Book:
    def __init__(self, title):
        self.title = title

    def get_title(self):
        return self.title

#Let's create a person class
class Person:
    def __init__(self, name):
        self.name = name

    #Notice that this method requires a book as an argument
    def read(self, book):
        print("Message: " + self.name +  " is reading " + book.get_title() )
        

p = Person("Emma")
b = Book("Oliver Twist")

p.read(b)

Notice how a class can have a reference to another class. In the case above, the method "read" makes reference to another class. We need to have another class present in our program in order to do this, as we are establishing a dependency between the classes.

Let's look at another type of interaction - Composition .

In this case, we will see that one of the objects has a hierarchy over the other one, as one will contain the other one.

Let's look at one example:

class Book:
    def __init__(self, title):
        self.title = title

    def get_title(self):
        return self.title
        
class Library:
    def __init__(self):
        self.books = []

    def add_book(self, book):
        self.books.append(book)

    def list_books(self):
        for book in self.books:
            print(book.get_title())

lib = Library()

b1 = Book("Oliver Twist")
b2 = Book("Frankenstein")
b3 = Book("The Magic Mountain")

lib.add_book(b1)
lib.add_book(b2)
lib.add_book(b3)

lib.list_books()

Notice how the Library class has a list to store books. This type of class is incredibly useful as a manager of a collection.