1. 程式人生 > >JAVA方法的重寫與過載的原則

JAVA方法的重寫與過載的原則

重寫的原則

請看這道題:

QUESTION NO: 10
Click the Exhibit button.
Which statement is true about theclasses and interfaces in the exhibit?



A. Compilation willsucceed for all classes and interfaces.
B. Compilation of classC will fail because of an error in line 2.
C. Compilation of classC will fail because of an error in line 6.
D. Compilation of classAImpl will fail because of an error in line 2.

這道題就是涉及到繼承時候方法的重寫問題,重寫要遵循以下原則:

1.重寫方法必須和被重寫方法有相同的方法名稱、引數列表、返回值型別;(注:返回值可以為父類中返回值的子型別.引數若為子類,則不是重寫是過載)

2.重寫方法不能使用比被重寫方法更嚴格的訪問許可權;

3.重寫方法不能宣告丟擲比被重寫方法範圍更大的異常型別。

這裡C的第二行,返回型別是AImpl ,它是A的子類,是允許的,但是第六行Object顯示不是String 或String的子類,因此會報錯。

Answer: C

關於第二點,實際上如果子類寫一個訪問更寬鬆的方法,實際上相當於另寫了一個方法,並不會報錯,但是如果用父類refer 的子類例項呼叫此方法可能會出錯的。

關於第三點,實測如果子類不拋異常,也沒有報錯。

例如:

class Foo{
	public int a = 3;
	private void addFive(){
		a +=5;
		System.out.print("f ");
	}
}
public class Bar extends Foo{
	public int a = 8;
	public void addFive(){
		this.a +=5;
		System.out.print("b ");
	}
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Foo f = new Bar();
		f.addFive();//不合法!
		System.out.print(f.a);
	}
}

屬性的重寫

看以下程式碼輸出什麼?
class Foo{
	public int a = 3;
	public void addFive(){
		a +=5;
		System.out.print("f ");
	}
}
public class Bar extends Foo{
	public int a = 8;
	public void addFive(){
		this.a +=5;
		System.out.print("b ");
	}
	public static void main(String[] args) {
		Foo f = new Bar();
		f.addFive();
		System.out.print(f.a);
	}
}
實際上在記憶體中重寫的方法被覆蓋了,所以先輸出b  f.a輸出的結果實際上是3,也就是說子類的屬性a並沒有覆蓋父類的a. 在記憶體中屬性並不會覆蓋,當呼叫的時候要看例項的控制代碼是父類還是它本身,這裡Foo f = new Bar();因此呼叫f.a時候實際上輸出的時候Foo的a屬性。


過載的原則

看下面題,更復雜

QUESTION NO: 17
Given:
1. public class Blip {
2. protected int blipvert(int x) {return 0; }
3. }
4. class Vert extends Blip {
5. // insert code here
6. }
Which five methods, insertedindependently at line 5, will compile? (Choose five.)
A. public int blipvert(int x) {return 0; }
B. private int blipvert(int x) {return 0; }
C. private int blipvert(long x) {return 0; }
D. protected long blipvert(int x) {return 0; }
E. protected int blipvert(long x) {return 0; }
F. protected long blipvert(long x) {return 0; }
G. protected long blipvert(int x,int y) { return 0; }

上面有重寫的原則了,這裡考察的更多,綜合考察重寫與過載,過載的原則如下:

1.方法名必須相同。 
2.方法的引數型別和引數個數兩者至少有一不同。 (引數為子類也算不同。 int 和Integer也算不同,都算過載)
3.方法的修飾符和返回值型別可以不同。 

我們來分析答案:

A. public int blipvert(int x) {return 0; }   符合重寫原則,許可權更鬆

B. private int blipvert(int x) {return 0; } 屬於重寫,但許可權更嚴格,因此×

C. private int blipvert(long x) {return 0; } 符合過載原則

D. protected long blipvert(int x) {return 0; } 返回型別變化,不屬於重寫。不符合過載原則 ×

E. protected int blipvert(long x) {return 0; } 引數變化,過載

F. protected long blipvert(long x) {return 0; } 引數變化,過載

G. protected long blipvert(int x,int y) { return 0; } 符合過載原則


因此答案是

Answer: A,C,E,F,G