java-2

面向对象高级 - 继承篇

01 什么是继承?

知识点讲解

继承是面向对象三大特征(封装、继承、多态)之一,是 Java 实现代码复用的核心机制。

  • 定义:让一个类(子类 / 派生类)获得另一个类(父类 / 基类 / 超类)的属性和方法,子类可直接使用父类非私有成员,也可以扩展自己的特有功能。
  • 关键字:extends,语法:class 子类名 extends 父类名 { }
  • 核心价值:抽取共性代码,减少重复;为多态提供语法基础。
  • 逻辑关系:必须满足 is-a(子类是父类的一种),例如 "猫是动物""学生是人"。

例题:动物类基础继承

需求:定义父类Animal(共性属性:姓名、年龄;共性方法:吃饭、睡觉),定义子类CatDog,继承父类并添加特有行为。

java

复制代码
// 父类:动物类
class Animal {
    // 公共属性
    String name;
    int age;

    // 公共方法
    public void eat() {
        System.out.println(name + "在吃饭");
    }

    public void sleep() {
        System.out.println(name + "在睡觉,今年" + age + "岁");
    }
}

// 子类:猫类,继承Animal
class Cat extends Animal {
    // 子类特有方法
    public void catchMouse() {
        System.out.println(name + "在抓老鼠");
    }
}

// 子类:狗类,继承Animal
class Dog extends Animal {
    // 子类特有方法
    public void lookHome() {
        System.out.println(name + "在看家");
    }
}

// 测试类
public class Demo01_ExtendsIntro {
    public static void main(String[] args) {
        Cat cat = new Cat();
        cat.name = "橘猫";
        cat.age = 2;
        cat.eat();      // 继承自父类
        cat.sleep();    // 继承自父类
        cat.catchMouse();// 子类特有

        System.out.println("----------");

        Dog dog = new Dog();
        dog.name = "中华田园犬";
        dog.age = 3;
        dog.eat();
        dog.sleep();
        dog.lookHome();
    }
}

运行结果:

plaintext

复制代码
橘猫在吃饭
橘猫在睡觉,今年2岁
橘猫在抓老鼠
----------
中华田园犬在吃饭
中华田园犬在睡觉,今年3岁
中华田园犬在看家

02 如何设计一个复杂的继承体系?

知识点讲解

设计复杂继承体系的核心原则:共性向上抽取,特性向下扩展,形成层级化的类树。设计步骤:

  1. 梳理所有类的共性属性与方法,抽取到最顶层父类;
  2. 不同子类的特有属性与方法,留在子类中定义;
  3. 支持多层继承(爷爷类→父类→子类),逐级细化;
  4. 禁止为了复用代码强行继承,必须符合 "is-a" 逻辑。

典型场景:公司员工体系 → 顶层员工 → 细分正式员工 / 临时工 → 正式员工再细分研发 / 产品岗。

例题:公司员工继承体系

需求:设计三级员工继承体系:

  • 顶层:Employee(工号、姓名、基本工资;工作、领工资方法)
  • 二级:FullTimeEmployee正式员工(年终奖;发年终奖方法)、PartTimeEmployee临时工(时薪、工时;结算薪资方法)
  • 三级:Developer程序员(敲代码方法),继承正式员工

java

复制代码
// 顶层父类:员工
class Employee {
    String id;      // 工号
    String name;    // 姓名
    double salary;  // 基本工资

    public void work() {
        System.out.println(name + "在上班工作");
    }

    public void getSalary() {
        System.out.println(name + "领取基本工资:" + salary + "元");
    }
}

// 子类:正式员工
class FullTimeEmployee extends Employee {
    double yearBonus; // 年终奖

    public void getYearBonus() {
        System.out.println(name + "领取年终奖:" + yearBonus + "元");
    }
}

// 子类:临时工
class PartTimeEmployee extends Employee {
    double hourSalary; // 时薪
    int workHours;     // 工作时长

    public void calcHourSalary() {
        double total = hourSalary * workHours;
        System.out.println(name + "临时工结算薪资:" + total + "元");
    }
}

// 正式员工的子类:程序员
class Developer extends FullTimeEmployee {
    public void coding() {
        System.out.println(name + "程序员在写Java代码");
    }
}

// 测试类
public class Demo02_ExtendsDesign {
    public static void main(String[] args) {
        Developer dev = new Developer();
        dev.id = "R001";
        dev.name = "张三";
        dev.salary = 12000;
        dev.yearBonus = 36000;

        dev.work();       // 爷爷类方法
        dev.getSalary();  // 爷爷类方法
        dev.getYearBonus();// 父类方法
        dev.coding();     // 自身方法

        System.out.println("----------");

        PartTimeEmployee pt = new PartTimeEmployee();
        pt.name = "李四";
        pt.hourSalary = 80;
        pt.workHours = 120;
        pt.work();
        pt.calcHourSalary();
    }
}

运行结果:

plaintext

复制代码
张三在上班工作
张三领取基本工资:12000.0元
张三领取年终奖:36000.0元
张三程序员在写Java代码
----------
李四在上班工作
李四临时工结算薪资:9600.0元

03 继承的特点

知识点讲解

Java 继承有三个核心规则:

  1. 单继承限制 :一个类只能有一个直接父类(不支持多继承,避免多个父类同名方法冲突);
  2. 多层继承:支持间接继承(爷爷类、曾祖父类),子类可继承整条继承链上的非私有成员;
  3. Object 根类 :所有类都直接或间接继承自java.lang.Object,它是 Java 所有类的根父类。

补充:一个父类可以拥有多个子类。

例题:验证继承三大特点

需求:设计A→B→C多层继承,验证单继承、多层继承、Object 根类特性。

java

复制代码
// 顶层类A(默认继承Object)
class A {
    public void methodA() {
        System.out.println("A类的方法");
    }
}

// B类继承A(单继承,只能写一个父类)
class B extends A {
    public void methodB() {
        System.out.println("B类的方法");
    }
}

// C类继承B(多层继承,间接继承A和Object)
class C extends B {
    public void methodC() {
        System.out.println("C类的方法");
    }
}

// 测试类
public class Demo03_ExtendsFeature {
    public static void main(String[] args) {
        C c = new C();
        // 可调用自身、父类B、爷爷类A的方法
        c.methodC();
        c.methodB();
        c.methodA();

        // 所有类都继承Object,可调用Object方法,例如toString()
        System.out.println("Object类的toString方法:" + c.toString());

        // 错误写法(编译不通过):Java不支持多继承
        // class D extends A, B {}
    }
}

运行结果:

plaintext

复制代码
C类的方法
B类的方法
A类的方法
Object类的toString方法:C@1b6d3586

04 继承中成员变量的特点

知识点讲解

当子类与父类出现同名成员变量时,遵循就近原则

  1. 子类方法访问变量:先找方法局部变量 → 再找子类成员变量 → 再找父类成员变量,都没有则编译报错;
  2. 访问父类同名变量:使用super.变量名
  3. 同名现象叫变量隐藏,父子类的变量同时存在,不是覆盖。

super关键字:代表父类对象的引用,用于访问父类的成员变量、成员方法、构造方法。

例题:变量就近原则与 super 使用

需求:父子类定义同名变量num,演示局部变量、子类变量、父类变量的访问区别。

java

复制代码
// 父类
class Father {
    int num = 100; // 父类成员变量
    String name = "父亲";
}

// 子类
class Son extends Father {
    int num = 200; // 子类同名成员变量

    public void show() {
        int num = 300; // 方法局部变量
        System.out.println("局部变量num:" + num);          // 就近:300
        System.out.println("子类成员变量num:" + this.num); // 子类:200
        System.out.println("父类成员变量num:" + super.num);// 父类:100

        // 无同名变量时,直接向上找父类
        System.out.println("父类的name:" + name);
    }
}

// 测试类
public class Demo04_VariableInExtends {
    public static void main(String[] args) {
        Son son = new Son();
        son.show();
    }
}

运行结果:

plaintext

复制代码
局部变量num:300
子类成员变量num:200
父类成员变量num:100
父类的name:父亲

05 继承中成员方法的特点(方法重写)

知识点讲解

子类中出现与父类方法声明完全一致 (方法名、参数列表、返回值类型都相同)的方法,叫做方法重写(Override),也叫方法覆盖。

重写规则
  1. 方法名、参数列表必须与父类完全一致;
  2. 子类方法权限 >= 父类方法权限(public > protected > 默认 > private);
  3. 引用类型返回值,子类可以是父类返回值的子类;基本类型必须完全相同;
  4. private 方法、静态方法不能被重写。
@Override 注解

写在子类方法上方,用于检测该方法是否符合重写规则,语法错误会直接编译报错,提升代码安全性。

重写 vs 重载
  • 重写:父子类之间,方法名 + 参数列表完全相同,是方法的 "覆盖";
  • 重载:同一个类中,方法名相同、参数列表不同,是方法的 "多版本"。

例题:方法重写与 super 调用父类方法

需求:父类Phone有打电话、发短信方法,子类NewPhone重写方法,扩展新功能,并用 super 保留父类原有逻辑。

java

复制代码
// 父类:旧手机
class Phone {
    public void call() {
        System.out.println("打电话:语音通话");
    }

    public void sendMessage() {
        System.out.println("发短信:文字短信");
    }
}

// 子类:新手机
class NewPhone extends Phone {
    // 重写call方法,添加视频通话
    @Override // 重写校验注解
    public void call() {
        super.call(); // 保留父类原有功能
        System.out.println("升级:支持视频通话");
    }

    // 重写发短信方法
    @Override
    public void sendMessage() {
        super.sendMessage();
        System.out.println("升级:支持发送图片、表情");
    }
}

// 测试类
public class Demo05_MethodOverride {
    public static void main(String[] args) {
        NewPhone phone = new NewPhone();
        phone.call();
        System.out.println("----------");
        phone.sendMessage();
    }
}

运行结果:

plaintext

复制代码
打电话:语音通话
升级:支持视频通话
----------
发短信:文字短信
升级:支持发送图片、表情

06 继承中构造方法的特点

知识点讲解

子类构造方法执行时,一定会先执行父类构造方法------ 子类继承了父类成员,需要先完成父类成员的初始化。

核心规则
  1. 子类构造方法第一行,默认隐藏super();,自动调用父类无参构造;
  2. 若父类没有无参构造,子类必须通过super(参数);手动调用父类有参构造,否则编译报错;
  3. super()this()都必须写在构造方法第一行,因此两者不能同时出现
  4. 构造方法不能被继承,只能被调用。

例题:构造方法调用顺序

需求:父类Person有无参、有参构造,子类Student有多个构造方法,演示执行顺序与 super 传参。

java

复制代码
// 父类
class Person {
    String name;
    int age;

    // 父类无参构造
    public Person() {
        System.out.println("父类Person的无参构造执行了");
    }

    // 父类有参构造
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
        System.out.println("父类Person的有参构造执行了");
    }
}

// 子类
class Student extends Person {
    int score;

    // 子类无参构造
    public Student() {
        // 默认隐藏 super(); 调用父类无参
        System.out.println("子类Student的无参构造执行了");
    }

    // 子类有参构造
    public Student(String name, int age, int score) {
        // 手动调用父类有参构造,给父类属性赋值
        super(name, age);
        this.score = score;
        System.out.println("子类Student的有参构造执行了");
    }

    public void show() {
        System.out.println("姓名:" + name + ",年龄:" + age + ",成绩:" + score);
    }
}

// 测试类
public class Demo06_ConstructorInExtends {
    public static void main(String[] args) {
        System.out.println("=== 创建无参学生对象 ===");
        Student s1 = new Student();

        System.out.println("\n=== 创建有参学生对象 ===");
        Student s2 = new Student("小明", 18, 95);
        s2.show();
    }
}

运行结果:

plaintext

复制代码
=== 创建无参学生对象 ===
父类Person的无参构造执行了
子类Student的无参构造执行了

=== 创建有参学生对象 ===
父类Person的有参构造执行了
子类Student的有参构造执行了
姓名:小明,年龄:18,成绩:95

07 带有继承结构的标准 JavaBean

知识点讲解

标准 JavaBean(实体类)开发规范:

  1. 成员变量全部使用private修饰(封装);
  2. 为每个成员变量提供getXxxsetXxx方法;
  3. 提供无参构造方法 + 全参构造方法;
  4. 建议重写toString()方法,方便打印对象信息。

继承体系下的 JavaBean:

  • 父类按规范编写自身的属性、get/set、构造方法;
  • 子类继承父类,编写自身特有属性、get/set,构造方法通过super调用父类构造。

例题:继承体系下的标准 JavaBean

需求:编写标准父类Person、子类Teacher,完全符合 JavaBean 规范。

java

复制代码
// 标准父类JavaBean
class Person {
    // 1.私有成员变量
    private String name;
    private int age;

    // 2.无参构造
    public Person() {
    }

    // 3.全参构造
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    // 4.get/set方法
    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;
    }

    // 5.重写toString
    @Override
    public String toString() {
        return "Person{name='" + name + "', age=" + age + "}";
    }
}

// 标准子类JavaBean
class Teacher extends Person {
    // 子类特有私有属性
    private double salary;

    // 子类无参构造
    public Teacher() {
    }

    // 子类全参构造:调用父类有参构造
    public Teacher(String name, int age, double salary) {
        super(name, age);
        this.salary = salary;
    }

    // 子类属性的get/set
    public double getSalary() {
        return salary;
    }

    public void setSalary(double salary) {
        this.salary = salary;
    }

    // 重写toString,拼接父子类信息
    @Override
    public String toString() {
        return "Teacher{name='" + getName() + "', age=" + getAge() + ", salary=" + salary + "}";
    }
}

// 测试类
public class Demo07_StandardJavaBean {
    public static void main(String[] args) {
        // 无参构造 + set赋值
        Teacher t1 = new Teacher();
        t1.setName("王老师");
        t1.setAge(35);
        t1.setSalary(8000);
        System.out.println(t1);

        // 全参构造直接赋值
        Teacher t2 = new Teacher("李老师", 28, 6500);
        System.out.println(t2);
    }
}

运行结果:

plaintext

复制代码
Teacher{name='王老师', age=35, salary=8000.0}
Teacher{name='李老师', age=28, salary=6500.0}

08 继承的作业

知识点讲解

本节通过编程作业综合巩固:继承定义、成员变量、成员方法、方法重写的组合使用。

作业例题:图形类继承练习

需求:

  1. 父类Shape(图形):属性color;方法getArea()返回面积、getPerimeter()返回周长(默认返回 0)
  2. 子类Circle(圆形):特有属性radius半径;重写面积、周长方法
  3. 子类Rectangle(矩形):特有属性length长、width宽;重写面积、周长方法
  4. 创建对象测试计算结果

java

复制代码
// 父类:图形
class Shape {
    String color;

    public double getArea() {
        return 0;
    }

    public double getPerimeter() {
        return 0;
    }
}

// 子类:圆形
class Circle extends Shape {
    double radius;

    public Circle(double radius, String color) {
        this.radius = radius;
        this.color = color;
    }

    @Override
    public double getArea() {
        return Math.PI * radius * radius;
    }

    @Override
    public double getPerimeter() {
        return 2 * Math.PI * radius;
    }
}

// 子类:矩形
class Rectangle extends Shape {
    double length;
    double width;

    public Rectangle(double length, double width, String color) {
        this.length = length;
        this.width = width;
        this.color = color;
    }

    @Override
    public double getArea() {
        return length * width;
    }

    @Override
    public double getPerimeter() {
        return 2 * (length + width);
    }
}

// 测试类
public class Demo08_ExtendsHomework {
    public static void main(String[] args) {
        Circle circle = new Circle(5, "红色");
        System.out.println("圆形颜色:" + circle.color);
        System.out.println("圆形面积:" + String.format("%.2f", circle.getArea()));
        System.out.println("圆形周长:" + String.format("%.2f", circle.getPerimeter()));

        System.out.println("----------");

        Rectangle rect = new Rectangle(4, 6, "蓝色");
        System.out.println("矩形颜色:" + rect.color);
        System.out.println("矩形面积:" + rect.getArea());
        System.out.println("矩形周长:" + rect.getPerimeter());
    }
}

运行结果:

plaintext

复制代码
圆形颜色:红色
圆形面积:78.54
圆形周长:31.42
----------
矩形颜色:蓝色
矩形面积:24.0
矩形周长:20.0

09 子类到底能继承父类的什么?

知识点讲解

子类不是父类所有内容都能继承,访问权限受修饰符限制:

表格

成员类型 能否直接访问 说明
public 成员变量 / 方法 ✅ 可以 任意位置都能访问
protected 成员变量 / 方法 ✅ 可以 子类中可直接访问,不同包子类也可
默认(包访问)成员 同包✅ / 不同包❌ 父子类同包可直接访问,不同包不行
private 成员变量 / 方法 ❌ 不能直接访问 只能在父类内部访问,子类需通过 get/set 间接操作

补充:

  • 父类构造方法不能继承 ,只能通过super调用;
  • 静态成员属于类本身,不存在 "继承" 概念,属于类共享。

例题:私有成员的访问验证

需求:父类定义私有属性,演示子类不能直接访问,必须通过 get/set 间接操作。

java

复制代码
// 父类
class Parent {
    public String publicVar = "公共变量";
    private int privateVar = 100; // 私有变量

    public void publicMethod() {
        System.out.println("父类公共方法");
    }

    private void privateMethod() {
        System.out.println("父类私有方法");
    }

    // 提供get/set访问私有变量
    public int getPrivateVar() {
        return privateVar;
    }

    public void setPrivateVar(int privateVar) {
        this.privateVar = privateVar;
    }
}

// 子类
class Child extends Parent {
    public void show() {
        System.out.println("直接访问父类公共变量:" + publicVar);
        // 编译报错:不能直接访问父类私有变量
        // System.out.println(privateVar);

        // 通过get方法间接访问
        System.out.println("通过get访问父类私有变量:" + getPrivateVar());

        publicMethod(); // 可调用父类公共方法
        // 编译报错:不能调用父类私有方法
        // privateMethod();
    }
}

// 测试类
public class Demo09_WhatCanInherit {
    public static void main(String[] args) {
        Child child = new Child();
        child.show();

        // 通过set修改父类私有变量
        child.setPrivateVar(200);
        System.out.println("修改后父类私有变量值:" + child.getPrivateVar());
    }
}

运行结果:

plaintext

复制代码
直接访问父类公共变量:公共变量
通过get访问父类私有变量:100
父类公共方法
修改后父类私有变量值:200

10 Java 中的权限修饰符

知识点讲解

Java 有 4 种权限修饰符,权限从大到小:public > protected > 默认(空) > private

访问范围对照表:

表格

修饰符 本类中 同包下 不同包的子类 不同包无关类
public
protected
默认(包访问)
private

使用建议:

  • 成员变量:一般用private封装,通过 get/set 对外暴露;
  • 成员方法:对外功能用public,子类重写用protected,本包内部用默认;
  • 普通类:只能用public或默认,不能用 protected/private(内部类除外)。

例题:权限修饰符访问验证

需求:在同包环境下,验证本类、子类、无关类对不同权限成员的访问能力。

java

复制代码
// 父类(同包)
class ModifierDemo {
    public int a = 1;       // 公共
    protected int b = 2;    // 受保护
    int c = 3;              // 默认
    private int d = 4;      // 私有

    public void test() {
        // 本类中:所有权限都能访问
        System.out.println(a);
        System.out.println(b);
        System.out.println(c);
        System.out.println(d);
    }
}

// 同包下的子类
class SubSamePackage extends ModifierDemo {
    public void show() {
        System.out.println("同包子类访问public:" + a);
        System.out.println("同包子类访问protected:" + b);
        System.out.println("同包子类访问默认:" + c);
        // System.out.println(d); // 编译报错,private不可访问
    }
}

// 同包下的无关类
class OtherSamePackage {
    public void show() {
        ModifierDemo demo = new ModifierDemo();
        System.out.println("同包无关类访问public:" + demo.a);
        System.out.println("同包无关类访问protected:" + demo.b);
        System.out.println("同包无关类访问默认:" + demo.c);
        // System.out.println(demo.d); // 编译报错,private不可访问
    }
}

// 测试类
public class Demo10_PermissionModifier {
    public static void main(String[] args) {
        System.out.println("=== 本类测试 ===");
        ModifierDemo demo = new ModifierDemo();
        demo.test();

        System.out.println("\n=== 同包子类测试 ===");
        SubSamePackage sub = new SubSamePackage();
        sub.show();

        System.out.println("\n=== 同包无关类测试 ===");
        OtherSamePackage other = new OtherSamePackage();
        other.show();
    }
}

运行结果:

plaintext

复制代码
=== 本类测试 ===
1
2
3
4

=== 同包子类测试 ===
同包子类访问public:1
同包子类访问protected:2
同包子类访问默认:3

=== 同包无关类测试 ===
同包无关类访问public:1
同包无关类访问protected:2
同包无关类访问默认:3

本章综合练习题(5 道,难度递进)

综合题 1(基础难度)

题目 :定义父类Vehicle(交通工具),属性:品牌brand、价格price;方法:运行run()。定义子类Car,继承 Vehicle,特有属性:座位数seatCount;特有方法:载人carryPeople()。创建 Car 对象,调用所有属性和方法。

java

复制代码
class Vehicle {
    String brand;
    double price;

    public void run() {
        System.out.println(brand + "交通工具正在行驶,售价" + price + "元");
    }
}

class Car extends Vehicle {
    int seatCount;

    public void carryPeople() {
        System.out.println("这辆" + brand + "汽车可以载" + seatCount + "个人");
    }
}

public class Exam01_Basic {
    public static void main(String[] args) {
        Car car = new Car();
        car.brand = "比亚迪";
        car.price = 159800;
        car.seatCount = 5;

        car.run();
        car.carryPeople();
    }
}

运行结果:

plaintext

复制代码
比亚迪交通工具正在行驶,售价159800.0元
这辆比亚迪汽车可以载5个人

综合题 2(中等难度)

题目 :设计多层继承体系:Food(食物)→ Fruit(水果)→ Apple(苹果)。

  • Food:属性name,方法taste()输出 "食物有味道"
  • Fruit:新增属性isSweet,重写taste()
  • Apple:新增属性color,重写taste(),新增方法makeJuice()创建 Apple 对象,测试所有属性和方法。

java

复制代码
class Food {
    String name;

    public void taste() {
        System.out.println(name + ":食物有味道");
    }
}

class Fruit extends Food {
    boolean isSweet;

    @Override
    public void taste() {
        System.out.println(name + "是水果," + (isSweet ? "味道很甜" : "味道不甜"));
    }
}

class Apple extends Fruit {
    String color;

    @Override
    public void taste() {
        System.out.println(color + "的" + name + "," + (isSweet ? "脆甜多汁" : "酸酸的"));
    }

    public void makeJuice() {
        System.out.println("用" + name + "榨苹果汁");
    }
}

public class Exam02_Medium {
    public static void main(String[] args) {
        Apple apple = new Apple();
        apple.name = "红富士";
        apple.isSweet = true;
        apple.color = "红色";

        apple.taste();
        apple.makeJuice();
    }
}

运行结果:

plaintext

复制代码
红色的红富士,脆甜多汁
用红富士榨苹果汁

综合题 3(进阶难度)

题目:按照标准 JavaBean 规范,设计员工继承体系:

  • 父类Staff:私有属性idnamebaseSalary;无参、全参构造;get/set;重写 toString
  • 子类Salesman(销售员):私有属性saleAmount(销售额)、commissionRate(提成比例);无参、全参构造;get/set;重写 toString;方法calcSalary()计算薪资(薪资 = 基础工资 + 销售额 * 提成比例)

java

复制代码
class Staff {
    private String id;
    private String name;
    private double baseSalary;

    public Staff() {
    }

    public Staff(String id, String name, double baseSalary) {
        this.id = id;
        this.name = name;
        this.baseSalary = baseSalary;
    }

    public String getId() { return id; }
    public void setId(String id) { this.id = id; }
    public String getName() { return name; }
    public void setName(String name) { this.name = name; }
    public double getBaseSalary() { return baseSalary; }
    public void setBaseSalary(double baseSalary) { this.baseSalary = baseSalary; }

    @Override
    public String toString() {
        return "员工{工号='" + id + "', 姓名='" + name + "', 基本工资=" + baseSalary + "}";
    }
}

class Salesman extends Staff {
    private double saleAmount;
    private double commissionRate;

    public Salesman() {
    }

    public Salesman(String id, String name, double baseSalary, double saleAmount, double commissionRate) {
        super(id, name, baseSalary);
        this.saleAmount = saleAmount;
        this.commissionRate = commissionRate;
    }

    public double getSaleAmount() { return saleAmount; }
    public void setSaleAmount(double saleAmount) { this.saleAmount = saleAmount; }
    public double getCommissionRate() { return commissionRate; }
    public void setCommissionRate(double commissionRate) { this.commissionRate = commissionRate; }

    // 计算总薪资
    public double calcSalary() {
        return getBaseSalary() + saleAmount * commissionRate;
    }

    @Override
    public String toString() {
        return "销售员{工号='" + getId() + "', 姓名='" + getName() +
               "', 基本工资=" + getBaseSalary() +
               ", 销售额=" + saleAmount + ", 提成比例=" + commissionRate + "}";
    }
}

public class Exam03_Advanced {
    public static void main(String[] args) {
        Salesman s = new Salesman("S001", "赵六", 5000, 80000, 0.1);
        System.out.println(s);
        System.out.println("本月总薪资:" + s.calcSalary() + "元");
    }
}

运行结果:

plaintext

复制代码
销售员{工号='S001', 姓名='赵六', 基本工资=5000.0, 销售额=80000.0, 提成比例=0.1}
本月总薪资:13000.0元

综合题 4(较难难度)

题目:设计学校人员继承体系,结合方法重写、super 调用、权限修饰符:

  • 父类SchoolPerson:protected 属性nameage;方法introduce()介绍自己
  • 子类Student:特有属性stuIdgrade;重写introduce(),调用父类方法并补充学生信息
  • 子类Teacher:特有属性subjecttitle;重写introduce(),调用父类方法并补充教师信息

java

复制代码
class SchoolPerson {
    protected String name;
    protected int age;

    public SchoolPerson(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public void introduce() {
        System.out.println("大家好,我叫" + name + ",今年" + age + "岁");
    }
}

class Student extends SchoolPerson {
    private String stuId;
    private String grade;

    public Student(String name, int age, String stuId, String grade) {
        super(name, age);
        this.stuId = stuId;
        this.grade = grade;
    }

    @Override
    public void introduce() {
        super.introduce();
        System.out.println("我是" + grade + "的学生,学号是" + stuId);
    }
}

class Teacher extends SchoolPerson {
    private String subject;
    private String title;

    public Teacher(String name, int age, String subject, String title) {
        super(name, age);
        this.subject = subject;
        this.title = title;
    }

    @Override
    public void introduce() {
        super.introduce();
        System.out.println("我是教" + subject + "的" + title);
    }
}

public class Exam04_Hard {
    public static void main(String[] args) {
        Student stu = new Student("小红", 16, "2024001", "高一");
        stu.introduce();

        System.out.println("----------");

        Teacher tea = new Teacher("张老师", 40, "数学", "高级教师");
        tea.introduce();
    }
}

运行结果:

plaintext

复制代码
大家好,我叫小红,今年16岁
我是高一的学生,学号是2024001
----------
大家好,我叫张老师,今年40岁
我是教数学的高级教师

综合题 5(最难,全知识点综合)

题目:设计电商商品继承体系,综合封装、继承、方法重写、构造方法、权限修饰符所有知识点:

  1. 顶层父类Product
    • 私有属性:商品 id、名称、价格
    • 无参、全参构造,get/set 方法
    • 方法:showInfo()展示基础信息;calcTotalPrice(int count)计算总价(价格 * 数量)
  2. 子类Electronics(电子产品):
    • 新增私有属性:品牌、保修期(月)
    • 重写showInfo()补充电子商品信息
    • 重写calcTotalPrice:满 1000 减 50
  3. 子类Clothing(服装):
    • 新增私有属性:尺码、颜色
    • 重写showInfo()补充服装信息
    • 重写calcTotalPrice:买 2 件以上打 9 折
  4. 创建两个子类对象,分别调用展示信息和购买 5 件的总价。

java

复制代码
class Product {
    private String id;
    private String name;
    private double price;

    public Product() {
    }

    public Product(String id, String name, double price) {
        this.id = id;
        this.name = name;
        this.price = price;
    }

    public void showInfo() {
        System.out.println("商品编号:" + id);
        System.out.println("商品名称:" + name);
        System.out.println("商品单价:" + price + "元");
    }

    public double calcTotalPrice(int count) {
        return price * count;
    }

    public String getId() { return id; }
    public void setId(String id) { this.id = id; }
    public String getName() { return name; }
    public void setName(String name) { this.name = name; }
    public double getPrice() { return price; }
    public void setPrice(double price) { this.price = price; }
}

class Electronics extends Product {
    private String brand;
    private int warrantyMonths;

    public Electronics() {
    }

    public Electronics(String id, String name, double price, String brand, int warrantyMonths) {
        super(id, name, price);
        this.brand = brand;
        this.warrantyMonths = warrantyMonths;
    }

    @Override
    public void showInfo() {
        super.showInfo();
        System.out.println("品牌:" + brand);
        System.out.println("保修期:" + warrantyMonths + "个月");
    }

    // 满1000减50
    @Override
    public double calcTotalPrice(int count) {
        double total = super.calcTotalPrice(count);
        if (total >= 1000) {
            total -= 50;
        }
        return total;
    }

    public String getBrand() { return brand; }
    public void setBrand(String brand) { this.brand = brand; }
    public int getWarrantyMonths() { return warrantyMonths; }
    public void setWarrantyMonths(int warrantyMonths) { this.warrantyMonths = warrantyMonths; }
}

class Clothing extends Product {
    private String size;
    private String color;

    public Clothing() {
    }

    public Clothing(String id, String name, double price, String size, String color) {
        super(id, name, price);
        this.size = size;
        this.color = color;
    }

    @Override
    public void showInfo() {
        super.showInfo();
        System.out.println("尺码:" + size);
        System.out.println("颜色:" + color);
    }

    // 买2件以上打9折
    @Override
    public double calcTotalPrice(int count) {
        double total = super.calcTotalPrice(count);
        if (count >= 2) {
            total *= 0.9;
        }
        return total;
    }

    public String getSize() { return size; }
    public void setSize(String size) { this.size = size; }
    public String getColor() { return color; }
    public void setColor(String color) { this.color = color; }
}

public class Exam05_Master {
    public static void main(String[] args) {
        System.out.println("===== 电子产品 =====");
        Electronics phone = new Electronics("E001", "智能手机", 2999, "小米", 12);
        phone.showInfo();
        System.out.println("购买5台总价:" + phone.calcTotalPrice(5) + "元");

        System.out.println("\n===== 服装 =====");
        Clothing shirt = new Clothing("C001", "纯棉衬衫", 199, "XL", "白色");
        shirt.showInfo();
        System.out.println("购买5件总价:" + shirt.calcTotalPrice(5) + "元");
    }
}

运行结果:

plaintext

复制代码
===== 电子产品 =====
商品编号:E001
商品名称:智能手机
商品单价:2999.0元
品牌:小米
保修期:12个月
购买5台总价:14945.0元

===== 服装 =====
商品编号:C001
商品名称:纯棉衬衫
商品单价:199.0元
尺码:XL
颜色:白色
购买5件总价:895.5元
相关推荐
是小蟹呀^9 小时前
Spring Security + JWT 面试题整理
java·jwt·springsecurity
tkevinjd10 小时前
MiniCode 项目详解6:原项目控制系统的10个缺陷(已修复)
python·llm·agent
星栈独行11 小时前
翻完 Pi 源码:它和 Codex、Claude Code 有何不同
开发语言·javascript·人工智能·程序人生
dNGUZ7UGj11 小时前
10分钟完成第一个Python小游戏
python·django
没有梦想的咸鱼185-1037-166311 小时前
AI-Python机器学习与深度学习技术:CNN/Transformer/扩散模型、SHAP可解释及Hermes智能体自动化
人工智能·python·深度学习·机器学习·chatgpt·cnn·transformer
spencer_tseng11 小时前
Redis + Nacos.bat
java·windows·dos
qq_4480111611 小时前
C语言中的变量和函数的定义与声明
android·c语言·开发语言
霸道流氓气质11 小时前
SpringBoot中通用工具类库(Utils)封装与使用实践
spring boot·后端·python