Java基础快速入门: 面向对象高级之继承、抽象类、代码块与final关键字

Java高级教程 方法 描述将元素插入到指定位置的 arraylist 中addAll() 添加集合中的所有元素到 arraylist 中clear() 删除 arraylist 中的所有元素clone() 复制一份 arraylistcontains() 判断元素是否在 arraylist通过索引值获取 arraylist 中的元素indexOf() 返回 arraylist 中元素的索引值removeAll() 删除存在于指定集合中的 arraylist 里的所有元素。 阅读详情

本文纲要

  1. 继承入门
  2. 继承的好处与弊端
  3. 继承的特点
  4. 继承中成员变量的访问特点
  5. this 和 super 访问成员的格式
  6. 继承中成员方法的访问特点
  7. 方法重写概述与应用场景
  8. 方法重写的注意事项
  9. 权限修饰符
  10. 继承中构造方法的访问特点
  11. 构造方法的访问特点 - 父类没有无参构造
  12. 代码优化与内存图解
  13. 信息管理系统- 集成改进
  14. 抽象类入门
  15. 抽象类的注意事项
  16. 模板设计模式
  17. final 关键字
  18. 信息管理系统- 抽象类改进
  19. 代码块
  20. 信息管理系统- 代码块改进
  21. 总结

本文代码结构

project-root/
├── test-abstract/src/com/wb                          (代码块)
│     ├── mfinal/                                     (final关键字)
│     ├── test1/                                      (抽象类)
│     └── test2/                                      (模板设计模式)
├── test-extends/src/com/wb                           (继承)
│     ├── constructor/                                (继承-构造方法)
│     ├── override/                                   (方法重写)
│     ├── override2/                                  (方法重写注意事项)
│     ├── test1/                                      (继承-基础)
│     ├── test2/                                      (继承-优化)
│     ├── test3/                                      (继承-多层继承)
│     ├── test4/                                      (继承-成员变量访问)
│     └──  test5/                                     (继承-成员方法访问)
├── test-permission/src/com/wb/                       (代码块)
│     ├── test1/                                      (权限修饰符)
│     └── test2/                                      (权限修饰符-不同包)
├── test-block/src/com/wb/block                       (代码块)
│     ├── construction/                               (构造代码块)
│     ├── local/                                      (局部代码块)
│     └── mstatic/                                    (静态代码块)
└── wb-edu-info-manager/com/wb/edu/info/manager/      (信息管理系统)
    ├── controller/                                   (控制层)
    ├── dao/                                          (数据访问层)
    ├── domain/                                       (实体类)
    ├── entry/                                        (程序入口)
    ├── factory/                                      (工厂类)
    └── service/                                      (业务层)

继承入门

概念: 继承是面向对象编程的第二大特征(封装、继承、多态)。它允许类与类之间产生子父类关系。子类可以直接使用父类中非私有的成员变量和成员方法。

场景: 在之前的黑马信息管理系统中,Student类和Teacher类中存在大量共性的代码(如 id, name, age 等属性),这降低了代码的复用性。为了解决这个问题,可以将这些共性的内容向上抽取,形成一个父类 Person,然后让 Student 和 Teacher 继承它。

格式: 在类名后使用 extends 关键字,后跟父类名
public class 子类名 extends 父类名 { ... }

代码演示:

// 父类 Person,抽取了 Student 和 Teacher 的共性内容 
public class Person {
    private String id;
    private String name;
    private String age;
    private String birthday;
 
    public Person() {
    }
 
    public Person(String id, String name, String age, String birthday) {
        this.id = id;
        this.name = name;
        this.age = age;
        this.birthday = birthday;
    }
 
    // 提供非私有的 get/set 方法供子类访问 
    public String getId() {
        return id;
    }
 
    public void setId(String id) {
        this.id = id;
    }
 
    // 其他 get/set 方法...
}
 
// 子类 Student,通过 extends 关键字继承 Person 
public class Student extends Person {
    // 子类可以编写自己特有的成员,没有编写任何代码,也可以使用父类非私有成员 
}
 
// 子类 Teacher 
public class Teacher extends Person {
    // ...
}

结论: 虽然父类中的成员变量是 private 的,子类不能直接访问,但父类提供了非私有的 getter/setter 方法。子类通过继承这些方法,间接地访问了父类的私有数据。

继承的好处与弊端

好处:

  1. 提高代码的复用性: 这是继承最直观的好处,子类无需重复编写代码,可以直接使用父类的非私有成员。

  2. 提高代码的维护性: 当需求变更(如增加一个属性),只需在父类中修改一次,所有子类都会自动更新。

    // 没有继承时,修改需求需在多个类中重复添加属性 
    public class Student { / ... / String address; }
    public class Teacher { / ... / String address; }
    
    // 有继承时,只在父类修改一次 
    public class Person { / ... / String address; }
    // Student 和 Teacher 无需任何修改,即可使用 address 属性(通过get/set)
    
  3. 是多态的前提: 代码之间的“是”(is-a)关系(学生是人的一种)是建立继承关系的基础,这也是多态技术实现的前提。

弊端:

  1. 降低了代码的灵活性: 继承是侵入性的。子类必须拥有父类非私有的属性和方法,这给予了子类一些不想要的约束。
  2. 增强了代码的耦合性: 父类和子类之间的关联非常紧密(强耦合)。如果父类的某个成员被修改或删除,所有使用该成员的子类代码都可能需要修改,否则会报错,这就是“牵一发而动全身”。

应用场景: 当类与类之间存在共性内容,并且满足"is-a"关系时(如:学生和老师都是人),就可以考虑使用继承来优化代码结构。

继承的特点

  1. 单继承: Java只支持单继承,一个子类只能有一个直接父类。

  2. 不支持多继承: 一个子类不能同时继承多个父类。

    // 错误写法!Java不支持多继承 
    public class C extends A, B { }
    

    原因:如果父类A和B有同名方法但实现不同,子类调用时会产生逻辑冲突,Java为避免这种二义性,不支持多继承。

  3. 多层继承: 支持多层继承体系(子->父->爷)。

    public class A { public void methodA(){} }
    public class B extends A { public void methodB(){} }
    // C 是最底层的子类,可以访问 A 和 B 中所有非私有成员 
    public class C extends B { }
    
    public class Test {
        public static void main(String[] args) {
            C c = new C();
            c.methodA(); // 访问爷爷类的方法 
            c.methodB(); // 访问父亲类的方法 
        }
    }
    

继承中成员变量的访问特点

访问一个变量时,遵循就近原则:

  1. 先在方法内部查找(局部变量)。
  2. 没有则去子类的成员范围查找(本类成员变量)。
  3. 还没有则去父类的成员范围查找(父类成员变量)。
  4. 如果都找不到,则编译报错。

子父类成员变量重名:

如果子类和父类出现了重名的成员变量,默认访问的是子类的。如果想在子类中访问父类的同名变量,需要使用 super 关键字。

public class Fu {
    int a = 10;
}
 
public class Zi extends Fu {
    int a = 20; // 与父类重名 
 
    public void method() {
        int a = 30; // 局部变量 
        System.out.println(a);          // 30,就近使用局部变量 
        System.out.println(this.a);     // 20,使用this区分,访问本类成员变量 
        System.out.println(super.a);    // 10,使用super关键字访问父类成员变量 
    }
}

this 和 super 访问成员的格式

this: 代表本类对象的引用。用于区分局部变量和成员变量,或调用本类的其他成员。
super: 代表父类存储空间的标识(可以理解为父类对象的引用)。用于在子类中访问父类的成员。

两者的格式非常相似,可以调用成员变量、成员方法和构造方法。

关键字访问成员变量访问成员方法访问构造方法
thisthis.成员变量this.成员方法(参数)this(参数)
supersuper.成员变量super.成员方法(参数)super(参数)
this(…) 和 super(…) 是用来调用构造方法的,且都必须放在构造方法的第一行。

继承中成员方法的访问特点

通过子类对象访问方法时,查找顺序:

  1. 在子类的成员范围查找。
  2. 如果子类有,则执行子类的方法。
  3. 如果子类没有,则去父类的成员范围查找。
  4. 如果父类也没有,则报错。

代码演示:

public class Fu {
    public void show() { System.out.println("父类show方法"); }
}
public class Zi extends Fu {
    // 子类有 show 方法,则调用时执行这个 
    public void show() { System.out.println("子类show方法"); }
 
    public void method() {
        this.show();   // 调用本类的show方法 
        super.show();  // 通过super调用父类的show方法 
    }
}

方法重写概述与应用场景

概念: 在继承体系中,子类出现了和父类一模一样的方法声明(方法名、参数列表、返回值类型都相同)的行为,称为方法重写 (Override)。

应用场景: 当子类需要父类的功能,但功能主体子类又有自己特有的实现时。通过重写,既能沿袭父类的功能,又能定义子类特有的内容。

案例: 手机系统升级。v1.0 手机的语音助手 smallBlack 只说英文,v2.0 要求既能说英文又能说中文。

// 父类 iPearV1 
public class iPearV1 {
    public void smallBlack() {
        System.out.println("speak english...");
    }
}
// 子类 iPearV2 
public class iPearV2 extends iPearV1 {
    // 重写父类方法 
    @Override 
    public void smallBlack() {
        // 调用父类的功能,沿袭了说英文的能力 
        super.smallBlack();
        // 添加子类特有的功能 
        System.out.println("说中文");
    }
}

区分方法重载 (Overload):

  • 重写 (Override): 在继承体系的子父类中,方法声明一模一样。
  • 重载 (Overload): 在同一个类中,方法名相同,参数列表不同,与返回值无关。

方法重写的注意事项

  1. 权限:子类重写方法时,访问权限必须大于等于父类方法的权限。
  2. 静态:父类中静态方法,不能被子类以非静态方法重写,反之亦然。静态方法本身不能被重写(只能被隐藏),但可以用 @Override 注解来检查。
  3. 私有:父类中私有方法不能被重写。
public class Fu {
    void method() { ... } // 默认权限 
    // public static void show() { ... }
}
 
public class Zi extends Fu {
    @Override 
    void method() { ... } // OK, 权限 >= 默认权限 
    // @Override 
    // public void show() { ... } // 报错,父类静态,子类未用 static 
}

权限修饰符

Java中有四种权限修饰符,用来控制成员的访问范围,从小到大的等级为:
private < 默认 (什么都不写) < protected < public

修饰符同一个类同一个包中的子类/无关类不同包下的子类不同包下的无关类
private√×××
默认 (default)√√××
protected√√√×
public√√√√

我们日常开发中最常用的是 private(用于封装)和 public(对外提供接口)。

继承中构造方法的访问特点

规则:子类中所有的构造方法,默认都会先访问父类中的无参构造方法,再执行自己的方法体。

为什么?: 因为子类在初始化时,可能会使用到父类的数据。如果父类数据没有完成初始化,子类就无法安全地使用它。所以,子类初始化前,必须先完成父类的初始化。

**怎么做? **:super() 语句。每一个子类构造方法的第一行,都隐式地有一条 super() 语句,用于调用父类的无参构造。

public class Person {
    public Person() {
        System.out.println("父类无参构造");
    }
}
 
public class Student extends Person {
    public Student() {
        // 系统默认隐藏了 super();
        System.out.println("子类无参构造");
    }
}
 
// main中执行 new Student();
// 控制台输出顺序:
// "父类无参构造"
// "子类无参构造"

Object类:每一个类都直接或间接地继承了 Object 类。Object 是 Java 类层次结构的最顶层。父类 Person 如果不显式继承其他类,那么它也默认继承 Object。Person 构造中的 super() 调用的就是 Object 的无参构造。

构造方法的访问特点 - 父类没有无参构造

如果父类没有提供无参构造方法,只提供了有参构造方法,子类构造方法就不会再默认生成 super(),而是会报错。

解决方案(推荐):
在子类构造方法中,手工调用父类的有参构造方法 super(参数),并传入相应的参数。

public class Fu {
    private int age;
    // 父类没有无参构造 
    public Fu(int age) {
        this.age = age;
    }
}
 
public class Zi extends Fu {
    public Zi(int age) {
        super(age); // 必须手写,显式调用父类的有参构造 
    }
}

注意事项:
this(...) 和 super(...) 调用构造方法的语句,都必须放在构造方法的第一行有效语句。因此,它们在同一个构造方法中不能共存。

代码优化与内存图解

在编写继承代码时,子类的构造方法可以通过快捷键 Alt + Insert (或右键 -> Generate…) 快速生成。如果需要初始化完整的属性,子类的有参构造应接收所有数据(包括父类的),并通过 super 将父类的数据传递给父类去初始化。

// 父类 
public class Person {
    private String name;
    private int age;
    public Person(String name, int age) { this.name = name; this.age = age; }
    // ...
}
 
// 子类 
public class Student extends Person {
    private int score;
    public Student(String name, int age, int score) {
        super(name, age); // 将 name 和 age 传递给父类初始化 
        this.score = score; // 子类自己初始化独有属性 
    }
}

内存图解(堆内存):
当创建 new Student(“张三”, 23, 100) 时,堆内存的结构分析。

执行流程

堆内存_Heap

主程序

Student stu = new Student('张三', 23, 100)

创建对象

Student对象空间
含地址值 @15db9742

super区域 Person成员

name = null
age = 0

Student特有成员

score = 0

1. new Student时
实参 张三,23,100 传给有参构造

2. super 张三,23 语句执行

3. Person有参构造完成赋值

4. super区域更新
name=张三, age=23

5. this.score = 100 执行

6. Student对象空间完整

结论:
父类中private的成员也会在子类对象的super区域内有一份存储空间。子类只是没有直接访问的权限。
初始化是分层进行的:先由父类完成其成员的初始化,再由于子类完成其自身特有成员的初始化。

信息管理系统 - 集成改进

利用继承思想对信息管理系统进行优化。

1 ) 实体类优化:将 Student 和 Teacher 的共性属性抽取到 Person 父类。

2 ) 控制器优化:

  • 起初,StudentController 使用 set方法给属性赋值,代码冗长。
  • 新业务要求使用构造方法赋值,但不希望修改原有代码。这体现了开闭原则(对修改关闭,对扩展开放)。
  • 解决方案:创建一个新控制器 OtherStudentController,复写 inputStudentInfo 方法,在其内部使用有参构造来封装 Student 对象。
  • 进一步优化:发现 StudentController 和 OtherStudentController 中有大量共性代码。于是向上抽取,创建一个抽象的 BaseStudentController 父类,将公共方法(如 start, addStudent, deleteStudentById 等)放入其中。子类只需专注于重写 inputStudentInfo 这个核心差异方法。

优化后的代码结构:

// 抽象的父类控制器 
public abstract class BaseStudentController {
    private StudentService studentService = new StudentService();
    private Scanner sc = new Scanner(System.in);
 
    public final void start() { / 复杂的控制逻辑, 不允许子类修改 / }
    public final void deleteStudentById() { / ... / }
    public final void addStudent() {
        // ... 接收id等公共逻辑 ...
        Student stu = inputStudentInfo(id); // 调用抽象方法,具体怎么输入由子类决定 
        // ...
    }
    // 将录入学生信息的方法定义为抽象,强制子类实现,体现了多态思想 
    public abstract Student inputStudentInfo(String id);
}
 
// 子类实现1: 使用set方法赋值 
public class StudentController extends BaseStudentController {
    @Override 
    public Student inputStudentInfo(String id) {
        // ... 键盘录入 ...
        Student stu = new Student();
        stu.setId(id);
        stu.setName(name);
        // ...
        return stu;
    }
}
 
// 子类实现2: 使用构造方法赋值 
public class OtherStudentController extends BaseStudentController {
    @Override 
    public Student inputStudentInfo(String id) {
        // ... 键盘录入 ...
        Student stu = new Student(id, name, age, birthday);
        return stu;
    }
}

抽象类入门

1 ) 概念由来: 当我们将共性方法(如 eat)向上抽取到父类 Animal 时,发现该方法在父类中无法给出具体的实现(因为猫吃鱼,狗吃肉,方法体不同)。这种只有方法声明而没有方法体的,就是抽象方法。有抽象方法的类,必须是抽象类。

2 ) 格式:
抽象方法:public abstract void 方法名(参数列表);
抽象类:public abstract class 类名 { ... }

3 ) 案例:

// 父类是抽象类 
public abstract class Animal {
    // 普通方法,可以直接有实现 
    public void drink() { System.out.println("喝水"); }
    // 抽象方法,没有方法体 
    public abstract void eat();
}
 
// 子类继承抽象类后,必须重写所有抽象方法 
public class Cat extends Animal {
    @Override 
    public void eat() { System.out.println("猫吃鱼"); }
}
public class Dog extends Animal {
    @Override 
    public void eat() { System.out.println("狗吃肉"); }
}

抽象类的注意事项

1 ) 不能实例化:抽象类不能创建对象(new Animal() 是错误的)。因为如果允许创建,就可以调用没有方法体的抽象方法,这是没有意义的。

2 ) 有构造方法:抽象类中有构造方法。这是为了让子类通过 super() 调用,以完成父类成员的初始化。

3 ) 子类的职责:
方案A(推荐):子类必须重写抽象父类中的所有抽象方法。
方案B(不推荐):把自己也变成一个抽象类。但这会导致功能延期,最终必须由另一个子类来实现抽象方法,增加了复杂度。

4 ) 抽象类中可以有普通方法:抽象类中可以没有抽象方法。但有抽象方法的类,必须是抽象类。

模板设计模式

1 ) 设计模式: 一套被反复使用、多数人知晓、经过分类编目的代码设计经验的总结。简单说,就是一种优秀的、固定的编码风格,而不是新技术点。

2 ) 模板设计模式: 抽象类最常见的应用。它将抽象类看成一个模板,用final修饰的普通方法作为模板骨架(定义好流程),而将流程中不能确定的部分定义为抽象方法,让子类来重写实现。

3 ) 案例: 作文模板。所有作文的标题和结尾是固定的(模板),但正文内容由不同学生自己决定

// 作文模板抽象类 
public abstract class CompositionTemplate {
    // final 修饰的模板方法,定义了写作文的整体骨架,不允许子类修改 
    public final void write() {
        System.out.println("<<我的爸爸>>"); // 固定部分 
        body(); // 不确定部分,由子类实现 
        System.out.println("啊~ 这就是我的爸爸"); // 固定部分 
    }
    // 抽象方法,将变化的正文内容留给子类实现 
    public abstract void body();
}
 
// Tom 同学的作文 
public class Tom extends CompositionTemplate {
    @Override 
    public void body() {
        System.out.println("那是一个秋天, 风儿那么缠绵...");
    }
}
// 测试 
public class Test { public static void main(String[] args) { new Tom().write(); } }

final 关键字

final 是最终的意思,可用于修饰类、方法和变量。

1 ) 修饰类:该类是最终类,不能被继承。例如,当希望一个工具类的所有方法都不能被重写时,可以直接将类声明为 final
java public final class Fu { } // public class Zi extends Fu { } // 报错

2 ) 修饰方法:该方法是最终方法,不能被重写。常用于模板方法(如上文的 write())。

public class Fu { public final void show(){} }
// public class Zi extends Fu { public void show(){} } // 报错 

3 ) 修饰变量:变量变为常量,只能被赋值一次。

  • 基本数据类型:数据值不可变。

  • 引用数据类型:对象的内存地址不可变,但对象内部属性可以修改。

    // 常量命名规范: 单词全大写,多个单词用_分隔 
    public static final int MAX_VALUE = 100;
    
    final Student stu = new Student("张三"); // 地址值被绑定,不能修改 
    stu.setName("李四"); // OK, 对象内容可以修改 
    // stu = new Student("李四"); // Error, 不能新指向其他对象 
    
  • 修饰成员变量时:必须在对象构造完成前完成初始化。有两种方式:

    1. 在定义时直接赋值:final int a = 10;
    2. 在构造方法中完成赋值。

信息管理系统 - 抽象类改进

运用抽象类思想,对 BaseStudentController 继续优化

  1. 将 inputStudentInfo 设计为抽象方法,因为它就是模板中无法确定的部分
  2. 将类本身和内部不希望子类修改的核心方法(如 start, addStudent 等)用 abstract 和 final 进行修饰,强化模板设计的规范性和安全性
public abstract class BaseStudentController {
    // ... 其他final方法 ...
    public final void start() { ... }
    public abstract Student inputStudentInfo(String id);
}

代码块

Java中用 {} 括起来的代码段就是代码块,根据位置和修饰符不同,分为三种

1 ) 局部代码块

位置:方法内部

作用:限定变量的生命周期,让变量尽早释放,提高内存利用率

public void method() {
    {
        int a = 10; // a 的作用域只在这个大括号内 
        System.out.println(a);
    }
    // System.out.println(a); // 无法访问,a已从内存释放 
}

2 ) 构造代码块

位置:类中方法外,无任何修饰符。

特点:每次构造方法执行时,都会在构造方法体之前执行。

作用:将多个构造方法中相同的代码抽取出来,提高代码复用性。

class Student {
    { System.out.println("好好学习"); } // 构造代码块 

    public Student() { System.out.println("空参构造"); }
    public Student(int a) { System.out.println("带参构造"); }
}
// 每次 new Student(),都会先打印“好好学习”,再打印各自的构造方法内容 

3 ) 静态代码块

位置:类中方法外,用 static 修饰。

特点:随着类的加载而加载,且只执行一次,优先于对象的创建。

作用:在类加载时,做一些数据初始化操作

class Person {
    static { System.out.println("我是静态代码块, 类一加载我就执行"); }
    public Person() { System.out.println("构造方法执行"); }
}
// 执行 new Person() 两次,静态代码块只在第一次加载类时执行 

信息管理系统 - 代码块改进

为了在系统启动后,自动拥有初始学生数据,方便功能测试,我们可以利用静态代码块来初始化 StudentDao 中的学生数组/集合。

public class StudentDao implements BaseStudentDao {
    // 创建学生对象数组 
    private static Student[] stus = new Student[5];
 
    // 静态代码块: 初始化数组数据 
    static {
        Student stu1 = new Student("heima001", "张三", "23", "1999-11-11");
        Student stu2 = new Student("heima002", "李四", "24", "2000-11-11");
        stus[0] = stu1;
        stus[1] = stu2;
    }
    // ...
}

这样,当 StudentDao 类被加载到JVM时,静态代码块执行,学生数组就自动添加了初始数据,大大方便了后续的开发和测试

总结

1 ) 继承 — 代码复用的基石

  • 概念:子类通过 extends 关键字获取父类的非私有成员。
  • 优点:提高代码复用性、维护性,是多态的前提。
  • 弊端:侵入性强,耦合性高,使用需谨慎。
  • 特点:Java 单继承、多层继承,不支持多继承(避免方法冲突)。
  • 成员访问:
    • 变量:就近原则(局部 → 本类成员 → 父类成员),同名时用 super. 访问父类变量。
    • 方法:子类优先,用 super. 可显式调用父类方法。
    • 构造方法:子类构造默认 super() 调用父类无参构造,用于完成父类数据初始化。
  • 方法重写:子类定义与父类方法签名完全相同的方法,用于扩展或改变父类行为。
    • 要求:权限不降低,静态只能重写静态,私有不可重写。
    • 与重载的区别:重载在同类的同名不同参。

2 ) 抽象类 — 模板与约束

  • 抽象方法:只有声明,没有方法体,用 abstract 修饰。
  • 抽象类:包含抽象方法的类必须声明为抽象类,也可包含普通方法。
  • 规则:
    • 不能实例化,但有构造方法(供子类 super() 用)。
    • 子类必须实现所有抽象方法,或自己也声明为抽象类。
  • 设计模式 — 模板模式:抽象类作为模板,定义骨架流程(final 方法),将可变部分声明为抽象方法,交由子类实现。保证整体结构统一,管理灵活。

3 ) final 关键字 — 不可变性

  • 修饰类:类不能被继承。
  • 修饰方法:方法不能被重写。
  • 修饰变量:
    • 基本类型值不可变,引用类型地址不可变(属性可变)。
    • 成员变量须在构造完成前初始化(直接赋值或构造方法中赋值)。
    • 常量命名全大写,多单词用下划线分隔。

4 )代码块 — 初始化利器

  • 局部代码块(方法内):控制变量生命周期,优化内存。
  • 构造代码块(类中方法外):每次构造方法执行前调用,提取公共初始化代码。
  • 静态代码块(static 修饰):类加载时执行一次,适合静态数据初始化。

5 ) 权限修饰符 — 访问控制
从紧到宽:private → 默认 → protected → public。合理使用保护封装和继承可见性。

6 ) 实战:信息管理系统的优化

  • 实体类:抽取 Person 父类,Student、Teacher 继承。
  • 控制器层:
    • 抽取 BaseStudentController 抽象父类,定义模板方法 start()、addStudent() 等并声明为 final。
    • 将差异方法 inputStudentInfo() 声明为抽象方法,由子类 StudentController、OtherStudentController 分别实现。
    • 符合开闭原则,新增子类时无需修改父类代码。
    • 数据访问层:在 StudentDao 中使用静态代码块初始化初始学生数据,方便测试。

要领:面向对象编程中,通过继承提升复用,通过抽象规范行为,通过 final 锁定核心,通过代码块巧设初始化,最终构建出灵活、可维护的应用程序架构。

如果需要更简短的结论,一句话:以继承和抽象为核心的模板设计模式,结合 final 约束和各类代码块,能够有效提升 Java 项目代码的结构化、复用性和可维护性。

[NoC]Outstanding和Credit的概念详解 摘要:本文详细解析了计算机体系结构中outstanding和credit两个核心概念。outstanding指已发出但未完成的请求数量,通过跟踪未决事务实现并发和乱序执行,常见于AXI总线等场景;credit则是基于信用令牌的流控机制,通过控制发送速率防止接收端缓冲溢出,多用于NoC网络。二者在目的、机制上存在差异:outstanding侧重提升并发度,credit关注流控保护。文章通过AXI协议实例和SystemC代码示例展示了二者的应用与结合方式,并探讨了在SoC设计中参数优化的方法,包括性能/资源权衡 阅读详情

相关推荐

如何从零开始写小程序

看了这篇文章,即使让我现在就从头写一个能够正常运行的小程序,也没有原本想象中的那么难了。 在本文中,我们将会以一个具体的小程序为例,带领大家从零到一完成一个小程序的开发流程,并将这个小程序上传到 FinClip.com 进行小程序提审与上架操作。 我们新建了一个叫做「HelloWorld」的小程序,FIDE 在初始化小程序项目时,会自动在项目目录中补充对应所需要的项目文件。那不妨让我们先从小程序目录下的配置文件开始,逐渐揭开小程序的面纱。 使用 FIDE 编辑小程序 1. 认识 json 文件 在小程序项目

POHOU23的博客 4396

Java 高级教程

1. 数据结构 Java2中引入了一种新的框架-集合框架(Collection) 2. 集合接口 (1) 用得最多的是list接口和set接口。 (2) List 接口存储的是有序的,可以重复的元素。 Set 接口存储的是无序的,不重复的数据。 (3) List接口检索效率高,插入和删除效率低。 Set接口检索效率低,插入和删除效率高。 (4)Map.Entry: 描述Map中的一个元素(键/值对)。 3. 集合实现类 (1) ArrayList: 实现了List的接口, 随机访问和..

1823

2024高教社杯数学建模国赛B题丨国一原创论文解析及源码超详细分享!

继续分享一篇2024国赛B题的国奖论文,包含可运行源代码jupyter,国赛B题通常比较聚焦实际复杂系统的多目标优化决策,主要偏重算法实现与概率建模解决开放性的管理问题。而且高度开放,无标准答案,学科交叉复杂,如资源调度、交通优化、海洋探测等。比较建议有一定统计学基础的同学参加。

ihui永不放弃 6740

java 常用代码

Java常用代码

lwq597的博客 1万+

IC设计新手必看:如何正确使用去耦电容(decap)避免电源噪声?

本文深入探讨了IC设计中去耦电容(decap)的应用技巧,从核心原理到布局实现,帮助新手工程师有效抑制电源噪声。文章详细解析了MIM、MOM等电容类型的特性与选择策略,并提供了先进的布局技巧和验证方法,特别适用于28nm以下先进工艺的电路设计挑战。

weixin_30555125的博客 116

Databricks Genie:语义编译器架构与企业级智能解析实践

语义层是现代数据平台实现自然语言查询的核心基础,其本质是将业务术语映射为可执行、可治理的数据契约。原理上依赖结构化元数据、值字典与数据血缘三支柱协同,通过分层AI代理(如Intent Parsing、Retriever、Verifier)实现意图识别→语义对齐→安全执行的闭环。技术价值在于降低SQL使用门槛的同时保障审计性、一致性和权限可控性,适用于销售运营、财务分析等一线业务场景。本文深入解析Databricks Genie作为典型语义编译器的落地逻辑,涵盖Unity Catalog知识注入、七层Agen

weixin_29053695的博客 338

50个JAVA常见代码大全:学完这篇从Java小白到架构师

Java,作为一门流行多年的编程语言,始终占据着软件开发领域的重要位置。无论是初学者还是经验丰富的程序员,掌握Java中常见的代码和概念都是至关重要的。本文将列出50个Java常用代码示例,并提供相应解释,助力你从Java小白成长为架构师。

penggerhe的博客 8万+

OAuth2.0集成SpringSecurity加JWT实现单点登录

单点登录(Single sign on),英文名称缩写SSO,SSO的意思就是在多系统的环境中,登录单方系统,就可以在不用再次登录的情况下访问相关受信任的系统。也就是说只要登录一次单体系统就可以

Nicky's blog 9039

JAVA基础(9.面向对象:继承、抽象、方法重写)

面向对象:继承、抽象、方法重写

weixin_45707083的博客 752

微信小程序 - 真机调试请求异常 Provisional headers are shown,微信小程序开发者工具调试没问题就真机测试时出现请求报错(微信小程序请求接口提示Provisional h)

微信小程序开发 Request Headers: Provisional headers are shown,微信开发工具请求正常,真机调试和上线之后出现 Provisional headers are shown,微信小程序开发工具调试没问题,真机调试Provisional headers are shown,在开发工具调试,请求正常没问题,使用真机调试,请求异常,微信小程序真机调试时后台是本地服务器,显示“Provisional headers are shown”问题解决,微信小程序websocket

🏆 前端领域优质创作者 1万+

【深度学习|Transformer模型学习】什么是前馈神经网络(Feed-Forward Neural Network)?将前馈神经网络中的全连接层变成1*1卷积层会有什么样的效果?

【深度学习|Transformer模型学习】什么是前馈神经网络(Feed-Forward Neural Network)?将前馈神经网络中的全连接层变成1*1卷积层会有什么样的效果?

985小水博的摸鱼日常 1377

Java面向对象编程:从基础到高级

修饰符] class 类名{1.成员变量//2.构造方法3.成员方法访问权限 返回类型 方法名(形参){类名要符合见名知义的原则,首字母要大写,以多个单词组成的类名的每个单词首字母均大写。//举例int age;

2301_80888241的博客 1084

RK3568平台开发系列讲解(项目篇)手写数字识别

📢 本篇章带大家基于飞桨(PaddlePaddle),完成一个简单的手写数字识别任务。

内核笔记 1183

【Java 基础编程】Java 面向对象进阶:static/final、抽象类、接口、单例模式

本文介绍了Java面向对象编程的高级特性,主要包括static、final、抽象类和接口等核心概念。重点讲解了static关键字在类变量和类方法中的应用,以及代码块(静态代码块和普通代码块)的执行顺序和使用场景。此外还涉及单例模式、final修饰符的特点,以及抽象类和接口的区别。这些特性能够帮助开发者设计更加灵活、健壮的程序架构,提高代码的可维护性和扩展性。

懿轩的技术小窝 1130

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

帮你快速了解Java抽象类、接口和多态

大家好,我是KookNut39也是Tommy,在优快云写文,写Java时候我是Tommy,分享一些自己认为在学习过程中比较重要的东西,致力于帮助初学者入门,希望可以帮助你进步。感兴趣的欢迎关注博主,和博主一起学习Java知识。大家还可以去专栏查看之前的文章,希望未来能和大家共同探讨技术。 文章目录面向对象特征——多态1.抽象类2.接口多态final关键字 面向对象特征——多态 学习多态之前我们应该先学习抽象类和接口,因为抽象类和接口是实现多态的前提。 1.抽象类 如果自上而下在类的继承层次结构中上移.

KOOKNUT的博客 1324

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

[Java基础]面向对象

/ 模拟ArrayList集合@Override// 使用泛型// true如果需要, 可以进一步使用extends限制泛型的范围表示类型E必须是Animal类型或者是Animal的子类类型变量建议用大写的英文字母,常用的有:E、T、K、V等// 学生类// 老师类// 自定义泛型接口// 数据操作接口// 学生操作实现类@Override@Override@Override@Override// 老师操作实现类。

. 1594

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

1个月征服Java:零基础直达企业级开发——Java面向对象高级

本文系统讲解了面向对象编程的高级特性,包括静态修饰符、继承、多态、抽象类和接口等核心概念。首先介绍了static关键字修饰成员变量和方法的用法,及其在工具类和单例模式中的应用。其次详细阐述了继承的特性,包括方法重写、访问权限控制等。在多态部分,重点讲解了对象多态和行为多态的实现方式及优势。随后探讨了final关键字的用法和常量定义。最后深入讲解了抽象类和接口的特点、应用场景及其区别,包括JDK8新增的接口特性。这些内容构成了Java面向对象编程的核心知识体系,为开发复杂应用程序奠定了基础。

阳光开朗大男孩 = ̄ω ̄=的博客 970

Java零基础快速入门

这篇Java基础复习笔记系统整理了Java核心知识点,主要包含以下内容: 核心特性:封装(属性私有+公共方法)、继承(IS-A关系)、多态(编译时重载/运行时重写)三大面向对象特性,以及编译运行机制。 基础语法:访问权限控制、开发环境组成、8种基本数据类型与缓冲池机制、字符串特性与相关类对比、变量分类及运算符使用。 关键字解析:final(不可变性)、static(类共享成员)、this/super(对象引用)、instanceof(类型判断)等关键字的用法和限制。 面向对象核心:类与对象关系、继承与重写规

weixin_47759174的博客 694

继承详解,快速入门

文档讲解了Java中继承的概念,包括子类如何继承父类的属性和方法,构造函数的调用顺序,以及如何使用`super`关键字。还介绍了如何通过父类引用来实现多态,调用子类的方法,并提供了相关代码示例。

云生的博客 2223

JAVA final关键字 抽象类专题(韩顺平)

一.final关键字 1.final使用情况 final可以修饰类,属性,方法和局部变量 在以下情况下,我们可能需要使用final 1)当不希望类被继承时,可以用final修饰 2)当不希望父类的某个方法被子类覆盖/重写(override)时,可以用final修饰 【案例演示:访问修饰符 final 返回类型 方法名】 3)当不希望类的某个属性的值被修改,可以用final修饰 【案例演示:public final double TAX_RATE = 0.08(一般用大写来表示某个属性的值不能

wztmds的博客 699

java基础-面向对象

这章分享面向对象高级技巧:包含枚举、封装、继承、多态、抽象类、内部类、函数式编程、常用API等内容

qq_44930306的博客 1011

Java | final关键字快速上手【通俗易懂,看这篇就够了】

图文并茂,通俗易懂,带你快速上手final关键字

做技术人 · 产优质博客 · 找好工作 2493

java基础-第六章 继承、多态、抽象类、接口

前面介绍了面向对象中类和对象的概念以及如何将数据放到类和对象中(封装),本章将继续介绍三大特性中继承和多态的概念。以及如何使用抽象类和接口来约束类。有时我们的某些方法(功能)在父类中并不会定义其具体的实现功能,而是只想表示有这个功能,具体实现交给子类完成,这样的功能(方法)没有方法体,叫抽象方法,拥有抽象方法的类叫抽象类。用abstract关键字来修饰抽象类和抽象方法。接口是为了解决抽象类的一个弊端出现的。抽象类的弊端:抽象类中的某些抽象方法,对于某子类而言是不需要的,但该子类却必须继承并重写。

m0_74606902的博客 796

面向对象JAVA基础知识(3)

关键字进行修饰1)如果一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就是抽象类。2)抽象类除了不能实例化对象之外,类的其它功能依然存在,成员变量、成员方法和构造方法。3)用abstract修饰的类就是抽象类。如果某个类中包含有抽象方法,那么该类就必须定义成抽象类。

2303_77640525的博客 1468

Java——代码块、继承篇

面向对象之代码块、继承 一、代码块的概述和分类 A:代码块概述 在Java中,使用{}括起来的代码被称为代码块。 B:代码块分类 根据其位置和声明的不同,可以分为局部代码块,构造代码块,静态代码块,同步代码块(多线程讲解)。 C:常见代码块的应用 a:局部代码块 在方法中出现;限定变量生命周期,及早释放,提高内存利用率 b:构造代码块 在类中方法外出现;多个构造方法方法中相同的代码存放到一...

panda_burn的博客 163

面向对象高级二:多态 final 抽象类 接口

a.默认方法:可以带方法体 必须用default修饰 默认public 也是实例方法 要使用类的对象访问。b.私有方法:可以带方法体 必须用private修饰 也是实例方法 要使用类的对象访问。因为private 所以不能在其他类被调用 可以在test1里加上test2方法的调用。c.私有方法:可以带方法体 必须用static修饰 默认public。识别技巧:编译看左边 运行看右边(多态)编译阶段是谁的,运行阶段就是。编译看左边 运行看右边(变量)(1)接口中新增的三个方法。(3)使用接口的注意事项。

2401_83837907的博客 401
上一篇: Java基础快速入门:面向对象高级与信息管理系统实战
下一篇: Java基础快速入门:面向对象高级之接口、多态与内部类
Wang's Blog
博客等级 码龄12年 7433粉丝 2421原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Wang's Blog

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值