[英]Overriding Methods constraints in java
在Java中重寫方法具有以下功能:
1> Overrinding方法應該與Parent類方法具有相同的參數列表。
2>返回類型應該是父類方法的返回類型的相同/子類。
3>訪問級別應與父類方法相同或更少限制。
4> overriden方法可以拋出相同或更窄的異常,而不是更廣泛的異常。
* 只是想知道為什么這么點*
* 2 - 為什么子類為什么不是超類呢? *
3 - 為什么訪問級別應該限制較少?
4 - 為什么它應該拋出狹窄的異常?
根據我的理解它只是如果我正在創建一個父類refrence創建一個子類對象並嘗試運行每個場景然后
讓我們假設A是父類 , B是子類,它們都有方法printAndReturnSomething()
public class A{
public B printAndReturnSomething(){
S.O.P("Inside A Print");
return new B();
}
}
現在我們將子類B作為
public class B extends A{
public A printAndReturnSomething(){ // I know this isn't possible to return A but had it been then
S.O.P("Inside A Print");
return new A();
}
}
現在,如果我做這樣的事情
A a =new B();
現在因為我有一個A的引用,所以我希望返回類型是B類型
B returnedValue=a.printAndReturnSomething(); // But it actually calls the child class method and hence returns A. So here comes the contradiction.
Similaraly為場景3和4.我的理解是否正確? 我錯過了其他更相關的東西嗎?
所有這些都可以通過說“子類必須表現得好像它是一個超類”來概括。 因此,如果Derived
擴展Base
並且我有一個Derived
類型的對象x
,那么我希望它的行為就像它是Base
類型一樣。
因此,如果x.foo()
返回某個類型T
,並且Base::foo()
返回一個類型S
,那么我希望能夠將x.foo()
視為S
,所以T
最好與或者相同S
子類。
類似地, x.foo()
應該只拋出Base:foo()
承諾的異常。 它無法開始拋出新的意外異常。
如果Base::foo()
是公共的,那么x.foo()
應如此。 你不能突然對派生類有更嚴格的限制,因為基類承諾我是公開的。
總是將繼承視為“表現得像超級類”,或“可以像超類一樣對待”,所有這一切都應該清楚。
根據我的理解,它只是如果我創建一個父類refrence創建一個子類對象並嘗試運行每個場景...
我認為你正確地理解了這個想法。
具有父類引用子類對象的情況是所謂的Liskov替換原則發揮作用的地方: 在計算機程序中,如果S是T的子類型,那么類型為T的對象 [即你的“父類”] 可以用類型的對象替換S [這是你的“子類對象”] (即,類型S的對象可以替代T類型的對象),而不改變該程序的任何所需屬性(正確性,執行的任務等)......
第2點
想象一下:
class Animal {}
class Dog extends Animal {}
class Base {
Dog get() { ... }
}
class Derived extends Base {
Animal get() { ... }
}
Base b = new Derived();
Dog d = b.get(); // What?
類似的邏輯可以應用於其他問題。
回答你的觀點:
2 - 為什么子類為什么不是超類?
如果允許超類,則可能發生這種情況:
class A {
public A makeCopy() { return clone(); }
}
class B extends A {
public Object makeCopy() { return new Date(); }
}
public static void main(String[] args) {
A a = new B();
A copy = a.makeCopy(); // OOPS -- didn't get an A after all!
}
3 - 為什么訪問級別應該限制較少?
將上述B類修改為:
class B extends A {
private A makeCopy() { return clone(); }
}
public static void main(String[] args) {
A a = new B();
A copy = a.makeCopy(); // OOPS -- accessing a private method!
}
4 - 為什么它應該拋出狹窄的異常?
同樣的想法 - 如果聲明A.makeCopy
拋出AException
(在A
聲明的假設異常類),但是聲明B.makeCopy
拋出Throwable
,那么B.makeCopy
可以拋出任何東西。 這將使得無法合理地編寫main
的try / catch塊。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.