# Java 方法覆盖

> 原文： [https://javabeginnerstutorial.com/core-java-tutorial/java-overriding/](https://javabeginnerstutorial.com/core-java-tutorial/java-overriding/)

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

* * *

## 方法覆盖示例

```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`关键字。

```java
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");
	}
}
```

输出量

```java
In Super Class
In Sub Class
```

### 静态方法不能被覆盖

静态方法不能被覆盖。 看起来好像它已被覆盖，但事实并非如此。 静态方法可以隐藏。

```java
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`关键字不能用于调用超类方法。 因为它没有被超类的方法覆盖。

## 备忘单

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

### 方法覆盖异常示例

```java
package com.example.simple;

public class Overridding_Class extends base_class {

    @Override
    void method() throws exception_3 {  // NO PROBLEM, It is not a broader Exception.
    }

    void method1() throws exception_1 {   // It will give COMPILATION ERROR as it is throwing Broader Exception
    }
}

class base_class {
    void method() throws exception_2 {
    }

    void method1() throws exception_2 {
    }
}

class excepion_1 extends Exception {
}

class exception_2 extends excepion_1 {
}

class exception_3 extends exception_2 {
} 
```

方法覆盖示例

```java
package com.override;

public class MethodOverrideRule {

	public static void main(String args[])
	{
		// Here reference type and Object type is same
		MethodOverrideRule scls = new MethodOverrideRule();
		OverrideSubclass subcls = new OverrideSubclass();

		// Here reference type is of Super class and Object is of child class
		MethodOverrideRule subOcls = new OverrideSubclass();

		// This will invoke method from Super class
		scls.method();
		// This will onvoke method form sub class
		subcls.method();

		/*
		 * Here overriding will work. Even reference type is of Super class still object type if of Subclass.
		 * Hence Subclass version of method will get invoked.
		 */
		subOcls.method();

		/*
		 * Which overridden method is to be executed depends on the actual Object type at run time.
		 */
	}

	void method(){
		System.out.println("Overriding method without argument in Super");
	}

	int method(String str)
	{
		System.out.println("Overriding method with int argument in Super");
		return 9;
	}
}

class OverrideSubclass extends MethodOverrideRule{

	/*
	 * Here we are overriding the method from super class.
	 * @Override annotation is used to confirm the same. It makes sure the all override rules get followed 
	 * 
	 */
	@Override
	void method(){
		System.out.println("Overriding method without argument in subclass");
	}

	@Override
	int method(String str)
	{
		System.out.println("Overriding method with int argument in subclass");
		return 10;
	}
}
```

