JAVA中,重写要求,重写与重载区别

在Java中,子类重写(Override)父类方法需要遵循一系列规则,这些规则确保了面向对象的多态性能够正确实现。主要要求如下:

1. 方法签名必须完全一致

  • 方法名、参数列表(参数类型、顺序、个数)必须与父类方法完全相同
    若参数列表不同,即使方法名相同,也属于“重载(Overload)”而非“重写”。

    示例:

    class Parent {
        public void print(int a) { ... } // 父类方法
    }
    
    class Child extends Parent {
        // 正确:方法名和参数列表与父类一致(重写)
        @Override
        public void print(int a) { ... }
        
        // 错误:参数列表不同(这是重载,不是重写)
        // @Override  // 加注解会编译报错
        public void print(String a) { ... }
    }
    

2. 返回值类型需兼容

  • 若父类方法返回基本类型,子类重写的方法必须返回相同的基本类型

  • 若父类方法返回引用类型,子类方法可以返回该类型的子类(称为“协变返回类型”)。

    示例:

    class Parent {
        public Number getValue() { return 0; } // 父类返回Number
    }
    
    class Child extends Parent {
        // 正确:返回Number的子类(Integer)
        @Override
        public Integer getValue() { return 1; }
    }
    

3. 访问修饰符不能更严格

  • 子类重写的方法的访问权限不能比父类方法更严格(可以相同或更宽松)。
    权限等级(从宽到严):public > protected > default(无修饰符) > private

    示例:

    class Parent {
        protected void doSomething() { ... } // 父类为protected
    }
    
    class Child extends Parent {
        // 正确:权限更宽松(public > protected)
        @Override
        public void doSomething() { ... }
        
        // 错误:权限更严格(private < protected)
        // @Override
        // private void doSomething() { ... }
    }
    

4. 异常声明需受限

  • 子类重写的方法不能抛出比父类方法更多、更广泛的检查型异常(Checked Exception)

    • 可以不抛异常,或抛出父类异常的子类异常,或抛出更少的异常。
    • 运行时异常(Unchecked Exception,如NullPointerException)不受此限制。

    示例:

    import java.io.IOException;
    import java.io.FileNotFoundException;
    
    class Parent {
        public void read() throws IOException { ... } // 父类抛IOException
    }
    
    class Child extends Parent {
        // 正确:抛出IOException的子类(更具体)
        @Override
        public void read() throws FileNotFoundException { ... }
        
        // 错误:抛出比IOException更广泛的异常(如Exception)
        // @Override
        // public void read() throws Exception { ... }
    }
    

5. 特殊方法不能被重写

  • 私有方法(private):父类的private方法对子类不可见,子类若定义同名方法,属于新方法(非重写)。
  • 静态方法(static):静态方法属于类而非对象,子类若定义同名静态方法,属于“隐藏(Hide)”而非重写(调用时取决于引用的类型,而非对象实际类型)。
  • 被final修饰的方法final方法是“不可修改的”,子类不能重写。
  • 构造方法:构造方法名与类名一致,子类无法重写父类构造方法(但可以通过super()调用)。

6. 必须使用@Override注解(推荐)

  • 虽然不是强制要求,但显式添加@Override注解可以让编译器检查是否符合重写规则,避免意外错误(如拼写错误、参数不一致等)。

总结:重写的核心是“保持方法签名兼容,权限不收紧,异常不扩大”,同时遵循特殊方法的限制,以确保多态性的正确运行。

在Java中,重写(Override)重载(Overload) 是两个容易混淆但本质不同的概念,核心区别体现在定义、用途和规则上。以下是详细对比:

1. 定义与核心目的

特性重写(Override)重载(Overload)
定义子类对父类中同名、同参数的方法进行重新实现同一个类中,方法名相同但参数列表不同的多个方法
核心目的实现多态:让子类拥有自己特有的行为逻辑方便调用:用同一方法名处理不同参数的场景

2. 关键区别

(1)发生范围不同
  • 重写:必须发生在父子类继承关系中(子类重写父类的方法)。
  • 重载:发生在同一个类中(也包括子类继承的父类方法在子类中被重载的情况,但本质是同一类内)。
(2)方法签名要求不同
  • 方法签名:由“方法名 + 参数列表(参数类型、顺序、个数)”组成。

    • 重写:要求方法签名完全相同(方法名、参数列表必须与父类一致)。
    • 重载:要求方法名相同,但参数列表必须不同(如参数类型不同、个数不同、顺序不同)。
    // 重写示例
    class Parent {
        public void test(int a) {} // 父类方法
    }
    class Child extends Parent {
        @Override
        public void test(int a) {} // 重写:签名与父类完全相同
    }
    
    // 重载示例
    class MyClass {
        public void test(int a) {} // 方法1
        public void test(String b) {} // 重载:参数类型不同
        public void test(int a, String b) {} // 重载:参数个数不同
    }
    
(3)返回值要求不同
  • 重写
    • 若父类方法返回基本类型,子类必须返回相同的基本类型
    • 若父类返回引用类型,子类可返回该类型的子类(协变返回类型)。
  • 重载:对返回值无要求(可以相同,也可以不同)。
(4)访问修饰符与异常的限制不同
  • 重写
    • 子类方法的访问权限不能比父类更严格(如父类是protected,子类可改为public,但不能改为private);
    • 子类方法不能抛出比父类更广泛的检查型异常(可抛出更少或更具体的异常)。
  • 重载:对访问修饰符和异常无限制(可任意修改)。
(5)与多态的关系不同
  • 重写:是实现运行时多态的核心(调用方法时,根据对象的实际类型执行对应子类的实现)。
  • 重载:是编译时多态(调用时,编译器根据参数类型匹配对应的方法)。

3. 总结表格

对比维度重写(Override)重载(Overload)
发生范围父子类之间同一个类中
方法签名完全相同(名+参数)名相同,参数列表不同
返回值基本类型必须相同;引用类型可协变无限制
访问修饰符不能更严格无限制
异常处理不能抛出更广泛的检查异常无限制
多态类型运行时多态编译时多态
注解推荐使用@Override验证无专用注解

通过以上对比可以看出:重写是“父子类间的方法覆盖”,核心是多态;重载是“同类内的方法复用”,核心是便捷性。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值