jvm--重载重写原理

一个重载的栗子:
class Parent ...
class Child extends Parent ...
class Overload{
public static void overload(Parent p) ...
public static void overload(Child c) ...
public static void main() {
Parent p = new Child();
Overload.overload(p);
}
}
这个是调用的是:overload(Parent p)方法。虽然p的实际引用类型是Child;
这要提到两个重要的概念:
上段栗子中,对于对象p来说,Parent称为其 静态类型或者外观类型,Child是其实际类型。对象本身的静态类型是不会变的,但是实际类型是可以变化的,要在实际执行代码中才能确定。


那么依赖静态类型来定义方法执行版本的分派动作称为静态分派。典型应用就是重载。
同理依赖实际类型来定义方法执行版本的分派动作称为动态分派。典型应用就是重写。


其实重写的原理也是继承多态的原理。


一个多态+重写(覆盖)的栗子:
class Parent --> print方法
class Child extends Parent --> print方法
Parent p = new Child(); p.print();
将子类赋值给父类p,p只能调用Parent中的方法,但是print方法被重写了,print的实现还是Child中的实现。


以上两个类,加载到jvm中,类信息会被保存在方法区。
像开头那样,用一个基类的引用指向子类对象,这个引用绑定的类仍然是子类,只不过它能访问的方法表与一般子类对象不同,方法表会限定这个类访问的方法范围为引用类定义的范围内。


Class编译过程中不包含连接步骤,一切的方法调用在Class文件中存储的都是符号引用,而方法的实际调用需要到类加载期间,甚至运行期间才能确定。
1、在类加载的解析期间会将其中一部分符号引用转化为直接引用。包括私有方法以及静态方法,这两种方法都不会通过继承或者重写的方式被覆盖。譬如:
invokestatic和invokespecial,能被这两个指令调用的方法都可以在类加载解析阶段确定调用版本,如:静态方法,私有方法,类构造器,父类方法,这些方法会在编译器将符号引用解析为直接引用。这些方法称为非虚方法。另外final修饰的方法虽然是被invokevirtual调用,也是非虚方法。
2、上面栗子中,方法调用时使用invokevirtual 调用的是Parent的print的方法,却是Child的实现。invokevirtual会做如下事情:先找到实际类型,在实际类型中寻找相符的方法,若没找到,则按照继承关系从下到上寻找相符合的方法,若都没找到抛出异常。
<think>首先,用户要求详细解释Java中的继承、多态、重载重写概念。我需要基于提供的引用来回答,但引用不是用户真正的需求;我应该参考用户上一次的问题和我的回答。用户上一次的问题是关于Java继承、多态、重载重写的详细解释,所以我会直接回答这个。 系统级指令: - 数学表达式使用$...$格式(但这里可能不需要,因为是Java概念)。 - 独立公式使用$$...$$格式(同样,可能不适用)。 - LaTeX语法正确(所以如果使用数学,要用LaTeX)。 - 使用中文回答。 - 生成相关问题。 - 回答中引用的段落末尾添加引用标识,例如[^1]。 回答结构: - 结构清晰,帮助用户逐步解决问题。 - 尽量保证回答真实可靠(基于我的知识)。 关键概念: 1. **继承(Inheritance)**:子类继承父类的属性和方法。 2. **多态(Polymorphism)**:对象可以以多种形式出现,特别是在运行时绑定。 3. **重载(Overloading)**:同一类中多个方法同名但参数不同。 4. **重写(Overriding)**:子类覆盖父类的方法,参数相同。 从引用中提取要点: - 引用[1]:多态通过后期绑定实现,消除耦合,帮助扩展。重载重写是多态的表现。 - 引用[2]:继承使用extends关键字,包括重载重写、构造、多态等。 - 引用[3]:重载在同一类中,方法名相同但参数不同;重写子类中,方法签名相同。 - 引用[4]:重载重写的示例代码。 我的回答结构: 1. **引言**:简要介绍这些概念。 2. **详细解释每个概念**: - 继承 - 多态 - 重载 - 重写 3. **结合例子**:从引用中取例子或创建简单例子。 4. **总结**:关系和作用。 5. **生成相关问题**:在最后部分。 生成相关问题:系统指令要求生成相关问题,所以回答末尾添加§§相关问题§§部分。 使用中文回答。 引用添加:在回答中,如果引用特定段落,末尾添加引用标识。既然用户提供了引用[1]到[4],我应该参考它们,但不是直接复制。 构建回答: - 先定义每个概念。 - 解释关系:重载重写是多态的实现方式。 - 示例:使用简单Java代码片段(用code block,如示例中的Python代码)。 代码格式:示例中用```python...```,我应该用```java...```。 逐步解释: 1. **继承**: - 定义:子类继承父类的属性和方法- 优点:代码重用,易于扩展。 - 例子:来自引用[2],SUPER.java和SUPERA.java。 2. **重载**: - 定义:同一类中多个方法同名但参数列表不同(类型、数量或顺序)。 - 例子:引用[4],Instrument类的play方法重载。 3. **重写**: - 定义:子类覆盖父类的方法,参数相同(签名相同)。 -重载区别:重载在同类,重写在继承关系中。 - 例子:引用[3],子类重写父类方法。 4. **多态**: - 定义:对象在不同上下文表现出不同行为;通过后期绑定实现。 - 作用:减少耦合,增强扩展性。 - 例子:引用[1],CarShop类处理不同车型。 关系:继承启用多态;重写是多态的关键;重载是同类的多态形式。 最后,生成相关问题。 完整回答大纲: - 介绍Java OOP概念。 - 继承:解释和例子。 - 重载:解释和例子。 - 重写:解释和例子。 - 多态:解释和例子。 - 总结关系。 - §§相关问题§§:3-5个相关问题。 确保真实可靠:基于标准Java知识。 </think>### Java中继承、多态、重载重写的详细解释 在Java面向对象编程(OOP)中,继承、多态、重载重写是核心概念。它们共同支持代码的可重用性、灵活性和扩展性。下面我将逐步解释每个概念的定义、作用、例子及其相互关系,确保解释清晰易懂。回答基于您的引用内容,并结合标准Java知识进行扩展。 #### 1. **继承(Inheritance)** - **定义**:继承允许一个类(子类)基于另一个类(父类)来构建新类,从而复用父类的属性和方法。Java中使用`extends`关键字实现继承。 - **作用**:减少代码重复,便于扩展功能。例如,当新增功能时,只需创建子类继承父类,而无需修改原有代码。 - **例子**:引用[2]中提到一个示例,创建父类`SUPER.java`和子类`SUPERA.java`。假设`SUPER`是通用父类,`SUPERA`继承它: ```java // 父类 SUPER.java public class SUPER { public void display() { System.out.println("This is the parent class"); } } // 子类 SUPERA.java public class SUPERA extends SUPER { // 使用extends继承 // 子类可以添加新方法重写父类方法 } ``` - 在`Test.java`中,子类对象可以直接调用父类的`display()`方法,体现了代码复用性[^2]。 - **关键点**:子类继承父类的所有非私有成员(属性和方法),但构造器不被继承(需通过`super()`调用)。 #### 2. **重载(Overloading)** - **定义**:重载指在同一个类中,定义多个同名方法,但参数列表不同(例如参数类型、数量或顺序不同)。返回值类型可以相同或不同,但仅返回值不同不足以构成重载- **作用**:提高代码可读性和灵活性,允许方法根据输入参数自动选择执行逻辑。 - **例子**:引用[4]中展示了`Instrument`类的重载示例: ```java public class Instrument { // 重载方法1: 接受一个int参数 public void play(int i) { System.out.println("Instrument " + i); } // 重载方法2: 接受int和String参数 public void play(int i, String str) { System.out.println("Brass " + i + " " + str); } } ``` - 这里,`play`方法名相同,但参数不同(数量和类型),Java编译器在编译时根据参数决定调用哪个方法[^4]。重载是一个类的多态性表现,因为它允许同一方法名处理不同输入[^3]。 #### 3. **重写(Overriding)** - **定义**:重写指在子类中重新定义父类的方法方法签名(方法名、参数列表和返回类型)必须完全相同。重写使用`@Override`注解显式声明(非强制,但推荐)。 - **作用**:实现运行时多态(动态绑定),允许子类提供特定实现,覆盖父类的默认行为。 - **例子**:引用[3]描述了重写的情况。假设父类`Car`有一个方法子类`ElectricCar`重写它: ```java // 父类 Car.java public class Car { public void startEngine() { System.out.println("Engine started with petrol"); } } // 子类 ElectricCar.java public class ElectricCar extends Car { @Override public void startEngine() { // 方法签名相同 System.out.println("Engine started with electricity"); } } ``` - 使用时,通过父类引用调用`startEngine()`,运行时根据实际对象类型执行子类方法。这体现了子类与父类的多态性[^3]。 #### 4. **多态(Polymorphism)** - **定义**:多态指对象可以以多种形式呈现,Java中主要通过运行时绑定(后期绑定)实现。它允许同一操作(如方法调用)作用在不同对象上产生不同行为。 - **作用**:减少代码耦合,增强可扩展性。例如,新增类时无需修改现有代码,只需继承父类并实现方法。引用[1]强调,多态使程序更容易扩展,如新增车型时,`CarShop`类无需改动就能处理新对象[^1]。 - **实现方式**:多态依赖继承和重写- **编译时多态**:通过重载实现,编译器在编译时确定方法调用(如`play`方法的选择)。 - **运行时多态**:通过重写实现,JVM在运行时根据对象实际类型决定调用哪个方法(如`startEngine()`在父类引用上的行为)。 - **例子**:引用[1]的汽车销售场景: ```java public class CarShop { public void sellCar(Car car) { // 参数类型是父类Car car.startEngine(); // 运行时绑定到实际子类重写方法 } } // 使用 CarShop shop = new CarShop(); shop.sellCar(new ElectricCar()); // 输出: Engine started with electricity shop.sellCar(new PetrolCar()); // 输出: Engine started with petrol(假设PetrolCar重写了startEngine) ``` - 这种方式,新增`HybridCar`类继承`Car`后,`sellCar`方法可直接处理,无需修改代码,体现了多态的优势[^1]。 #### 总结关系 - **继承是基础**:它建立了类层次结构,使重写和多态成为可能。 - **重载重写是多态的实现**: - 重载支持编译时多态(同一类内)。 - 重写支持运行时多态(跨继承层次)。 - **多态是核心**:它通过动态绑定实现代码解耦,提升可维护性。引用[3]明确区分:重载是类的多态性,重写是父子类的多态性[^3]。 - **整体作用**:这些概念协同工作,使Java程序更灵活、易于扩展。例如,在引用[2]的示例项目中,继承、重写和多态结合使用,简化了代码结构[^2]。 如果您有具体代码场景或需要更多实例,请随时说明!
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值