欢迎光临
我们一直在努力

Java 面向对象高级(一)超详细整理,从入门到精通

本篇承接面向对象基础内容,讲解继承、Object 类、final 关键字、抽象类四大核心知识点,配套语法规则、代码案例、内存解析、易错点与实战练习,适合零基础学习、课后复习以及面试备考。

一、继承

继承是面向对象三大核心特征之一,也是实现代码复用的核心手段。通过继承可以让类与类建立父子关系,子类能够直接使用父类中非私有成员,减少重复代码。

1.1 继承概述

1.1.1 核心概念

继承:使用extends关键字让两个类形成 ** 父类(基类 / 超类)和子类(派生类)关系,子类可以直接复用父类的非私有属性和行为。当多个类存在大量共性内容,且满足is-a(是一个)** 逻辑关系时,就适合使用继承抽取共性到父类,优化代码结构。

1.1.2 使用场景举例
  • 合理场景:学生、老师都属于 “人”,都拥有姓名、年龄,抽取共性定义Person父类,学生、老师作为子类继承;
  • 不合理场景:程序员和商品都存在编号,二者不存在is-a关系,不建议强行继承。
1.1.3 继承语法格式

public class 子类名 extends 父类名 {
// 子类独有成员
}

示例:

// 父类:员工
public class Employee {
String name;
int age;
double salary;
}

// 子类:程序员,继承员工类
public class Coder extends Employee {

}

// 子类:人事,继承员工类
public class Hr extends Employee {

}

1.2 继承中成员变量访问规则

  • 就近原则:子类、父存在重名成员变量时,优先在当前类查找;
  • 关键字super:主动访问父类的成员变量,格式:super.变量名;
  • 关键字this:访问当前子类的成员变量,格式:this.变量名。
  • 完整演示案例:

    public class Fu {
    int num = 10; // 父类变量
    }

    public class Zi extends Fu {
    int num = 20; // 子类变量

    public void method() {
    int num = 30; // 局部变量
    System.out.println(num); // 30 局部变量(就近)
    System.out.println(this.num); // 20 本类成员变量
    System.out.println(super.num);// 10 父类成员变量
    }
    }

    public class Test {
    public static void main(String[] args) {
    Zi z = new Zi();
    z.method();
    }
    }

    1.3 方法重写(Override)

    1.3.1 概念

    子类继承父类后,对父类原有方法的逻辑进行修改、增强,这个过程叫做方法重写 / 覆盖。

    1.3.2 重写语法要求
  • 方法名、参数列表、返回值必须和父类完全一致;
  • 访问权限:子类权限必须大于等于父类;
  • 父类private私有方法,子类无法重写。
  • 1.3.3 权限修饰符优先级(由低到高)

    private < 默认权限 < protected < public

    1.3.4 重写代码示例

    // 父类
    public class Fu {
    public void method() {
    System.out.println("父类原有方法逻辑");
    }
    }

    // 子类重写方法
    public class Zi extends Fu {
    @Override // 重写注解,校验语法合法性
    public void method() {
    System.out.println("子类重写后的方法逻辑");
    }
    }

    1.4 Java 继承语法特点

  • 只支持单继承:一个子类只能有一个直接父类,不支持多继承;原因:若一个类同时继承多个父,多个父存在同名方法时,编译器无法区分调用逻辑。
  • 支持多层继承:A 继承 B、B 继承 C,形成继承链,子类可以逐级复用上级父类成员。
  • 1.5 继承中的构造方法

    1.5.1 核心规则
  • 构造方法不能被继承,子类必须手动定义自身构造;
  • 子类所有构造方法中,默认第一行隐藏 super(),作用是调用父类无参构造;
  • super()必须放在构造方法第一行,且this()和super()不能同时存在。
  • 1.5.2 执行流程

    创建子类对象时:先初始化父类空间 → 再初始化子类空间。

    1.5.3 综合案例(学生 & 人员继承)

    // 父类:人类
    public class Person {
    private String name;
    private int age;

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

    // get/set方法
    public String getName() {
    return name;
    }
    public int getAge() {
    return age;
    }
    }

    // 子类:学生,继承人类
    public class Student extends Person {
    private int score; // 子类独有:成绩

    // 子类构造,通过super调用父类有参构造
    public Student(String name, int age, int score) {
    super(name, age);
    this.score = score;
    }

    public int getScore() {
    return score;
    }
    }

    // 测试类
    public class Test {
    public static void main(String[] args) {
    Student stu = new Student("钢门吹雪", 23, 100);
    System.out.println(stu.getName() + " " + stu.getAge() + " " + stu.getScore());
    }
    }

    1.6 this 与 super 完整对照表

    关键字访问成员变量访问成员方法访问构造方法
    this this.变量名 访问本类 this.方法名() 访问本类 this(参数) 调用本类构造
    super super.变量名 访问父类 super.方法名() 访问父类 super(参数) 调用父类构造

    补充:this() 和 super() 都要求写在构造方法第一行,因此二者不能同时使用。

    1.7 实战综合案例(员工体系)

    需求:定义父类Employee(员工),子类Coder(程序员)、Manager(项目经理),继承并重写工作方法。

    // 父类 员工
    public class Employee {
    private String name;
    private int age;
    private double salary;

    public Employee(){}
    public Employee(String name, int age, double salary) {
    this.name = name;
    this.age = age;
    this.salary = salary;
    }

    public void work() {
    System.out.println("员工开始工作");
    }

    // get/set
    public String getName() { return name; }
    public int getAge() { return age; }
    public double getSalary() { return salary; }
    }

    // 子类 程序员
    public class Coder extends Employee {
    public Coder(String name, int age, double salary) {
    super(name, age, salary);
    }

    @Override
    public void work() {
    System.out.println(getName() + "正在编写代码");
    }
    }

    // 子类 项目经理
    public class Manager extends Employee {
    private double bonus; // 独有奖金
    public Manager(String name, int age, double salary, double bonus) {
    super(name, age, salary);
    this.bonus = bonus;
    }

    @Override
    public void work() {
    System.out.println(getName() + "正在分配任务");
    }
    }

    // 测试
    public class TestEmp {
    public static void main(String[] args) {
    Coder c = new Coder("张三",23,15000);
    c.work();
    Manager m = new Manager("李四",24,18000,5000);
    m.work();
    }
    }

    小结

  • 继承使用extends,核心作用是复用代码,满足is-a关系再使用;
  • 重名变量遵循就近原则,this访问本类、super访问父类;
  • 方法重写要求声明一致、权限不缩小,私有方法不能重写;
  • Java 单继承、多层继承;子类构造默认调用父构造,super必须在首行。

  • 二、Object 类

    2.1 类层级关系

    Object是 Java 中所有类的根父类,所有类都会直接或间接继承它,因此Object中的方法所有类都可以使用。

    2.2 toString () 方法

    2.2.1 默认效果

    默认toString()会返回:类全限定名@内存哈希地址,直接打印对象默认调用该方法,地址信息无实际业务意义。

    2.2.2 重写目的

    重写toString(),让输出结果展示对象内部属性数据,方便查看对象信息。

    2.2.3 代码示例

    // 自定义类,默认继承Object
    public class Person {
    private String name;
    private int age;

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

    // 重写toString方法
    @Override
    public String toString() {
    return "姓名:" + name + ",年龄:" + age;
    }
    }

    public class Test {
    public static void main(String[] args) {
    Person p = new "李四",22);
    // 自动调用重写后的toString
    System.out.println(p);
    }
    }

    小结

    Object是所有类的父类;开发中必须重写 toString (),用于打印对象真实属性,而非内存地址。


    三、final 关键字

    final译为 “最终、不可改变”,可以修饰类、方法、变量,被修饰的内容都具备不可修改的特性。

    3.1 final 修饰类

    • 规则:被final修饰的类为最终类,不能被继承;
    • 示例:public final class FinalDemo {}

    3.2 final 修饰方法

    • 规则:被final修饰的方法为最终方法,无法被重写;
    • 应用:核心通用方法,禁止子类修改逻辑时使用。

    3.3 final 修饰变量

    变量分为基本类型、引用类型,规则不同:

  • 基本数据类型:变量值一旦赋值,无法修改,等同于常量;
  • 引用数据类型:对象地址不可修改,但对象内部的成员变量依然可以修改;
  • 成员变量使用final:必须在定义处 或 构造方法中完成赋值。
  • 代码示例

    // final修饰基本类型变量
    final int NUM = 10;
    // NUM = 20; 报错,值不可修改

    // final修饰引用类型
    final Person p = new Person("王五",25);
    p.setName("赵六"); // 内部属性可修改
    // p = new Person("赵六",26); 报错,地址不可修改

    小结

  • final 类:禁止继承;
  • final 方法:禁止重写;
  • final 变量:基本类型值不变,引用类型地址不变。

  • 四、抽象类(abstract)

    4.1 抽象类与抽象方法概念

  • 抽象方法:只有方法声明,没有方法体,使用abstract修饰。当抽取父类共性行为,但无法确定具体实现逻辑时,定义为抽象方法;
  • 抽象类:包含抽象方法的类,必须使用abstract修饰,是一种特殊的父类。
  • 语法格式

    // 抽象类
    public abstract class 类名 {
    // 抽象方法(无方法体)
    public abstract void 方法名();
    }

    4.2 抽象类核心注意事项

  • 抽象类不能实例化(不能 new 对象),防止调用无实现的抽象方法;
  • 抽象类可以拥有构造方法,供子类创建对象时,通过super调用;
  • 抽象类中可以包含普通成员变量、普通方法;
  • 抽象类的子类二选一:
    • 方案一:重写父类所有抽象方法(常用);
    • 方案二:子类也定义为抽象类。
  • 4.3 关键字冲突说明

    abstract 不能和 private、final、static 联用:

  • abstract + private:抽象方法要求子类实现,私有方法子类不可见,矛盾;
  • abstract + final:抽象要求重写,final 禁止重写,矛盾;
  • abstract + static:静态方法可通过类名直接调用,无方法体的抽象静态方法无意义。
  • 4.4 模板设计模式

    抽象类最典型应用:模板设计模式

    • 思路:抽象类定义通用代码模板,将不确定的逻辑抽取为抽象方法;
    • 子类继承后,仅需实现抽象方法,整体结构由模板固定,简化开发。
    模板模式示例

    // 抽象模板类
    public abstract class Template {
    // 通用模板方法
    public void run() {
    step1();
    step2();
    step3();
    }
    public void step1(){
    System.out.println("通用步骤1");
    }
    // 不确定的步骤,定义为抽象方法
    public abstract void step2();
    public void step3(){
    System.out.println("通用步骤3");
    }
    }

    // 子类实现抽象方法
    public class SubTemplate extends Template {
    @Override
    public void step2() {
    System.out.println("子类自定义步骤2");
    }
    }

    小结

  • 抽象类 / 方法使用abstract修饰,抽象方法无方法体;
  • 抽象类不能 new,但存在构造方法;
  • 子类必须重写全部抽象方法,或自身也设为抽象类;
  • 抽象类常用场景为模板设计模式。

  • 五、本篇全文总结

  • 继承:三大特征之一,extends实现单继承,依靠this/super区分父子成员,构造默认调用父构造,方法重写需遵守权限与语法规则;
  • Object 类:Java 所有类的顶层父类,开发中务必重写toString()打印对象属性;
  • final 关键字:修饰类禁止继承、修饰方法禁止重写、修饰变量分基本 / 引用两种规则;
  • 抽象类:含抽象方法,不能实例化,用于抽取通用模板,衍生出模板设计模式,牢记关键字冲突规则。
  • 以上是面向对象进阶第一部分核心内容,继承、抽象类是后续接口、多态、设计模式的基础,建议多写案例巩固语法与使用场景。

    赞(0)
    未经允许不得转载:171主机测评 » Java 面向对象高级(一)超详细整理,从入门到精通
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址