方法重载、重写、隐藏(new)的区别

这三个动词看起来没有多大的区别,很多人也都很混淆这三个方法,粗略的认为他们可以理解成一个意思,其实他们有着本质的区别,下面就来看看他们的不同之处吧!
 方法重载;
  在一个类中允许有几个同名的方法,前提是,这些同名方法必须有不同的调用参数(参数个数不同、参数类型不同),这样的好处是可以根据传递参数的不同来调用同一个类中的不同方法。
  举个例子,最简单的一个求和Sum()方法,当传递两个参数的话就调用有两个参数的Sum()方法,当传递三个参数的话就调用含有三个参数的Sum()方法。
   public double Sum(int num1,int num2)
   {
     return num1+num2;
   }
   public double Sum(int num1,int num2,int num3)
   {
     return num1+num2+num3;
   }
 这就是方法重载,方法重载在构造函数中用的比较多。


方法重写(virtual,override):
方法重写一般用在继承的虚方法中,方法重写的目的是现实多态,当在基类中有一个方法,而想在派生类中覆盖它时,应该把基类中的方子法声明为virtual的,他的含义是让派生类具有同样名字和参数表示的方法被调用,而不是调用基类中的子方法。而在派生类中声明次方法的时候必须用override关键字声明。
 举个最简单的例子:
 有一个People父类,他有一个GuoJI()方法,默认情况下他显示是一个中国人,而有一个American子类继承People父类,在继承GuoJi()这个方法就有点不合逻辑了,所以他就需要重写这个方法:
Class People
{
public virtual void GuoJi()
{
Console.WriteLine("大家好,我来自中国!");
}
}
Class American:People
{
public override void GuoJi()
{
Console.WriteLine("大家好,我来自美国!");
}
}
 这样的话在主函数的入口处:
People p1=new People();
p1.GuoJi();

People p2=new American();
p2.GuoJi();//调用父类中有的虚方法(实质在子类中对这一方法进行了重写)
Console.Readkey();

 运行后的显示结果是:
大家好,我来自中国!
大家好,我来自美国!

隐藏(new关键字):
上面方法重写中,当不能把基类中的方法声明为Virtual时,可以用另一种方法来实现上面例子中的功能,那就是在派生类中声明方法时使用new关键字,从而有效的隐藏基类中的同一名字的方法(次方法与参数无关)。
这种方式不叫重写,子类跟父类中的同名方法因为new这一关键字的关系而没有半毛钱的联系,所以子类可以调用自己类中的这一方法而不会被基类中的同名方法所干扰。
(需要注意的是,new关键字不可以用在抽象类中,因为抽象类中的抽象方法必须重写)
还是上面的那个例子,我们来看一下用new的实现方法:
Class People
{
public void GuoJi()
{
Console.WriteLine("大家好,我来自中国!");
}
}
Class American:People
{
public new void GuoJi()//用new关键字来隐藏父类中的同名方法
{
Console.WriteLine("大家好,我来自美国!");
}
}
 这样的话在主函数的入口处:
People p1=new People();
p1.GuoJi();

American p2=new American();//这里不能用People p2=new American();
p2.GuoJi();//注意这里调用的GuoJI()方法是子类自己的,不属于父类。
Console.Readkey();

  运行后的显示结果是:
   大家好,我来自中国!
   大家好,我来自美国!
   所以呢以后在遇到关于方法重载、方法重写、隐藏(new)时多少应该知道个123了吧。

<think>嗯,用户问的是怎么理解方法重载重写。首先,我需要回忆一下这两个概念的定义和区别方法重载(Overload)应该是在同一个类里面,方法名相同但参数列表不同,返回类型可以不同。而方法重写(Override)是子类继承父类时,重新实现父类的方法方法名、参数列表和返回类型都要相同。 然后,用户可能是刚开始学习Java的开发者,或者是在准备面试,需要明确这两个概念的区别。他们可能在实际编程中遇到了问题,比如不知道什么时候用重载,什么时候用重写,或者在面试中被问到两者的区别。这时候需要给出清晰的解释,最好有例子说明。 接下来,要确保回答的结构清晰,分点说明两者的定义、区别、应用场景以及注意事项。比如,先分别解释重载重写,然后对比它们的区别,再举例说明,这样用户更容易理解。 还需要注意用户提到的之前的系统级指令,比如行内数学表达式用$...$,但这里可能用不到数学公式,而是代码示例。不过用户之前的回答里用了代码块,比如`@Transactional`,所以可能需要用类似的格式来展示代码例子,比如方法名和参数。 另外,用户可能需要知道为什么要有这两个机制。比如,重载是为了让同一个方法名处理不同的参数类型,提高可读性;重写是为了多态,允许子类有自己的实现。这也是需要强调的。 还要考虑可能的误区,比如重载是否和返回类型有关(无关,只看参数列表),或者重写时访问权限不能更严格(比如父类方法是public,子类不能改成private)。这些细节需要提到,避免用户混淆。 最后,总结两者的核心区别,帮助用户记忆。比如,重载是同类中的不同参数,编译时决定;重写是子类覆盖父类,运行时多态。这样用户就能从机制和效果上区分开来。</think>好的,我将通过对比和示例详细解释方法重载(Overload)和方法重写(Override)的核心区别及实际应用。 --- ### 一、方法重载(Overload) #### 定义与特征 - **同一类中**定义多个同名方法 - **参数列表必须不同**(类型/数量/顺序不同) - **返回值类型可不同**(仅返回值不同不构成重载) - **访问修饰符可不同**(public/protected等) #### 典型场景 ```java public class Calculator { // 重载1:两个int相加 public int add(int a, int b) { return a + b; } // 重载2:三个int相加(参数数量不同) public int add(int a, int b, int c) { return a + b + c; } // 重载3:两个double相加(参数类型不同) public double add(double a, double b) { return a + b; } // 无效重载:仅返回值不同(编译报错) // public double add(int a, int b) { return a + b; } } ``` #### 本质目的 - **增强方法灵活性**:通过不同参数形式实现相同语义操作 - **提高代码可读性**:如`Arrays.sort(int[])`和`Arrays.sort(String[])` --- ### 二、方法重写(Override) #### 定义与特征 - **跨继承关系**:子类重新定义父类方法 - **三同原则**:方法名、参数列表、返回类型必须相同 - **访问权限不能更严格**(父类方法为`protected`,子类可改为`public`,但不可改为`private`) - **异常范围不能扩大**(子类抛出异常必须是父类异常的子类或相同) #### 典型场景 ```java class Animal { // 父类方法 public void speak() { System.out.println("Animal sound"); } } class Cat extends Animal { // 重写方法(实现多态) @Override public void speak() { System.out.println("Meow"); } // 错误示例:参数不同(实际是重载,不是重写) // public void speak(String msg) { ... } } ``` #### 核心机制 - **实现多态**:通过`父类引用指向子类对象`触发动态绑定 ```java Animal myCat = new Cat(); myCat.speak(); // 输出"Meow"(运行时确定实际方法) ``` --- ### 三、关键对比(表格形式) | 特性 | 重载 (Overload) | 重写 (Override) | |---------------------|--------------------------------|----------------------------------| | **作用范围** | 同一类中 | 继承关系的父子类之间 | | **参数列表** | 必须不同 | 必须完全相同 | | **返回值类型** | 可不同 | 必须相同(或为子类型) | | **访问修饰符** | 可不同 | 不能比父类更严格 | | **异常抛出** | 无限制 | 不能抛出更宽泛的检查型异常 | | **绑定阶段** | 编译时静态绑定 | 运行时动态绑定 | | **存在意义** | 扩展方法适用场景 | 实现多态行为 | --- ### 四、特殊注意事项 1. **`@Override`注解** 强烈建议在重写方法上添加该注解,编译器会检查是否符合重写规则,避免因拼写错误导致意外重载。 2. **协变返回类型**(Java 5+) 允许重写方法的返回类型是父类方法返回类型的子类: ```java class Parent { Number getValue() { return 0; } } class Child extends Parent { @Override Integer getValue() { return 42; } // 合法 } ``` 3. **静态方法隐藏** 静态方法不能重写,但子类可定义同名静态方法(实际是隐藏父类方法): ```java class Parent { static void show() { System.out.println("Parent"); } } class Child extends Parent { static void show() { System.out.println("Child"); } // 隐藏而非重写 } ``` --- ### 五、实战应用场景 1. **重载典型应用** - `System.out.println`支持不同参数类型(int/String/Object等) - `StringBuilder`的`append`方法处理多种数据类型 2. **重写典型应用** - 模板方法模式:父类定义算法骨架,子类重写具体步骤 ```java abstract class Game { abstract void initialize(); // 需子类重写 final void play() { // 模板方法 initialize(); startGame(); endGame(); } } ``` --- 理解两者的核心差异后,可通过以下口诀快速记忆: **重载同类参数异,重写继承三相同; 编译绑定看重载,运行多态靠重写。**
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值