面向对象编程(OOP)是Java语言的核心基石,掌握OOP思想对于Java开发者至关重要。本文从类和对象的基本概念出发,深入讲解封装、继承、多态三大特性,并结合抽象类、接口、内部类等高级特性,通过完整的实战代码帮助读者构建坚实的Java编程基础。
![图片[1]-Java面向对象编程完全指南:从基础到高级特性深度解析](https://blogimg.vcvcc.cc/2025/11/20251113123653687-1024x768.png?imageView2/0/format/webp/q/75)
一、类与对象:面向对象的基石
1. 类的基本结构
/**
* 学生类 - 演示类的基本结构
* 包含属性、构造方法、普通方法
*/
public class Student {
// 属性(成员变量)
private String name;
private int age;
private String studentId;
private double score;
// 静态变量 - 类级别共享
private static String schoolName = "清华大学";
private static int studentCount = 0;
// 构造方法
public Student() {
studentCount++;
}
// 带参数的构造方法
public Student(String name, int age, String studentId) {
this.name = name;
this.age = age;
this.studentId = studentId;
studentCount++;
}
// 完整的构造方法
public Student(String name, int age, String studentId, double score) {
this(name, age, studentId); // 调用其他构造方法
this.score = score;
}
// 方法(成员方法)
public void study() {
System.out.println(name + "正在学习...");
}
public void study(String course) {
System.out.println(name + "正在学习" + course);
}
// 封装 - getter和setter方法
public String getName() {
return name;
}
public void setName(String name) {
if (name != null && !name.trim().isEmpty()) {
this.name = name;
}
}
public int getAge() {
return age;
}
public void setAge(int age) {
if (age >= 0 && age <= 150) {
this.age = age;
}
}
public String getStudentId() {
return studentId;
}
public void setStudentId(String studentId) {
this.studentId = studentId;
}
public double getScore() {
return score;
}
public void setScore(double score) {
if (score >= 0 && score <= 100) {
this.score = score;
}
}
// 静态方法
public static String getSchoolName() {
return schoolName;
}
public static int getStudentCount() {
return studentCount;
}
// toString方法
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
", studentId='" + studentId + '\'' +
", score=" + score +
'}';
}
// equals和hashCode方法
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Student student = (Student) o;
return studentId.equals(student.studentId);
}
@Override
public int hashCode() {
return studentId.hashCode();
}
}
2. 对象创建与使用
/**
* 对象创建与使用演示
*/
public class ObjectDemo {
public static void main(String[] args) {
// 1. 使用无参构造方法创建对象
Student student1 = new Student();
student1.setName("张三");
student1.setAge(20);
student1.setStudentId("2023001");
student1.setScore(85.5);
// 2. 使用带参构造方法创建对象
Student student2 = new Student("李四", 21, "2023002");
student2.setScore(92.0);
// 3. 使用完整构造方法创建对象
Student student3 = new Student("王五", 22, "2023003", 78.5);
// 调用对象方法
student1.study();
student2.study("Java编程");
student3.study("数据结构");
// 访问对象属性(通过getter)
System.out.println(student1.getName() + "的成绩是: " + student1.getScore());
// 调用静态方法
System.out.println("学校名称: " + Student.getSchoolName());
System.out.println("学生总数: " + Student.getStudentCount());
// 使用toString方法
System.out.println("学生信息: " + student1);
// 对象比较
Student student4 = new Student("张三", 20, "2023001");
System.out.println("student1 equals student4: " + student1.equals(student4));
System.out.println("student1 == student4: " + (student1 == student4));
// 对象数组
Student[] students = {student1, student2, student3};
for (Student student : students) {
System.out.println(student);
}
}
}
二、封装:数据保护的核心
1. 访问控制修饰符
/**
* 访问控制演示类
*/
class AccessModifierDemo {
// public - 所有类都可访问
public String publicField = "公共字段";
// protected - 同包或子类可访问
protected String protectedField = "受保护字段";
// default (包级私有) - 同包可访问
String defaultField = "默认字段";
// private - 仅本类可访问
private String privateField = "私有字段";
// 提供公共方法访问私有字段
public String getPrivateField() {
return privateField;
}
public void setPrivateField(String privateField) {
this.privateField = privateField;
}
// 方法同样有访问控制
public void publicMethod() {
System.out.println("公共方法");
}
protected void protectedMethod() {
System.out.println("受保护方法");
}
void defaultMethod() {
System.out.println("默认方法");
}
private void privateMethod() {
System.out.println("私有方法");
}
}
/**
* 银行账户类 - 封装的最佳实践
*/
public class BankAccount {
private String accountNumber;
private String accountHolder;
private double balance;
private String password;
public BankAccount(String accountNumber, String accountHolder, double initialBalance, String password) {
this.accountNumber = accountNumber;
this.accountHolder = accountHolder;
this.balance = initialBalance;
this.password = password;
}
// 存款方法
public void deposit(double amount) {
if (amount > 0) {
balance += amount;
System.out.println("存款成功! 当前余额: " + balance);
} else {
System.out.println("存款金额必须大于0");
}
}
// 取款方法 - 包含业务逻辑验证
public boolean withdraw(double amount, String inputPassword) {
if (!verifyPassword(inputPassword)) {
System.out.println("密码错误!");
return false;
}
if (amount <= 0) {
System.out.println("取款金额必须大于0");
return false;
}
if (amount > balance) {
System.out.println("余额不足! 当前余额: " + balance);
return false;
}
balance -= amount;
System.out.println("取款成功! 当前余额: " + balance);
return true;
}
// 查询余额
public double getBalance(String inputPassword) {
if (verifyPassword(inputPassword)) {
return balance;
} else {
System.out.println("密码错误!");
return -1;
}
}
// 修改密码
public boolean changePassword(String oldPassword, String newPassword) {
if (verifyPassword(oldPassword)) {
if (newPassword.length() >= 6) {
this.password = newPassword;
System.out.println("密码修改成功!");
return true;
} else {
System.out.println("新密码长度必须至少6位");
return false;
}
} else {
System.out.println("原密码错误!");
return false;
}
}
// 私有方法 - 密码验证
private boolean verifyPassword(String inputPassword) {
return this.password.equals(inputPassword);
}
// getter方法
public String getAccountNumber() {
return accountNumber;
}
public String getAccountHolder() {
return accountHolder;
}
// 没有提供balance和password的setter,保护数据安全
}
/**
* 封装演示
*/
public class EncapsulationDemo {
public static void main(String[] args) {
// 创建银行账户
BankAccount account = new BankAccount("123456789", "张三", 1000.0, "123456");
// 测试存款
account.deposit(500.0);
// 测试取款
account.withdraw(200.0, "123456"); // 正确密码
account.withdraw(200.0, "wrong"); // 错误密码
account.withdraw(2000.0, "123456"); // 余额不足
// 查询余额
double balance = account.getBalance("123456");
System.out.println("当前余额: " + balance);
// 修改密码
account.changePassword("123456", "new123");
account.withdraw(100.0, "new123"); // 使用新密码
// 无法直接访问私有字段
// account.balance = 1000000; // 编译错误
// System.out.println(account.password); // 编译错误
}
}
三、继承:代码复用的艺术
1. 继承的基本概念
/**
* 父类 - 人类
*/
class Person {
private String name;
private int age;
private String gender;
public Person() {
System.out.println("Person无参构造方法被调用");
}
public Person(String name, int age, String gender) {
this.name = name;
this.age = age;
this.gender = gender;
System.out.println("Person带参构造方法被调用");
}
public void eat() {
System.out.println(name + "正在吃饭");
}
public void sleep() {
System.out.println(name + "正在睡觉");
}
public void introduce() {
System.out.println("我叫" + name + ", 今年" + age + "岁, 性别" + gender);
}
// getter和setter
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
}
/**
* 学生类 - 继承人类
*/
class Student extends Person {
private String studentId;
private String major;
private double score;
public Student() {
super(); // 调用父类构造方法
System.out.println("Student无参构造方法被调用");
}
public Student(String name, int age, String gender, String studentId, String major) {
super(name, age, gender); // 调用父类构造方法
this.studentId = studentId;
this.major = major;
System.out.println("Student带参构造方法被调用");
}
// 学生特有的方法
public void study() {
System.out.println(getName() + "正在学习" + major);
}
public void takeExam() {
System.out.println(getName() + "正在参加考试");
}
// 重写父类方法
@Override
public void introduce() {
super.introduce(); // 调用父类方法
System.out.println("我是学生, 学号:" + studentId + ", 专业:" + major);
}
// getter和setter
public String getStudentId() {
return studentId;
}
public void setStudentId(String studentId) {
this.studentId = studentId;
}
public String getMajor() {
return major;
}
public void setMajor(String major) {
this.major = major;
}
public double getScore() {
return score;
}
public void setScore(double score) {
this.score = score;
}
}
/**
* 教师类 - 继承人类
*/
class Teacher extends Person {
private String teacherId;
private String department;
private double salary;
public Teacher(String name, int age, String gender, String teacherId, String department) {
super(name, age, gender);
this.teacherId = teacherId;
this.department = department;
}
// 教师特有的方法
public void teach() {
System.out.println(getName() + "正在教学");
}
public void correctHomework() {
System.out.println(getName() + "正在批改作业");
}
// 重写父类方法
@Override
public void introduce() {
super.introduce();
System.out.println("我是教师, 工号:" + teacherId + ", 部门:" + department);
}
// getter和setter
public String getTeacherId() {
return teacherId;
}
public void setTeacherId(String teacherId) {
this.teacherId = teacherId;
}
public String getDepartment() {
return department;
}
public void setDepartment(String department) {
this.department = department;
}
public double getSalary() {
return salary;
}
public void setSalary(double salary) {
this.salary = salary;
}
}
/**
* 继承演示
*/
public class InheritanceDemo {
public static void main(String[] args) {
// 创建学生对象
Student student = new Student("李明", 20, "男", "2023001", "计算机科学");
student.eat(); // 继承自Person
student.sleep(); // 继承自Person
student.study(); // Student特有
student.introduce();// 重写的方法
System.out.println();
// 创建教师对象
Teacher teacher = new Teacher("张老师", 35, "女", "T1001", "计算机学院");
teacher.eat(); // 继承自Person
teacher.teach(); // Teacher特有
teacher.introduce();// 重写的方法
System.out.println();
// 多态演示
Person person1 = new Student("王同学", 19, "女", "2023002", "软件工程");
Person person2 = new Teacher("李老师", 40, "男", "T1002", "数学学院");
person1.introduce(); // 实际调用Student的introduce
person2.introduce(); // 实际调用Teacher的introduce
// 类型判断和转换
if (person1 instanceof Student) {
Student s = (Student) person1;
s.study();
}
}
}
2. 方法重写与super关键字
/**
* 图形类 - 演示方法重写
*/
class Shape {
private String color;
public Shape(String color) {
this.color = color;
}
// 计算面积 - 在父类中定义为抽象方法更合适,这里先这样写
public double calculateArea() {
System.out.println("计算图形面积");
return 0.0;
}
// 计算周长
public double calculatePerimeter() {
System.out.println("计算图形周长");
return 0.0;
}
public void displayInfo() {
System.out.println("图形颜色: " + color);
}
public String getColor() {
return color;
}
}
/**
* 圆形类 - 继承图形类
*/
class Circle extends Shape {
private double radius;
public Circle(String color, double radius) {
super(color); // 调用父类构造方法
this.radius = radius;
}
// 重写计算面积方法
@Override
public double calculateArea() {
return Math.PI * radius * radius;
}
// 重写计算周长方法
@Override
public double calculatePerimeter() {
return 2 * Math.PI * radius;
}
// 重写显示信息方法,同时调用父类方法
@Override
public void displayInfo() {
super.displayInfo(); // 调用父类方法
System.out.println("图形类型: 圆形");
System.out.println("半径: " + radius);
System.out.println("面积: " + calculateArea());
System.out.println("周长: " + calculatePerimeter());
}
public double getRadius() {
return radius;
}
}
/**
* 矩形类 - 继承图形类
*/
class Rectangle extends Shape {
private double width;
private double height;
public Rectangle(String color, double width, double height) {
super(color);
this.width = width;
this.height = height;
}
@Override
public double calculateArea() {
return width * height;
}
@Override
public double calculatePerimeter() {
return 2 * (width + height);
}
@Override
public void displayInfo() {
super.displayInfo();
System.out.println("图形类型: 矩形");
System.out.println("宽度: " + width + ", 高度: " + height);
System.out.println("面积: " + calculateArea());
System.out.println("周长: " + calculatePerimeter());
}
public double getWidth() {
return width;
}
public double getHeight() {
return height;
}
}
/**
* 方法重写演示
*/
public class MethodOverrideDemo {
public static void main(String[] args) {
Circle circle = new Circle("红色", 5.0);
Rectangle rectangle = new Rectangle("蓝色", 4.0, 6.0);
circle.displayInfo();
System.out.println();
rectangle.displayInfo();
// 多态数组
Shape[] shapes = {
new Circle("绿色", 3.0),
new Rectangle("黄色", 5.0, 8.0),
new Circle("紫色", 2.5)
};
System.out.println("\n多态数组演示:");
double totalArea = 0;
for (Shape shape : shapes) {
shape.displayInfo();
totalArea += shape.calculateArea();
System.out.println();
}
System.out.println("所有图形总面积: " + totalArea);
}
}
四、多态:面向对象的精髓
1. 多态的实现方式
/**
* 动物类 - 多态演示
*/
abstract class Animal {
private String name;
private int age;
public Animal(String name, int age) {
this.name = name;
this.age = age;
}
// 抽象方法 - 子类必须实现
public abstract void makeSound();
public abstract void eat();
// 具体方法
public void sleep() {
System.out.println(name + "正在睡觉...");
}
// 模板方法模式
public void dailyRoutine() {
System.out.println("=== " + name + "的日常 ===");
eat();
makeSound();
sleep();
System.out.println();
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
}
/**
* 狗类
*/
class Dog extends Animal {
private String breed;
public Dog(String name, int age, String breed) {
super(name, age);
this.breed = breed;
}
@Override
public void makeSound() {
System.out.println(getName() + "汪汪叫!");
}
@Override
public void eat() {
System.out.println(getName() + "正在吃狗粮");
}
// 狗特有的方法
public void fetch() {
System.out.println(getName() + "正在接飞盘");
}
public String getBreed() {
return breed;
}
}
/**
* 猫类
*/
class Cat extends Animal {
private boolean isIndoor;
public Cat(String name, int age, boolean isIndoor) {
super(name, age);
this.isIndoor = isIndoor;
}
@Override
public void makeSound() {
System.out.println(getName() + "喵喵叫!");
}
@Override
public void eat() {
System.out.println(getName() + "正在吃猫粮");
}
// 猫特有的方法
public void climbTree() {
System.out.println(getName() + "正在爬树");
}
public boolean isIndoor() {
return isIndoor;
}
}
/**
* 鸟类
*/
class Bird extends Animal {
private boolean canFly;
public Bird(String name, int age, boolean canFly) {
super(name, age);
this.canFly = canFly;
}
@Override
public void makeSound() {
System.out.println(getName() + "叽叽喳喳!");
}
@Override
public void eat() {
System.out.println(getName() + "正在吃谷物");
}
// 鸟特有的方法
public void fly() {
if (canFly) {
System.out.println(getName() + "正在飞翔");
} else {
System.out.println(getName() + "不会飞");
}
}
public boolean canFly() {
return canFly;
}
}
/**
* 多态演示
*/
public class PolymorphismDemo {
public static void main(String[] args) {
// 创建不同类型的动物
Animal dog = new Dog("旺财", 3, "金毛");
Animal cat = new Cat("咪咪", 2, true);
Animal bird = new Bird("小飞", 1, true);
Animal penguin = new Bird("企鹅", 4, false);
// 多态数组
Animal[] animals = {dog, cat, bird, penguin};
System.out.println("=== 多态方法调用 ===");
for (Animal animal : animals) {
animal.dailyRoutine();
}
System.out.println("=== 类型检查和转换 ===");
for (Animal animal : animals) {
animal.makeSound();
// 类型检查和特定方法调用
if (animal instanceof Dog) {
Dog d = (Dog) animal;
d.fetch();
} else if (animal instanceof Cat) {
Cat c = (Cat) animal;
c.climbTree();
} else if (animal instanceof Bird) {
Bird b = (Bird) animal;
b.fly();
}
System.out.println();
}
System.out.println("=== 方法参数多态 ===");
AnimalCareTaker careTaker = new AnimalCareTaker();
for (Animal animal : animals) {
careTaker.careForAnimal(animal);
}
}
}
/**
* 动物护理员 - 演示方法参数多态
*/
class AnimalCareTaker {
public void careForAnimal(Animal animal) {
System.out.println("护理员正在照顾 " + animal.getName());
animal.eat();
// 根据具体类型提供特殊护理
if (animal instanceof Dog) {
System.out.println("给狗狗梳毛");
} else if (animal instanceof Cat) {
System.out.println("给猫咪清理猫砂");
} else if (animal instanceof Bird) {
System.out.println("给鸟儿换水");
}
System.out.println();
}
}
2. 接口与多态
/**
* 接口演示 - 可飞行的接口
*/
interface Flyable {
// 接口常量
int MAX_ALTITUDE = 10000;
// 抽象方法
void fly();
// 默认方法 - Java 8新特性
default void takeOff() {
System.out.println("准备起飞...");
}
default void land() {
System.out.println("准备降落...");
}
// 静态方法 - Java 8新特性
static void showMaxAltitude() {
System.out.println("最大飞行高度: " + MAX_ALTITUDE + "米");
}
}
/**
* 可游泳的接口
*/
interface Swimmable {
void swim();
default void dive() {
System.out.println("潜入水中...");
}
}
/**
* 可奔跑的接口
*/
interface Runnable {
void run();
default void sprint() {
System.out.println("全力冲刺!");
}
}
/**
* 鸭子类 - 实现多个接口
*/
class Duck implements Flyable, Swimmable, Runnable {
private String name;
public Duck(String name) {
this.name = name;
}
@Override
public void fly() {
System.out.println(name + "在天空中飞翔");
}
@Override
public void swim() {
System.out.println(name + "在水中游泳");
}
@Override
public void run() {
System.out.println(name + "在陆地上奔跑");
}
public void displayAbilities() {
System.out.println("=== " + name + "的能力 ===");
takeOff();
fly();
land();
swim();
dive();
run();
sprint();
}
}
/**
* 飞机类 - 实现飞行接口
*/
class Airplane implements Flyable {
private String model;
public Airplane(String model) {
this.model = model;
}
@Override
public void fly() {
System.out.println(model + "飞机在万米高空飞行");
}
@Override
public void takeOff() {
System.out.println(model + "在跑道上加速起飞");
}
@Override
public void land() {
System.out.println(model + "正在降落,放下起落架");
}
}
/**
* 鱼类 - 实现游泳接口
*/
class Fish implements Swimmable {
private String species;
public Fish(String species) {
this.species = species;
}
@Override
public void swim() {
System.out.println(species + "在水中自由游动");
}
@Override
public void dive() {
System.out.println(species + "潜入深水区");
}
}
/**
* 接口多态演示
*/
public class InterfacePolymorphismDemo {
public static void main(String[] args) {
// 调用接口静态方法
Flyable.showMaxAltitude();
System.out.println();
// 多态数组 - 接口类型引用
Flyable[] flyables = {
new Duck("唐老鸭"),
new Airplane("波音747")
};
System.out.println("=== 飞行能力演示 ===");
for (Flyable flyable : flyables) {
flyable.takeOff();
flyable.fly();
flyable.land();
System.out.println();
}
// 多接口实现
Duck donald = new Duck("唐老鸭");
donald.displayAbilities();
System.out.println();
// 接口类型参数
testFlyable(new Airplane("空客A380"));
testSwimmable(new Fish("金鱼"));
testRunnable(donald);
// 接口组合
testAmphibious(donald);
}
// 接口类型作为方法参数
public static void testFlyable(Flyable flyable) {
System.out.println("=== 测试飞行能力 ===");
flyable.takeOff();
flyable.fly();
flyable.land();
System.out.println();
}
public static void testSwimmable(Swimmable swimmable) {
System.out.println("=== 测试游泳能力 ===");
swimmable.dive();
swimmable.swim();
System.out.println();
}
public static void testRunnable(Runnable runnable) {
System.out.println("=== 测试奔跑能力 ===");
runnable.run();
runnable.sprint();
System.out.println();
}
// 多接口参数
public static void testAmphibious(Object obj) {
System.out.println("=== 两栖能力测试 ===");
if (obj instanceof Flyable && obj instanceof Swimmable) {
System.out.println("这个对象具有两栖能力!");
Flyable flyable = (Flyable) obj;
Swimmable swimmable = (Swimmable) obj;
flyable.fly();
swimmable.swim();
} else {
System.out.println("这个对象不具备两栖能力");
}
System.out.println();
}
}
五、抽象类与接口的对比
1. 抽象类的使用
/**
* 员工抽象类
*/
abstract class Employee {
private String name;
private int id;
private double salary;
public Employee(String name, int id, double salary) {
this.name = name;
this.id = id;
this.salary = salary;
}
// 抽象方法 - 子类必须实现
public abstract void work();
public abstract double calculateAnnualBonus();
// 具体方法
public void attendMeeting() {
System.out.println(name + "正在参加会议");
}
public void takeBreak() {
System.out.println(name + "正在休息");
}
// 模板方法
public final void dailyRoutine() {
System.out.println("=== " + name + "的日常工作 ===");
work();
attendMeeting();
takeBreak();
System.out.println("年终奖金: " + calculateAnnualBonus());
System.out.println();
}
// getter和setter
public String getName() {
return name;
}
public int getId() {
return id;
}
public double getSalary() {
return salary;
}
public void setSalary(double salary) {
this.salary = salary;
}
}
/**
* 开发人员类
*/
class Developer extends Employee {
private String programmingLanguage;
public Developer(String name, int id, double salary, String programmingLanguage) {
super(name, id, salary);
this.programmingLanguage = programmingLanguage;
}
@Override
public void work() {
System.out.println(getName() + "正在用" + programmingLanguage + "编写代码");
}
@Override
public double calculateAnnualBonus() {
return getSalary() * 2; // 开发人员年终奖为2个月工资
}
public void debugCode() {
System.out.println(getName() + "正在调试代码");
}
public String getProgrammingLanguage() {
return programmingLanguage;
}
}
/**
* 经理类
*/
class Manager extends Employee {
private int teamSize;
public Manager(String name, int id, double salary, int teamSize) {
super(name, id, salary);
this.teamSize = teamSize;
}
@Override
public void work() {
System.out.println(getName() + "正在管理" + teamSize + "人的团队");
}
@Override
public double calculateAnnualBonus() {
return getSalary() * 3 + teamSize * 1000; // 经理年终奖更复杂
}
public void conductInterview() {
System.out.println(getName() + "正在面试候选人");
}
public int getTeamSize() {
return teamSize;
}
}
/**
* 抽象类演示
*/
public class AbstractClassDemo {
public static void main(String[] args) {
Employee developer = new Developer("张三", 1001, 15000, "Java");
Employee manager = new Manager("李四", 1002, 25000, 10);
developer.dailyRoutine();
manager.dailyRoutine();
// 多态数组
Employee[] employees = {
new Developer("王五", 1003, 12000, "Python"),
new Manager("赵六", 1004, 30000, 15),
new Developer("钱七", 1005, 18000, "JavaScript")
};
System.out.println("=== 所有员工日常工作 ===");
for (Employee employee : employees) {
employee.dailyRoutine();
}
// 计算总年终奖
double totalBonus = 0;
for (Employee employee : employees) {
totalBonus += employee.calculateAnnualBonus();
}
System.out.println("所有员工总年终奖: " + totalBonus);
}
}
六、综合案例:图书馆管理系统
import java.util.ArrayList;
import java.util.List;
/**
* 图书类
*/
class Book {
private String isbn;
private String title;
private String author;
private int publicationYear;
private boolean isBorrowed;
public Book(String isbn, String title, String author, int publicationYear) {
this.isbn = isbn;
this.title = title;
this.author = author;
this.publicationYear = publicationYear;
this.isBorrowed = false;
}
public void borrow() {
if (!isBorrowed) {
isBorrowed = true;
System.out.println("成功借出: " + title);
} else {
System.out.println("书籍已被借出: " + title);
}
}
public void returnBook() {
if (isBorrowed) {
isBorrowed = false;
System.out.println("成功归还: " + title);
} else {
System.out.println("书籍未被借出: " + title);
}
}
// getter方法
public String getIsbn() { return isbn; }
public String getTitle() { return title; }
public String getAuthor() { return author; }
public int getPublicationYear() { return publicationYear; }
public boolean isBorrowed() { return isBorrowed; }
@Override
public String toString() {
return String.format("ISBN: %s, 书名: %s, 作者: %s, 出版年: %d, 状态: %s",
isbn, title, author, publicationYear,
isBorrowed ? "已借出" : "可借阅");
}
}
/**
* 用户抽象类
*/
abstract class User {
private String userId;
private String name;
private String email;
protected List<Book> borrowedBooks;
public User(String userId, String name, String email) {
this.userId = userId;
this.name = name;
this.email = email;
this.borrowedBooks = new ArrayList<>();
}
// 抽象方法
public abstract boolean canBorrow();
public abstract int getMaxBorrowLimit();
// 具体方法
public void borrowBook(Book book) {
if (canBorrow() && borrowedBooks.size() < getMaxBorrowLimit()) {
if (!book.isBorrowed()) {
book.borrow();
borrowedBooks.add(book);
System.out.println(name + " 成功借阅: " + book.getTitle());
} else {
System.out.println("书籍已被借出: " + book.getTitle());
}
} else {
System.out.println(name + " 无法借阅更多书籍");
}
}
public void returnBook(Book book) {
if (borrowedBooks.contains(book)) {
book.returnBook();
borrowedBooks.remove(book);
System.out.println(name + " 成功归还: " + book.getTitle());
} else {
System.out.println(name + " 未借阅此书: " + book.getTitle());
}
}
public void displayBorrowedBooks() {
System.out.println(name + " 借阅的书籍:");
if (borrowedBooks.isEmpty()) {
System.out.println(" 无借阅记录");
} else {
for (Book book : borrowedBooks) {
System.out.println(" - " + book.getTitle());
}
}
}
// getter方法
public String getUserId() { return userId; }
public String getName() { return name; }
public String getEmail() { return email; }
public List<Book> getBorrowedBooks() { return borrowedBooks; }
}
/**
* 学生用户
*/
class Student extends User {
private String studentId;
private String major;
public Student(String userId, String name, String email, String studentId, String major) {
super(userId, name, email);
this.studentId = studentId;
this.major = major;
}
@Override
public boolean canBorrow() {
return true;
}
@Override
public int getMaxBorrowLimit() {
return 5; // 学生最多借5本书
}
public String getStudentId() { return studentId; }
public String getMajor() { return major; }
}
/**
* 教师用户
*/
class Teacher extends User {
private String teacherId;
private String department;
public Teacher(String userId, String name, String email, String teacherId, String department) {
super(userId, name, email);
this.teacherId = teacherId;
this.department = department;
}
@Override
public boolean canBorrow() {
return true;
}
@Override
public int getMaxBorrowLimit() {
return 10; // 教师最多借10本书
}
public String getTeacherId() { return teacherId; }
public String getDepartment() { return department; }
}
/**
* 图书馆类
*/
class Library {
private String name;
private List<Book> books;
private List<User> users;
public Library(String name) {
this.name = name;
this.books = new ArrayList<>();
this.users = new ArrayList<>();
}
public void addBook(Book book) {
books.add(book);
System.out.println("添加书籍: " + book.getTitle());
}
public void addUser(User user) {
users.add(user);
System.out.println("添加用户: " + user.getName());
}
public void displayAllBooks() {
System.out.println("=== " + name + " 所有书籍 ===");
for (Book book : books) {
System.out.println(book);
}
System.out.println();
}
public void displayAllUsers() {
System.out.println("=== " + name + " 所有用户 ===");
for (User user : users) {
System.out.println(user.getName() + " (" + user.getClass().getSimpleName() + ")");
}
System.out.println();
}
public Book findBookByTitle(String title) {
for (Book book : books) {
if (book.getTitle().equalsIgnoreCase(title)) {
return book;
}
}
return null;
}
public User findUserById(String userId) {
for (User user : users) {
if (user.getUserId().equals(userId)) {
return user;
}
}
return null;
}
// getter方法
public String getName() { return name; }
public List<Book> getBooks() { return books; }
public List<User> getUsers() { return users; }
}
/**
* 图书馆管理系统演示
*/
public class LibraryManagementSystem {
public static void main(String[] args) {
// 创建图书馆
Library library = new Library("市立图书馆");
// 添加书籍
library.addBook(new Book("9787111126768", "Java编程思想", "Bruce Eckel", 2007));
library.addBook(new Book("9787115216878", "Effective Java", "Joshua Bloch", 2009));
library.addBook(new Book("9787121022986", "设计模式", "Erich Gamma", 2010));
library.addBook(new Book("9787302275951", "算法导论", "Thomas Cormen", 2013));
// 添加用户
library.addUser(new Student("S001", "张三", "zhangsan@email.com", "2023001", "计算机科学"));
library.addUser(new Student("S002", "李四", "lisi@email.com", "2023002", "软件工程"));
library.addUser(new Teacher("T001", "王教授", "wang@email.com", "T1001", "计算机学院"));
System.out.println();
// 显示所有信息
library.displayAllBooks();
library.displayAllUsers();
// 借书操作
User student1 = library.findUserById("S001");
User teacher1 = library.findUserById("T001");
Book javaBook = library.findBookByTitle("Java编程思想");
Book effectiveJava = library.findBookByTitle("Effective Java");
Book designPatterns = library.findBookByTitle("设计模式");
Book algorithms = library.findBookByTitle("算法导论");
System.out.println("=== 借书操作 ===");
if (student1 != null && javaBook != null) {
student1.borrowBook(javaBook);
}
if (teacher1 != null && effectiveJava != null) {
teacher1.borrowBook(effectiveJava);
}
// 同一个学生借多本书
if (student1 != null) {
student1.borrowBook(designPatterns);
student1.borrowBook(algorithms);
}
System.out.println();
// 显示借阅情况
System.out.println("=== 借阅情况 ===");
for (User user : library.getUsers()) {
user.displayBorrowedBooks();
System.out.println();
}
// 还书操作
System.out.println("=== 还书操作 ===");
if (student1 != null && javaBook != null) {
student1.returnBook(javaBook);
}
// 再次显示借阅情况
System.out.println("\n=== 最终借阅情况 ===");
for (User user : library.getUsers()) {
user.displayBorrowedBooks();
System.out.println();
}
// 显示所有书籍状态
library.displayAllBooks();
}
}
七、总结与最佳实践
通过本文的系统学习,读者应该掌握:
1. 面向对象核心概念
- 类与对象:类是蓝图,对象是实例
- 封装:数据保护,提供安全的访问接口
- 继承:代码复用,建立is-a关系
- 多态:同一接口,不同实现
2. Java OOP特性
- 访问控制修饰符的正确使用
- 方法重写与重载的区别
- 抽象类与接口的应用场景
- 构造方法链和super关键字
3. 设计原则
- 单一职责原则
- 开闭原则
- 里氏替换原则
- 接口隔离原则
- 依赖倒置原则
4. 最佳实践建议
- 封装性:所有字段私有,通过方法访问
- 继承层次:不超过3层,避免过度设计
- 接口设计:小而专,避免臃肿接口
- 多态应用:面向接口编程,提高灵活性
- 代码复用:合理使用组合和继承
通过掌握这些面向对象编程的核心概念和Java实现,开发者可以构建出结构清晰、易于维护、可扩展的Java应用程序。
© 版权声明
THE END












暂无评论内容