JAVA中隐藏和覆盖的区别

本文探讨了Java中继承过程中变量和方法的隐藏与覆盖机制,通过实例代码展示了子类如何隐藏并覆盖父类的变量与方法,以及初始化过程中的细节。

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

隐藏与覆盖

public class Parent{
          int x=10;
          public Parent(){
               add(2);
          }
          void add(int y){
               x+=y;
          }
     }

     class Child extends Parent{
          int x=9;
          void add(int y){
               x+=y;
          }
          public static void main(String[] args){
               Parent p=new Child();
               System.out.println(p.x);
          }
     }
/*
(1)方法和变量在继承时的隐藏与覆盖
     隐藏:若B隐藏了A的变量或方法,那么B不能访问A被隐藏的变量或方法,但将B转换成A后可以访问A被隐藏的变量或者方法。
     覆盖:若B覆盖了A的变量或者方法,那么不仅B不能访问A被覆盖的变量或者方法,将B转换成A后同样不能访问A被覆盖的变量或者方法。
     (2)Java中变量与方法在继承中的隐藏与覆盖规则:
          一、父类的实例变量和类变量能被子类的同名变量隐藏。
          二、父类的静态方法被子类的同名静态方法隐藏,父类的实例方法被子类的同名实例方法覆盖。
          三、不能用子类的静态方法隐藏父类的实例方法,也不能用子类的实例方法覆盖父类的静态方法,否则编译器会异常。
          四、用final关键字修饰的最终方法不能被覆盖。
          五、变量只能被隐藏不会被覆盖,子类的实例变量可以隐藏父类的类变量,子类的类变量也可以隐藏父类的实例变量。
     在上面的试题中,子类Child的实例方法add(int y)覆盖了父类Parent的实例方法add(int y),而子类的实例变量x则是隐藏了父类的实例变量x。
     Child对象的初始化过程是:
     首先为父类的实例变量x分配内存空间,因为在定义变量x时为它赋了值(int x=10),所以会同时将这个值赋给x。
     其次调用父类的无参构造函数,Parent的构造函数中做的唯一的事情就是调用了add(2);
     第三、由于子类的add(int y)方法覆盖了父类的方法,所以add(2)实际调用的是子类的方法,在子类的add方法中做了如下操作x+=j;在这里由于子类的实例变量x隐藏了父类的实例变量x,所以这条语句是针对子类本身的,但是这时还没有为子类的实力变量x分配空间,它的默认值是0,加2之后是2。
     第四、父类初始化完毕后接着初始化子类,为子类的x分配内存空间并将它赋值为9,之前的add(2)操作白瞎了。
     再次注意Parent p=new Child();这条语句,它是用父类的引用指向子类的对象,而前面已经说过变量只会被隐藏不会被覆盖,所以这时的p.x值应该是父类的10,而不是子类的9;
     如果将输出语句换成下面的语句结果就是9了:
     System.out..println(((Child)p).x); //首先将p转换成Child类型
<think>嗯,用户想了解Java中的方法覆盖方法重载的区别。首先,我需要回顾一下这两个概念的定义特点。方法覆盖(Overriding)发生在子类父类之间,子类重新定义父类的方法,要求方法名、参数列表返回类型都相同。而方法重载(Overloading)是在同一个类中,方法名相同但参数列表不同,返回类型可以不同。 接下来,要找出它们的区别。根据引用中的资料,覆盖是多态的表现,用于修改或扩展父类方法的行为。而重载则是同一个类中处理不同参数的情况。另外,覆盖需要方法签名完全一致,而重载的参数必须不同。访问权限方面,覆盖的方法不能比父类更严格,而重载没有这个限制。异常处理上,覆盖抛出的异常不能比父类更宽泛,而重载可以随意。静态方法不能被覆盖,但可以被重载。 还要注意私有方法final方法的情况。引用[4]提到,私有final方法可以重载但不能覆盖。这点需要明确说明。此外,静态方法在覆盖时的表现,如引用[3]中的例子,父类子类的静态方法实际上是隐藏而非覆盖,所以调用时取决于引用类型。 用户可能需要具体的例子来理解这两个概念的区别,所以应该准备代码示例。例如,覆盖的例子中,子类重写父类的某个方法;而重载的例子则是同一个类中有多个同名方法,参数不同。同时,要指出覆盖涉及运行时多态,而重载是编译时多态。 还需要总结两者的异同点,以表格形式呈现可能更清晰。确保覆盖重载的关键点都被涵盖,如发生位置、参数要求、返回类型、访问权限、异常、多态类型等。这样用户能一目了然地看到区别。 另外,用户可能想知道为什么会有这样的设计,或者在实际开发中如何选择使用覆盖或重载。可以简要提及应用场景,如覆盖用于扩展或修改行为,重载用于提供多种处理方式。 最后,检查是否有遗漏的重要点,比如构造函数是否可以重载(可以),是否可以覆盖(不行,因为子类构造函数必须与父类不同名)。不过用户的问题可能不涉及构造函数,所以可能不需要展开。 确保回答结构清晰,分点说明,并引用提供的资料作为支持,比如引用[1]到[5]中的相关内容。同时,生成的相关问题要围绕这两个概念展开,帮助用户进一步学习。</think>### Java 方法覆盖与方法重载的区别 #### 1. **基本概念** - **方法覆盖(Overriding)** 子类重新定义父类中已有的方法,要求**方法名、参数列表、返回类型**完全一致,且访问权限不能更严格,抛出的异常不能更宽泛。目的是修改或扩展父类方法的行为[^1][^3][^4]。 - **方法重载(Overloading)** 在同一个类中定义多个同名方法,但**参数列表必须不同**(类型、顺序或数量不同),返回类型访问权限可以不同。目的是通过不同参数实现功能扩展[^2][^3]。 --- #### 2. **核心区别** | **特征** | **方法覆盖** | **方法重载** | |--------------------|---------------------------------------------------|---------------------------------------------------| | **发生位置** | 子类与父类之间 | 同一个类中 | | **参数要求** | 必须完全相同 | 必须不同 | | **返回类型** | 必须相同(协变返回类型允许子类返回更具体类型)[^5] | 可以不同 | | **访问权限** | 不能比父类更严格(如父类是`public`,子类不能是`private`) | 无限制 | | **异常** | 抛出的异常不能比父类更宽泛(如父类抛`IOException`,子类不能抛`Exception`) | 可以自由定义 | | **多态类型** | 运行时多态(动态绑定) | 编译时多态(静态绑定) | | **静态方法** | 不能覆盖(静态方法属于类,子类同名方法会隐藏父类方法)[^3] | 可以重载 | | **私有/`final`方法** | 不能覆盖[^4] | 可以重载 | --- #### 3. **代码示例** **方法覆盖**: ```java class Parent { public void show() { System.out.println("Parent"); } } class Child extends Parent { @Override public void show() { // 覆盖父类方法 System.out.println("Child"); } } ``` **方法重载**: ```java class Calculator { public int add(int a, int b) { return a + b; } // 重载1 public double add(double a, double b) { return a + b; } // 重载2 } ``` --- #### 4. **应用场景** - **覆盖**:用于实现多态,扩展或修改父类功能(如`@Override`重写`equals()`方法)。 - **重载**:提供多种处理方式(如构造函数重载、工具类方法多参数支持)。 --- #### 5. **注意事项** - **静态方法**:子类中定义的静态方法与父类同名时,属于**隐藏**而非覆盖,调用时取决于引用类型。 - **私有方法**:私有方法不能覆盖,但可以重载(仅在当前类中生效)[^4]。 - **`final`方法**:`final`方法不可覆盖。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值