36.md 5.7 KB
Newer Older
W
wizardforcel 已提交
1
# Java 方法覆盖
W
init  
wizardforcel 已提交
2 3 4

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

W
wizardforcel 已提交
5
从其**超类**继承该方法的类可以选择**覆盖**它。 覆盖的好处是可以定义特定于特定类的行为的能力。 对于具体的子类,如果在层次结构中没有其他超类实现抽象类中定义的所有方法,则将其强制实现。 覆盖有时称为*运行时绑定*。 这意味着将调用哪个覆盖方法将由引用类型而不是实例类型确定。
W
init  
wizardforcel 已提交
6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33

* * *

## 方法覆盖示例

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

* * *

## 方法替代规则

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

W
wizardforcel 已提交
42
## 从超类调用 Overridden 方法
W
init  
wizardforcel 已提交
43

W
wizardforcel 已提交
44
如果要在执行子类方法之前调用超类的覆盖方法,该怎么办。 您可以使用 SUPER 关键字。
W
init  
wizardforcel 已提交
45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100

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

W
wizardforcel 已提交
101
这里 super 关键字不能用于调用超类方法。 因为它没有被超类的方法覆盖。
W
init  
wizardforcel 已提交
102 103 104

## 备忘单

W
wizardforcel 已提交
105
*   *不能覆盖构造器*
W
init  
wizardforcel 已提交
106
*   覆盖方法必须具有相同的参数集。
W
wizardforcel 已提交
107
*   覆盖的方法必须具有相同的返回类型。 这些返回类型也可以是子类(***协变返回***)。
W
wizardforcel 已提交
108 109 110 111 112
*   覆盖的方法**无法**具有更严格的访问修饰符。
*   覆盖的方法**无法**抛出*新的或更广泛的*异常(***受检***)。 看下面的例子
*   覆盖的方法**可以引发**任何*非受检异常*
*   **最终**方法***无法覆盖***
*   ***私有方法***没有继承到子类,因此*不能*在子类中覆盖*
W
init  
wizardforcel 已提交
113
*   多态适用于覆盖。
W
wizardforcel 已提交
114
*   ***对象类型***确定将调用哪个覆盖方法,并由*运行时*确定。
W
init  
wizardforcel 已提交
115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212

### 方法覆盖异常示例

```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;
	}
}
```