Practice: OOP
This lesson is the hands-on practice for Phase 3, consolidating OOP knowledge through a library management system.
Project Requirements
Design a library management system that supports:
- Book information management (CRUD)
- Reader information management
- Borrowing and returning books
- Exception handling
Class Design
Entity Classes
JAVA
// Book class
public class Book {
private String isbn;
private String title;
private String author;
private boolean borrowed;
public Book(String isbn, String title, String author) {
this.isbn = isbn;
this.title = title;
this.author = author;
this.borrowed = false;
}
// Getters/Setters
public String getIsbn() { return isbn; }
public String getTitle() { return title; }
public String getAuthor() { return author; }
public boolean isBorrowed() { return borrowed; }
public void setBorrowed(boolean borrowed) { this.borrowed = borrowed; }
@Override
public String toString() {
return String.format("[%s] %s - %s (%s)", isbn, title, author, borrowed ? "Borrowed" : "Available");
}
}
// Reader class
public class Reader {
private String id;
private String name;
private List<Book> borrowedBooks;
public Reader(String id, String name) {
this.id = id;
this.name = name;
this.borrowedBooks = new ArrayList<>();
}
public String getId() { return id; }
public String getName() { return name; }
public List<Book> getBorrowedBooks() { return borrowedBooks; }
public void borrowBook(Book book) {
borrowedBooks.add(book);
}
public void returnBook(Book book) {
borrowedBooks.remove(book);
}
@Override
public String toString() {
return name + " (ID:" + id + ", Borrowed:" + borrowedBooks.size() + ")";
}
}
Exception Classes
JAVA
// Book already borrowed exception
public class BookAlreadyBorrowedException extends Exception {
public BookAlreadyBorrowedException(String message) {
super(message);
}
}
// Book not borrowed exception
public class BookNotBorrowedException extends Exception {
public BookNotBorrowedException(String message) {
super(message);
}
}
// Reader not found exception
public class ReaderNotFoundException extends Exception {
public ReaderNotFoundException(String message) {
super(message);
}
}
Interfaces
JAVA
// Book management interface
public interface BookManager {
void addBook(Book book);
void removeBook(String isbn);
Book findBook(String isbn);
List<Book> getAllBooks();
}
// Reader management interface
public interface ReaderManager {
void addReader(Reader reader);
void removeReader(String id);
Reader findReader(String id);
List<Reader> getAllReaders();
}
Manager Class
JAVA
import java.util.*;
// Library class
public class Library implements BookManager, ReaderManager {
private Map<String, Book> books;
private Map<String, Reader> readers;
public Library() {
this.books = new HashMap<>();
this.readers = new HashMap<>();
}
// Book management
@Override
public void addBook(Book book) {
books.put(book.getIsbn(), book);
System.out.println("Added book: " + book.getTitle());
}
@Override
public void removeBook(String isbn) {
Book book = books.remove(isbn);
if (book != null) {
System.out.println("Removed book: " + book.getTitle());
} else {
System.out.println("Book not found");
}
}
@Override
public Book findBook(String isbn) {
return books.get(isbn);
}
@Override
public List<Book> getAllBooks() {
return new ArrayList<>(books.values());
}
// Reader management
@Override
public void addReader(Reader reader) {
readers.put(reader.getId(), reader);
System.out.println("Added reader: " + reader.getName());
}
@Override
public void removeReader(String id) {
Reader reader = readers.remove(id);
if (reader != null) {
System.out.println("Removed reader: " + reader.getName());
} else {
System.out.println("Reader not found");
}
}
@Override
public Reader findReader(String id) {
return readers.get(id);
}
@Override
public List<Reader> getAllReaders() {
return new ArrayList<>(readers.values());
}
// Borrow book
public void borrowBook(String isbn, String readerId)
throws BookAlreadyBorrowedException, ReaderNotFoundException {
Book book = books.get(isbn);
if (book == null) {
System.out.println("Book not found");
return;
}
if (book.isBorrowed()) {
throw new BookAlreadyBorrowedException("Book already borrowed: " + book.getTitle());
}
Reader reader = readers.get(readerId);
if (reader == null) {
throw new ReaderNotFoundException("Reader not found: " + readerId);
}
book.setBorrowed(true);
reader.borrowBook(book);
System.out.println(reader.getName() + " borrowed " + book.getTitle());
}
// Return book
public void returnBook(String isbn, String readerId)
throws BookNotBorrowedException, ReaderNotFoundException {
Book book = books.get(isbn);
if (book == null) {
System.out.println("Book not found");
return;
}
if (!book.isBorrowed()) {
throw new BookNotBorrowedException("Book not borrowed: " + book.getTitle());
}
Reader reader = readers.get(readerId);
if (reader == null) {
throw new ReaderNotFoundException("Reader not found: " + readerId);
}
book.setBorrowed(false);
reader.returnBook(book);
System.out.println(reader.getName() + " returned " + book.getTitle());
}
}
Main Program
JAVA
import java.util.Scanner;
public class LibrarySystem {
private static Library library = new Library();
private static Scanner scanner = new Scanner(System.in);
public static void main(String[] args) {
// Initialize data
initData();
// Main loop
int choice;
do {
showMenu();
choice = scanner.nextInt();
scanner.nextLine(); // Consume newline
switch (choice) {
case 1: listBooks(); break;
case 2: listReaders(); break;
case 3: borrowBook(); break;
case 4: returnBook(); break;
case 5: addBook(); break;
case 6: addReader(); break;
case 0: System.out.println("Goodbye!"); break;
default: System.out.println("Invalid choice");
}
} while (choice != 0);
scanner.close();
}
private static void initData() {
library.addBook(new Book("978-7-111-40701-0", "Java Programming", "Bruce Eckel"));
library.addBook(new Book("978-7-111-21382-6", "Design Patterns", "GoF"));
library.addBook(new Book("978-7-115-22170-8", "Introduction to Algorithms", "CLRS"));
library.addReader(new Reader("R001", "Alice"));
library.addReader(new Reader("R002", "Bob"));
}
private static void showMenu() {
System.out.println("\n=== Library Management System ===");
System.out.println("1. View all books");
System.out.println("2. View all readers");
System.out.println("3. Borrow book");
System.out.println("4. Return book");
System.out.println("5. Add book");
System.out.println("6. Add reader");
System.out.println("0. Exit");
System.out.print("Enter choice: ");
}
private static void listBooks() {
System.out.println("\n--- Book List ---");
for (Book book : library.getAllBooks()) {
System.out.println(book);
}
}
private static void listReaders() {
System.out.println("\n--- Reader List ---");
for (Reader reader : library.getAllReaders()) {
System.out.println(reader);
}
}
private static void borrowBook() {
System.out.print("Enter ISBN: ");
String isbn = scanner.nextLine();
System.out.print("Enter reader ID: ");
String readerId = scanner.nextLine();
try {
library.borrowBook(isbn, readerId);
} catch (BookAlreadyBorrowedException | ReaderNotFoundException e) {
System.out.println("Error: " + e.getMessage());
}
}
private static void returnBook() {
System.out.print("Enter ISBN: ");
String isbn = scanner.nextLine();
System.out.print("Enter reader ID: ");
String readerId = scanner.nextLine();
try {
library.returnBook(isbn, readerId);
} catch (BookNotBorrowedException | ReaderNotFoundException e) {
System.out.println("Error: " + e.getMessage());
}
}
private static void addBook() {
System.out.print("Enter ISBN: ");
String isbn = scanner.nextLine();
System.out.print("Enter title: ");
String title = scanner.nextLine();
System.out.print("Enter author: ");
String author = scanner.nextLine();
library.addBook(new Book(isbn, title, author));
}
private static void addReader() {
System.out.print("Enter reader ID: ");
String id = scanner.nextLine();
System.out.print("Enter name: ");
String name = scanner.nextLine();
library.addReader(new Reader(id, name));
}
}
Example Output
TEXT
=== Library Management System ===
1. View all books
2. View all readers
3. Borrow book
4. Return book
5. Add book
6. Add reader
0. Exit
Enter choice: 1
--- Book List ---
[978-7-111-40701-0] Java Programming - Bruce Eckel (Available)
[978-7-111-21382-6] Design Patterns - GoF (Available)
[978-7-115-22170-8] Introduction to Algorithms - CLRS (Available)
Enter choice: 3
Enter ISBN: 978-7-111-40701-0
Enter reader ID: R001
Alice borrowed Java Programming
Design Highlights
| Aspect | Description |
|---|---|
| Encapsulation | Private attributes, accessed via getters/setters |
| Inheritance | Interface inheritance (BookManager, ReaderManager) |
| Polymorphism | Interface references point to implementation |
| Exception handling | Custom exceptions for business errors |
| Collections | Map for books and readers, List for borrow records |
❓ Frequently Asked Questions
Q How to extend the system?
A Add book categories, borrowing history, overdue fines, etc.
Q How to persist data?
A Use file IO or database to store data.
Q How to support multi-threading?
A Use synchronization (synchronized) or concurrent collections (ConcurrentHashMap).
📖 Summary
- Class design should consider encapsulation, inheritance, polymorphism
- Exception handling makes programs more robust
- Interfaces define contracts, implementations handle specifics
- Collection classes (Map, List) are used for data storage
📝 Exercises
- Extend functionality: Add book categories and category-based search
- Borrowing history: Record borrowing history and support viewing history
- Data persistence: Save data to file and load on program start
Next Lesson
In the next lesson, we'll move to Phase 4 and learn about Collection Framework Overview — understanding the Java collections system.



