CodeBlanks Logo Icon CodeBlanks

Challenge - OOP app

PHP course · Intermediate · Lesson 111/115

Build a book library management system with classes, interfaces and traits.

Challenge - OOP app

In this challenge you'll build a book library management system. The Book class stores the title and author in private properties; only a getter exposes them. The Borrowable interface declares a borrow() method as a contract; the BorrowableTrait implements it and is pulled into Book with use.

Together these three tools combine encapsulation and polymorphism. The challenge tests your full intermediate OOP knowledge.

Trait and interface together

A trait is a way to reuse code across classes without inheritance. The BorrowableTrait provides the borrow() and returnItem() methods; the Book class imports them with the use BorrowableTrait; line.

An interface is only a contract: it declares which methods must exist but not how to implement them. The Book class says implements Borrowable, so it must provide borrow(). The trait supplies that method.

Exercise Write the Book and Library classes

Define a Book class with private string $title and private string $author properties, a constructor that takes both, and a getTitle(): string method. Then write a Library class: it holds private array $books = []; its addBook(Book $book): void method adds a book; its count(): int method returns the count. Finally create a Book, add it to a Library, and run echo $lib->count() . "\n".

Show example solution
Define both classes, assign properties in the constructor, add addBook and count methods to Library.
Example solution:
<?php
// Write the Book and Library classes
class Book {
    private string $title;
    private string $author;

    public function __construct(string $title, string $author) {
        $this->title = $title;
        $this->author = $author;
    }

    public function getTitle(): string {
        return $this->title;
    }
}

class Library {
    private array $books = [];

    public function addBook(Book $book): void {
        $this->books[] = $book;
    }

    public function count(): int {
        return count($this->books);
    }
}

$lib = new Library();
$lib->addBook(new Book("Clean Code", "Robert Martin"));
echo $lib->count() . "\n";

Test yourself

  1. How should you declare $title in the Book class so it can't be changed from outside?

    • As public $title
    • As private $title, with a getter
    • As static $title
    • Make $title global
    Show answer

    As private $title, with a getter — Correct. With private $title you block direct outside access and provide getTitle() for controlled reads.

  2. Complete the trait usage

    class Book implements Borrowable {
        use ____;
        private string $title;
        public function getTitle(): string {
            return $this->title;
        }
    }
    Show answer
    class Book implements Borrowable {
        use BorrowableTrait;
        private string $title;
        public function getTitle(): string {
            return $this->title;
        }
    }
  3. Match each OOP concept

    interface
    defines a contract
    trait
    shares code
    class
    creates instances
    private
    blocks outside access

All lessons in Intermediate