Java重载与方法覆盖

22 阅读5分钟

开启掘金成长之旅!这是我参加「掘金日新计划·12月更文挑战」的第二十天,点击查看活动详情

Java重载

重载方法为您提供了一个选项,可以在类中使用与相同的方法名称,但具有不同的参数。

Java方法规则中的重载

有一些与重载方法相关的规则。

重载方法

  • 必须更改参数列表
  • 可以更改返回类型
  • 可以更改访问修饰符(更广泛)
  • 可以声明一个新的或更广泛的受检异常

方法可以在类或子类中重载。

重载方法示例

//Overloaded method with one argument
    public void add(int input1,int input2){
        System.out.println("In method with two argument");
    }
        //Overloaded method with one argument
    public void add(int input1){
        System.out.println("In method with one argument");
    }    

调用重载方法

在几种可用的重载方法中,调用的方法基于参数。

    add(3,4);
        add(5);

第一个调用将执行第一个方法,第二个调用将执行第二个方法。

引用类型而不是对象决定调用哪个重载方法,和覆盖方法相反。

方法重载备忘单

  • 使用相同的方法名称但使用不同的参数称为重载
  • 构造器也可以重载
  • 重载的方法必须设置不同的参数
  • 重载的方法可能具有不同的返回类型
  • 重载的方法可能具有不同的访问修饰符
  • 重载的方法可能抛出不同的异常,更宽或更窄的没有限制
  • 超类中的方法也可以在子类中重载
  • 多态适用于覆盖和重载
  • 基于引用类型,确定在编译时间上确定将调用哪个重载方法

方法重载示例

package com.overloading;
/*
* Here we will learn how to overload a method in the same class.
* Note: Which overloaded method is to invoke is depends on the argument passed to method.
*/
public class MethodOverloading {

    public static void main(String args[])
    {
        //Creating object of the class MethodOverloading

        MethodOverloading cls = new MethodOverloading();
        System.out.println("calling overloaded version with String parameter");
        cls.method("Hello");
        System.out.println("calling overloaded version with Int parameter");
        cls.method(3);

        /*
        * Here same method name has been used, But with different argument.
        * Which method is to invoke is decided at the compile time only
        */
    }

    /*
    * Overloaded version of the method taking string parameter
    * name of the method are same only argument are different.
    */
    void method(String str)
    {
        System.out.println("Value of the String is :"+str);
    }

    /*
    * Overloaded version taking Integer parameter
    */
    void method(int i)
    {
        System.out.println("Value of the Int is :"+i);
    }
}

Java方法覆盖

从其超类继承该方法的类可以选择覆盖它。 覆盖的好处是可以定义特定于特定类的行为的能力。 对于具体的子类,如果在层次结构中没有其他超类实现抽象类中定义的所有方法,则将其强制实现。 覆盖有时称为运行时绑定。 这意味着将调用哪个覆盖方法将由引用类型而不是实例类型确定。

方法覆盖示例

public class ParentClass
{
public void show()
{
System.out.println("Show method of Super class");
}
}

public class SubClass extends ParentClass
{
//below method is overriding the ParentClass version of show method
public void show()
{
System.out.println("Show method of Sub class");
}
}

方法覆盖规则

  • 覆盖方法不能具有比被覆盖的方法更多的限制性访问修饰符,但可以更少。
  • 参数列表必须与覆盖的方法完全匹配,如果不匹配,则很可能是您正在重载该方法。
  • 返回类型必须与在超类中的覆盖方法中声明的返回类型相同或为该子类型的子类型。
  • 覆盖方法可以抛出任何非受检异常(运行时) ,但是它可以抛出比被覆盖方法声明的范围更广或更新的受检异常,但不能抛出更少或狭窄的异常检查。
  • 不能覆盖最终的方法
  • 静态方法无法覆盖。 静态方法看起来可以覆盖,但它是隐藏的。
  • 如果方法无法继承,则无法覆盖

从超类调用被覆盖方法

如果要在执行子类方法之前调用超类的覆盖方法,该怎么办。 您可以使用SUPER关键字。

public class SubClass extends superclass{
    void method(){
        super.method();
        System.out.println("In Sub Class");
    }
    
    public static void main(String[] args){
        SubClass obj = new SubClass();
        obj.method();
    }
}

class superclass{
    void method(){
        System.out.println("In Super Class");
    }
}    

输出量

In Super Class
In Sub Class
``
## 静态方法不能被覆盖
静态方法不能被覆盖。 看起来好像它已被覆盖,但事实并非如此。 静态方法可以隐藏。

```js
public class SubClass extends superclass {

    static void method() {
        // super.method(); // Super keyword will not work here. As it is not overriden method
        System.out.println("In Sub Class");
    }

    @SuppressWarnings("static-access") // The static method method() from the type SubClass should be accessed in a static way
    public static void main(String[] args) {
        SubClass obj = new SubClass();
        obj.method();
            SubClass.method();// It is same as above. Same method will be invoked
    }
}

class superclass {
    static void method() {
        System.out.println("In Super Class");
    }
}

这里super关键字不能用于调用超类方法。 因为它没有被超类的方法覆盖。

备忘单

  • 不能覆盖构造器
  • 覆盖方法必须具有相同的参数集。
  • 覆盖的方法必须具有相同的返回类型。 这些返回类型也可以是子类(协变返回)。
  • 覆盖的方法无法具有更严格的访问修饰符。
  • 覆盖的方法无法抛出新的或更广泛的异常(受检)。 看下面的示例
  • 覆盖的方法可以引发任何非受检异常
  • 最终方法无法覆盖
  • 私有方法没有继承到子类,因此不能在子类中覆盖*。
  • 多态适用于覆盖。
  • 对象类型确定将调用哪个覆盖方法,并由运行时确定。