关于异常对重写和重载的影响

本文详细介绍了在面向对象编程中方法重载与重写的概念及其必要条件,并通过具体的Java代码示例解释了异常对重写的影响。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

如有不正确之处,希望有大神能指出来,我写的不一定是对的,仅供参考!

实现方法重载的必要条件:

(1)在同一个类中  (2)方法的名称相同   (3)参数的个数、类型、顺序不同   (4)与返回值类型和访问权限无关   (5)与异常无关

 

 

实现方法重写的必要条件:

(1)必须有继承关系   (2)发生在子类   (3)方法的名称相同    (4)参数的列表   (5)返回值类型与父类方法的返回值类型相同或者是父类方法返回值的子类    (6)访问权限>=父类

 

异常对重写的的影响:

(1)如果父类的方法使用throws声明一个Exception类型的异常,那么子类在重写该方法时,如果没有调用父类的方法,无需做处理 ,如果调用了父类的方法,要求必须做处理,处理方式两种,try-catch或throws向上声明!

(2)如果父类的方法没有异常,子类在重写该方法时,如果有Exception类型异常,必须自己做处理try-catch!如果不想处理,给父类中的方法使用throws添加异常。

(3)子类重写方法时,抛出的异常类型与父类方法抛出的异常类型相同,或都是父类异常的子类!

举例:父类 方法抛出是Exception  那么子类抛出的异常类型,可以是Exception或Exception的子类(RuntimeException)

package com.test.test;

public class Father {
	public void show() throws Exception{
		
	}
	
	class Son extends Father{
		@Override
		public void show() throws Exception {
			super.show();
		}
	}
}
package com.test.test;

public class Father {
	public void show() throws Exception{
		
	}
	
	class Son extends Father{
		@Override
		public void show() throws RuntimeException {
			
		}
	}
}

 

<think>我们正在讨论重写(Override)重载(Overload)的区别。根据用户提供的引用内容,我们可以总结如下: 1. **定义**: - **重载(Overload)**:在同一个类中,方法名相同,但参数列表(参数类型、个数、顺序)不同的方法。返回类型可以不同,但不能仅通过返回类型不同来区分重载方法。 - **重写(Override)**:发生在子类父类之间,子类重新定义父类中已有的方法。方法名、参数列表返回类型(或子类型)必须相同。 2. **发生位置**: - 重载:同一个类中。 - 重写:子类中。 3. **多态性**: - 重载:编译时多态(静态多态)。编译器在编译时根据方法签名(方法名参数列表)决定调用哪个方法。 - 重写:运行时多态(动态多态)。在运行时根据对象的实际类型(子类)来决定调用哪个方法。 4. **方法签名**: - 重载:必须改变参数列表(参数类型、个数或顺序),返回类型可以相同也可以不同,访问修饰符抛出的异常可以不同。 - 重写:方法签名(方法名参数列表)必须相同;返回类型必须相同或是父类方法返回类型的子类型;访问修饰符不能比父类更严格(即子类方法访问权限不能小于父类方法);抛出的异常不能比父类方法抛出的异常更宽泛(即子类方法抛出的异常必须是父类方法抛出异常的子类或不抛出异常)。 5. **应用场景**: - 重载:用于处理同一功能的不同参数情况,例如,一个加法方法可以重载为处理整数、浮点数等。 - 重写:用于子类需要改变父类方法的行为时,例如,动物类有`makeSound`方法,狗类重写该方法以发出狗叫。 6. **其他限制**: - 重载:不能通过返回类型来区分,因为调用时可能无法确定。 - 重写:子类方法不能抛出比父类方法更宽泛的检查异常(即不能抛出父类方法未声明的检查异常,或者更宽泛的检查异常)。非检查异常(RuntimeException)不受此限制。 下面用代码示例说明: **重载示例(在同一个类中)**: ```java public class Calculator { // 两个整数相加 public int add(int a, int b) { return a + b; } // 重载:三个整数相加 public int add(int a, int b, int c) { return a + b + c; } // 重载:两个浮点数相加 public double add(double a, double b) { return a + b; } } ``` **重写示例(子类重写父类方法)**: ```java class Animal { public void makeSound() { System.out.println("Animal makes a sound"); } } class Dog extends Animal { @Override public void makeSound() { // 重写父类方法 System.out.println("Dog barks"); } } public class Main { public static void main(String[] args) { Animal myAnimal = new Dog(); // 向上转型 myAnimal.makeSound(); // 输出"Dog barks",运行时多态 } } ``` **总结表格**: | 特性 | 重载 (Overload) | 重写 (Override) | |--------------|------------------------------------------|------------------------------------------| | **定义** | 同一类中,方法名相同,参数列表不同 | 子类重新定义父类方法 | | **位置** | 同一个类 | 子类 | | **多态性** | 编译时多态 | 运行时多态 | | **方法签名** | 必须不同(参数类型、个数、顺序) | 必须相同 | | **返回类型** | 可以不同 | 必须相同或是父类返回类型的子类型 | | **访问修饰符**| 可以不同 | 子类方法访问权限不能比父类更严格 | | **异常** | 可以不同 | 子类方法不能抛出更宽泛的检查异常 | | **作用** | 提供同一功能的不同版本(参数不同) | 改变父类方法的行为 | 通过以上对比,我们可以清晰地理解重载重写的区别。重载是在同一个类中多个同名方法根据参数不同而不同,重写是子类对父类方法的具体实现进行覆盖。 §§相关问题§§ 1. 为什么重载不能根据返回类型来区分? 2. 重写时如果返回类型是父类方法返回类型的子类,具体如何实现? 3. 在Java中,如何防止一个方法被重写?</think>### 重写(Override)与重载(Overload)的区别详解 #### 1. **核心定义** | **特性** | **重载 (Overload)** | **重写 (Override)** | |----------------|----------------------------------------|-----------------------------------------| | **发生位置** | 同一个类中 | 子类与父类之间 | | **方法签名** | 方法名相同,**参数列表不同** | 方法名、参数列表、返回类型**完全相同** | | **多态类型** | 编译时多态(静态绑定) | 运行时多态(动态绑定) | | **核心目的** | 处理不同类型/数量的参数 | 改变父类方法的行为 | #### 2. **技术特性对比** - **参数要求** - 重载:必须改变参数类型/数量/顺序 ```java // 重载示例:参数类型不同 void print(int a) { ... } void print(String s) { ... } // ✅ 有效重载 ``` - 重写:参数列表必须与父类完全一致 ```java class Parent { void show(int x) { ... } } class Child extends Parent { @Override void show(int x) { ... } // ✅ 有效重写(参数相同) } ``` - **返回类型** - 重载:返回类型可自由修改 ```java int calculate() { ... } // 返回int String calculate() { ... } // ❌ 编译错误!仅返回类型不同不构成重载 ``` - 重写:返回类型必须相同或是父类返回类型的**子类型**(协变返回) ```java class Animal { Animal create() { ... } } class Dog extends Animal { @Override Dog create() { ... } // ✅ 协变返回(Dog是Animal子类) } ``` - **访问权限** - 重载:访问修饰符可任意修改(public/protected/private) - 重写:子类方法访问权限**不能严于父类** ```java class Parent { protected void demo() { ... } } class Child extends Parent { @Override public void demo() { ... } // ✅ 更宽松(允许) // private void demo() { ... } // ❌ 编译错误!更严格禁止 } ``` - **异常处理** - 重载:可抛出任意异常 - 重写:**不能抛出更宽泛的检查异常** ```java class Parent { void test() throws IOException { ... } } class Child extends Parent { @Override void test() throws FileNotFoundException { ... } // ✅ 子异常 // void test() throws Exception { ... } // ❌ 更宽泛异常 } ``` #### 3. **多态机制差异** | **阶段** | **重载** | **重写** | |------------|-----------------------------------|-----------------------------------| | **编译时** | 编译器根据**参数类型**确定调用方法 | 编译器检查方法签名是否匹配父类 | | **运行时** | 无动态绑定 | JVM根据**对象实际类型**调用方法 | **示例说明**: ```java class Animal { void sound() { System.out.println("Animal sound"); } } class Dog extends Animal { @Override void sound() { System.out.println("Bark!"); } // 重写 // 重载 void sound(int volume) { System.out.println("Bark at volume: " + volume); } } public class Test { public static void main(String[] args) { Animal a = new Dog(); // 向上转型 a.sound(); // 输出"Bark!"(运行时多态) // a.sound(10); // ❌ 编译错误!Animal类无此方法 Dog d = new Dog(); d.sound(10); // ✅ 输出"Bark at volume: 10"(编译时多态) } } ``` #### 4. **设计思想差异** - **重载**:实现**横向扩展**(同一类提供多种参数处理方式) ```java class MathUtils { // 处理不同参数类型的加法 int add(int a, int b) { return a + b; } double add(double a, double b) { return a + b; } } ``` - **重写**:实现**纵向扩展**(子类定制父类行为) ```java abstract class Shape { abstract double area(); // 抽象方法 } class Circle extends Shape { @Override double area() { ... } // 实现具体计算 } ``` #### 5. **常见误区澄清** - **重载重写** - 仅方法名相同是重载的必要条件,参数不同是充分条件 - 子类中与父类**同名不同参**的方法属于重载而非重写 - **静态方法特殊规则** ```java class Parent { static void method() { ... } } class Child extends Parent { // 这是隐藏(hide)而非重写! static void method() { ... } } ``` > **核心总结**: > 重载解决**参数多样化**问题(编译时确定),重写实现**行为定制化**问题(运行时确定)。两者共同构成面向对象的多态性支柱[^1][^2][^3]。 --- ### 重载重写对比速查表 | **特性** | 重载 (Overload) | 重写 (Override) | |------------------|-------------------------|--------------------------| | 作用范围 | 同一个类 | 子类 vs 父类 | | 参数列表 | **必须不同** | **必须相同** | | 返回类型 | 可修改 | 相同或协变类型 | | 访问修饰符 | 可任意修改 | 不能更严格 | | 异常声明 | 无限制 | 不能抛出更宽泛检查异常 | | 绑定时机 | 编译时 | 运行时 | | 多态类型 | 静态多态 | 动态多态 | | 继承要求 | 不需要 | 必须存在继承关系 |
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值