Skip to Content
Course content

42: Practice Exercise: Building a Simple Library Catalog with Interfaces

Click on the "Edit" button in the top corner of the screen to edit your slide content.

We've talked about the theory of interfaces, but the best way to wrap your head around them is to build something where you'd actually regret not using one. Let's build a simple Library Catalog. In a real library, you have books, magazines, and DVDs. They are all different things, but from the perspective of a catalog, they all share a few common traits: they have a title and they can be checked out.

Defining the contract for catalog items

I don't want my catalog to care whether it's handling a 500-page novel or a 2-hour documentary. I just want to know that whatever the object is, I can ask it for its title. So, I'll start by defining a CatalogItem interface. This is our "contract." Any class that claims to be a CatalogItem must implement these methods.

public interface CatalogItem {
    String getTitle();
    boolean isAvailable();
    void markAsBorrowed();
    void markAsReturned();
}

Making Books and DVDs fit the mold

Now I can create my actual objects. Notice how the Book and DVD classes are completely different internally—the book has an ISBN, the DVD has a runtime—but they both satisfy the CatalogItem contract. This is where the power of interfaces kicks in; I can treat them as the same "type" when it matters.

public class Book implements CatalogItem {
    private String title;
    private String isbn;
    private boolean available = true;

    public Book(String title, String isbn) {
        this.title = title;
        this.isbn = isbn;
    }

    @Override
    public String getTitle() { return title; }

    @Override
    public boolean isAvailable() { return available; }

    @Override
    public void markAsBorrowed() { this.available = false; }

    @Override
    public void markAsReturned() { this.available = true; }
}

public class DVD implements CatalogItem {
    private String title;
    private int durationMinutes;
    private boolean available = true;

    public DVD(String title, int durationMinutes) {
        this.title = title;
        this.durationMinutes = durationMinutes;
    }

    @Override
    public String getTitle() { return title; }

    @Override
    public boolean isAvailable() { return available; }

    @Override
    public void markAsBorrowed() { this.available = false; }

    @Override
    public void markAsReturned() { this.available = true; }
}

A quick detour into a common mistake

While I was sketching this out, I actually tried to do something silly. I thought, "Wait, both Book and DVD have a title field. Why don't I just put private String title; inside the CatalogItem interface to save myself some typing?"

I tried it, and the compiler immediately yelled at me. I forgot for a second that interfaces cannot hold state. An interface defines behavior (what an object can do), not data (what an object is). If I wanted to share a field, I'd need an abstract class, but that creates a rigid hierarchy. By sticking with the interface, I keep my classes flexible. I had to move the title field back into the individual classes, and that's actually the correct way to do it here.

Wiring it all together in the Catalog

Now for the payoff. I'll create a LibraryCatalog class. Because I used an interface, my list doesn't need to be a list of Books or a list of DVDs. It's a list of CatalogItems. I can mix and match whatever I want in there, and as long as they implement the interface, my displayAvailableItems method will work perfectly.

import java.util.*;

public class LibraryCatalog {
    private List<CatalogItem> items = new ArrayList<>();

    public void addItem(CatalogItem item) {
        items.add(item);
    }

    public void displayAvailableItems() {
        System.out.println("Available items in the library:");
        for (CatalogItem item : items) {
            if (item.isAvailable()) {
                System.out.println("- " + item.getTitle());
            }
        }
    }

    public static void main(String[] args) {
        LibraryCatalog myLibrary = new LibraryCatalog();
        myLibrary.addItem(new Book("The Great Gatsby", "12345"));
        myLibrary.addItem(new DVD("Inception", 148));
        myLibrary.addItem(new Book("1984", "67890"));

        myLibrary.displayAvailableItems();
    }
}



📋 Practical Task

Exercise: Implementing a DigitalLicense Interface

Your library is expanding! They now offer "Digital eBooks" and "Streaming Movies." Unlike physical books and DVDs, these digital items have a license expiration date.

Your task is to:

  • Create a new interface called DigitalLicense with a method boolean isLicenseValid().
  • Create a class EBook that implements both CatalogItem (from the lesson) and your new DigitalLicense interface.
  • In the EBook class, implement isLicenseValid()` to return true if a dummy expiration date is in the future.
  • Modify the LibraryCatalog main method to add an EBook to the list and verify that it can still be processed by the displayAvailableItems()` method.
Rating
0 0

There are no comments for now.

to be the first to leave a comment.