实战:面向对象

本课是Phase 3的综合实战,通过图书管理系统巩固面向对象知识。

项目需求

设计一个图书管理系统,支持:

类设计

实体类

JAVA
// 图书类
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;
    }
    
    // getter/setter
    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 ? "已借出" : "可借");
    }
}

// 读者类
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 + ", 已借:" + borrowedBooks.size() + ")";
    }
}

异常类

JAVA
// 图书已借出异常
public class BookAlreadyBorrowedException extends Exception {
    public BookAlreadyBorrowedException(String message) {
        super(message);
    }
}

// 图书未借出异常
public class BookNotBorrowedException extends Exception {
    public BookNotBorrowedException(String message) {
        super(message);
    }
}

// 读者不存在异常
public class ReaderNotFoundException extends Exception {
    public ReaderNotFoundException(String message) {
        super(message);
    }
}

接口

JAVA
// 图书管理接口
public interface BookManager {
    void addBook(Book book);
    void removeBook(String isbn);
    Book findBook(String isbn);
    List<Book> getAllBooks();
}

// 读者管理接口
public interface ReaderManager {
    void addReader(Reader reader);
    void removeReader(String id);
    Reader findReader(String id);
    List<Reader> getAllReaders();
}

管理类

JAVA
import java.util.*;

// 图书馆类
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<>();
    }
    
    // 图书管理
    @Override
    public void addBook(Book book) {
        books.put(book.getIsbn(), book);
        System.out.println("添加图书:" + book.getTitle());
    }
    
    @Override
    public void removeBook(String isbn) {
        Book book = books.remove(isbn);
        if (book != null) {
            System.out.println("删除图书:" + book.getTitle());
        } else {
            System.out.println("图书不存在");
        }
    }
    
    @Override
    public Book findBook(String isbn) {
        return books.get(isbn);
    }
    
    @Override
    public List<Book> getAllBooks() {
        return new ArrayList<>(books.values());
    }
    
    // 读者管理
    @Override
    public void addReader(Reader reader) {
        readers.put(reader.getId(), reader);
        System.out.println("添加读者:" + reader.getName());
    }
    
    @Override
    public void removeReader(String id) {
        Reader reader = readers.remove(id);
        if (reader != null) {
            System.out.println("删除读者:" + reader.getName());
        } else {
            System.out.println("读者不存在");
        }
    }
    
    @Override
    public Reader findReader(String id) {
        return readers.get(id);
    }
    
    @Override
    public List<Reader> getAllReaders() {
        return new ArrayList<>(readers.values());
    }
    
    // 借书
    public void borrowBook(String isbn, String readerId) 
            throws BookAlreadyBorrowedException, ReaderNotFoundException {
        Book book = books.get(isbn);
        if (book == null) {
            System.out.println("图书不存在");
            return;
        }
        
        if (book.isBorrowed()) {
            throw new BookAlreadyBorrowedException("图书已借出:" + book.getTitle());
        }
        
        Reader reader = readers.get(readerId);
        if (reader == null) {
            throw new ReaderNotFoundException("读者不存在:" + readerId);
        }
        
        book.setBorrowed(true);
        reader.borrowBook(book);
        System.out.println(reader.getName() + " 借阅 " + book.getTitle());
    }
    
    // 还书
    public void returnBook(String isbn, String readerId) 
            throws BookNotBorrowedException, ReaderNotFoundException {
        Book book = books.get(isbn);
        if (book == null) {
            System.out.println("图书不存在");
            return;
        }
        
        if (!book.isBorrowed()) {
            throw new BookNotBorrowedException("图书未借出:" + book.getTitle());
        }
        
        Reader reader = readers.get(readerId);
        if (reader == null) {
            throw new ReaderNotFoundException("读者不存在:" + readerId);
        }
        
        book.setBorrowed(false);
        reader.returnBook(book);
        System.out.println(reader.getName() + " 归还 " + book.getTitle());
    }
}

主程序

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) {
        // 初始化数据
        initData();
        
        // 主循环
        int choice;
        do {
            showMenu();
            choice = scanner.nextInt();
            scanner.nextLine();  // 消耗换行符
            
            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("再见!"); break;
                default: System.out.println("无效选择");
            }
        } while (choice != 0);
        
        scanner.close();
    }
    
    private static void initData() {
        library.addBook(new Book("978-7-111-40701-0", "Java编程思想", "Bruce Eckel"));
        library.addBook(new Book("978-7-111-21382-6", "设计模式", "GoF"));
        library.addBook(new Book("978-7-115-22170-8", "算法导论", "CLRS"));
        
        library.addReader(new Reader("R001", "张三"));
        library.addReader(new Reader("R002", "李四"));
    }
    
    private static void showMenu() {
        System.out.println("\n=== 图书管理系统 ===");
        System.out.println("1. 查看所有图书");
        System.out.println("2. 查看所有读者");
        System.out.println("3. 借书");
        System.out.println("4. 还书");
        System.out.println("5. 添加图书");
        System.out.println("6. 添加读者");
        System.out.println("0. 退出");
        System.out.print("请选择:");
    }
    
    private static void listBooks() {
        System.out.println("\n--- 图书列表 ---");
        for (Book book : library.getAllBooks()) {
            System.out.println(book);
        }
    }
    
    private static void listReaders() {
        System.out.println("\n--- 读者列表 ---");
        for (Reader reader : library.getAllReaders()) {
            System.out.println(reader);
        }
    }
    
    private static void borrowBook() {
        System.out.print("请输入ISBN:");
        String isbn = scanner.nextLine();
        System.out.print("请输入读者ID:");
        String readerId = scanner.nextLine();
        
        try {
            library.borrowBook(isbn, readerId);
        } catch (BookAlreadyBorrowedException | ReaderNotFoundException e) {
            System.out.println("错误:" + e.getMessage());
        }
    }
    
    private static void returnBook() {
        System.out.print("请输入ISBN:");
        String isbn = scanner.nextLine();
        System.out.print("请输入读者ID:");
        String readerId = scanner.nextLine();
        
        try {
            library.returnBook(isbn, readerId);
        } catch (BookNotBorrowedException | ReaderNotFoundException e) {
            System.out.println("错误:" + e.getMessage());
        }
    }
    
    private static void addBook() {
        System.out.print("请输入ISBN:");
        String isbn = scanner.nextLine();
        System.out.print("请输入书名:");
        String title = scanner.nextLine();
        System.out.print("请输入作者:");
        String author = scanner.nextLine();
        
        library.addBook(new Book(isbn, title, author));
    }
    
    private static void addReader() {
        System.out.print("请输入读者ID:");
        String id = scanner.nextLine();
        System.out.print("请输入姓名:");
        String name = scanner.nextLine();
        
        library.addReader(new Reader(id, name));
    }
}

运行示例

TEXT
=== 图书管理系统 ===
1. 查看所有图书
2. 查看所有读者
3. 借书
4. 还书
5. 添加图书
6. 添加读者
0. 退出
请选择:1

--- 图书列表 ---
[978-7-111-40701-0] Java编程思想 - Bruce Eckel (可借)
[978-7-111-21382-6] 设计模式 - GoF (可借)
[978-7-115-22170-8] 算法导论 - CLRS (可借)

请选择:3
请输入ISBN:978-7-111-40701-0
请输入读者ID:R001
张三 借阅 Java编程思想

设计要点

要点 说明
封装 属性私有,通过getter/setter访问
继承 接口继承(BookManager、ReaderManager)
多态 接口引用指向实现类
异常处理 自定义异常处理业务错误
集合使用 Map存储图书和读者,List存储借阅记录

❓ 常见问题

Q 如何扩展系统?
A 可以添加图书分类、借阅历史、逾期罚款等功能。
Q 数据如何持久化?
A 可以使用文件IO或数据库存储数据。
Q 如何支持多线程?
A 使用同步机制(synchronized)或并发集合(ConcurrentHashMap)。

📖 小节

📝 作业

  1. 扩展功能: 添加图书分类和按分类查询功能
  2. 借阅历史: 记录借阅历史,支持查看历史记录
  3. 数据持久化: 将数据保存到文件,程序启动时加载

下一课

下一课我们将进入Phase 4,学习 集合框架概览,了解Java集合体系。

100%

🙏 帮我们做得更好

我们是刚上线的编程教程站,几个人的小团队,精力有限。页面虽经检查,难免还有疏漏——链接失效、排版错乱、内容有误、语言生硬……

如果您发现了,麻烦告诉我们,我们会在收到反馈后第一时间进行修复,再次感谢您的光临 🙏