🚀 Java面向对象核心揭秘:从构造到多态的实战指南
文章目录
前言
本笔记系统整理Java面向对象编程的核心概念,涵盖构造方法调用规则、方法重载与重写、多态实现机制及类型转换原理,帮助开发者深入理解Java对象模型与继承体系。
一、构造方法调用规则
1. 无参构造方法调用
Student s = new Student(); // 自动调用无参构造方法
- 执行顺序:
- 父类构造方法 → 2. 子类构造方法
- 隐式super():编译器自动添加父类无参构造调用
2. 父类有参构造的强制调用
class Parent {
public Parent(String name) {} // 只有有参构造
}
class Child extends Parent {
public Child() {
super("强制调用"); // 必须显式调用
}
}
- 规则:
- 父类没有无参构造时,子类必须显式调用
super(参数)
super()
必须是构造方法中的第一条语句
- 父类没有无参构造时,子类必须显式调用
- 编译错误示例:
public Child() { System.out.println("子类初始化"); // 错误! super("调用"); // 必须放在第一行 }
二、方法重载与重写
1. 方法重载(Overload)
特性 | 说明 |
---|---|
同个类中 | 方法名相同,参数列表不同 |
返回值无关 | 仅参数类型/数量不同 |
编译时绑定 | 根据调用参数确定方法 |
class Calculator {
// 重载示例
int add(int a, int b) { return a + b; }
double add(double a, double b) { return a + b; }
}
2. 方法重写(Override)
特性 | 说明 |
---|---|
父子类之间 | 子类重定义父类方法 |
方法签名相同 | 方法名+参数列表相同 |
运行时多态 | 根据实际对象类型调用 |
class Animal {
void sound() { System.out.println("动物叫"); }
}
class Cat extends Animal {
@Override
void sound() { System.out.println("喵喵喵"); }
}
三、向上转型与多态
1. 向上转型(Upcasting)
Animal animal = new Cat(); // 父类引用指向子类对象
- 特点:
- 编译时类型 = 父类(Animal)
- 运行时类型 = 子类(Cat)
- 只能访问父类声明的方法
2. 多态实现机制
animal.sound(); // 输出"喵喵喵"(实际调用Cat的方法)
- 核心条件:
- 继承关系
- 方法重写
- 父类引用指向子类对象
- 动态绑定:运行时根据实际对象类型确定方法
3. 静态方法 vs 实例方法
调用方式 | 绑定时机 | 多态支持 |
---|---|---|
animal.staticMethod() |
编译时(按引用类型) | ❌ |
animal.instanceMethod() |
运行时(按实际类型) | ✅ |
四、方法重写规则
1. 核心规则
@Override // 注解确保正确重写
void sound() { ... }
- 必须遵守:
- 方法名和参数列表完全相同
- 返回值类型兼容(相同或是子类)
- 访问权限不能缩小(
public
→private
禁止) - 异常范围不能扩大(
IOException
→Exception
禁止)
2. 重写与super关键字
class Cat extends Animal {
@Override
void sound() {
super.sound(); // 调用父类原始实现
System.out.println("追加猫叫");
}
}
- super使用限制:
- 只能在子类中使用
- 构造方法中必须位于第一行
- 不能与this()同时调用构造方法
五、多态深度解析
1. 多态应用场景
// 统一处理不同子类
void animalConcert(Animal[] animals) {
for (Animal a : animals) {
a.sound(); // 每个对象执行自己的实现
}
}
2. 类型转换与异常
Animal animal = new Cat();
// 向下转型(需显式转换)
if (animal instanceof Cat) {
Cat cat = (Cat) animal;
cat.catchMouse();
} else {
// 类型不匹配处理
}
// 错误转换导致ClassCastException
Dog dog = (Dog) animal; // 抛出异常!
3. 不可重写的情况
修饰符 | 说明 | 示例 |
---|---|---|
static |
类方法,不支持多态 | public static void method() |
final |
禁止重写 | public final void method() |
private |
不可访问 | private void method() |
六、抽象类
abstract
修饰的类为抽象类,可包含抽象方法(只有方法名,无实现)- 抽象类中可定义普通方法,但抽象方法必须在抽象类中
- 抽象类的所有抽象方法必须由子类实现
- 抽象类不能被
new
实例化,只能通过子类继承实现
七、接口
- 接口无法定义具体方法,声明关键字为
interface
- 接口中所有方法默认是
public abstract
(可省略修饰符) - 实现接口的类需通过
implements
关键字,并必须重写接口中所有方法 - 接口支持多继承(一个类可实现多个接口)
- 接口不能被实例化,无构造方法
// Runnable接口定义(Java标准库)
@FunctionalInterface
public interface Runnable {
public abstract void run();
}
八、异常处理机制
- 异常处理五关键字:
try
、catch
、finally
、throw
、throws
try
:监控可能发生异常的代码块catch
:捕获并处理异常finally
:无论是否发生异常,都会执行的善后工作throw
:在方法内主动抛出异常(一般用于业务校验)throws
:在方法声明处声明可能抛出的异常
九、普通方法与多线程
示例代码:
package org.example;
public class ThreadTest1 extends Thread {
@Override
public void run() {
for (int i = 0; i < 20; i++) {
System.out.println("threadtest1");
}
}
public static void main(String[] args) {
ThreadTest1 t = new ThreadTest1();
t.start();
for (int i = 0; i < 2000; i++) {
System.out.println("test2");
}
}
}
常见错误总结:
- 类名必须与文件名一致
- 继承的
Thread
类首字母需大写(Thread
) - 主函数(
main
线程)需定义在当前类中 - for循环快捷写法:输入循环次数+
.fori
@Override
是重写方法的注解(建议添加,确保语法正确)
十、实现Runnable接口
- 步骤:
- 定义类实现
Runnable
接口 - 实现
run()
方法,编写线程执行体 - 创建线程对象,调用
start()
方法启动线程
- 定义类实现
- 核心区别:
main()
是Java程序的入口run()
是线程的入口(线程启动后执行的方法)
总结
核心知识体系:
- 构造方法链:父类构造先于子类执行,有参构造需显式调用
- 方法重写:遵循"两同一小一大"原则(方法名同、参数同;子类异常小/访问权限大)
- 多态本质:向上转型 + 动态绑定 + 方法重写
- 类型安全:用
instanceof
避免ClassCastException
掌握这些面向对象核心机制,是构建健壮Java应用的基础。如果内容对您有帮助,请点赞👍、关注❤️、收藏⭐️。创作不易,您的支持是我持续创作的动力!