我有一些抽象的超類和一些實現的方法。子類中的隱藏方法
是否有可能隱藏在子類從這個超類繼承自該超類的方法?我不想在某些子類中的超類中看到某些方法。最後但並非最不重要的是,是否可以更改超類中具有相同名稱的子類中某個方法的參數個數?
假設我們在超類中有一個方法public void test(int a, int b)
,但現在我想要調用超類功能的子類中的方法public void test(int a)
,並且超類中的方法不再可見。
我有一些抽象的超類和一些實現的方法。子類中的隱藏方法
是否有可能隱藏在子類從這個超類繼承自該超類的方法?我不想在某些子類中的超類中看到某些方法。最後但並非最不重要的是,是否可以更改超類中具有相同名稱的子類中某個方法的參數個數?
假設我們在超類中有一個方法public void test(int a, int b)
,但現在我想要調用超類功能的子類中的方法public void test(int a)
,並且超類中的方法不再可見。
是否有可能在從這個超類繼承的子類中隱藏這個超類的方法?
如果您的方法在超類私有的,它不會在子類中可見(或任何其他人)。
如果您需要在基類中的方法,但是是公開的,不存在由例如與私有實現覆蓋它掩藏它在子類中的方法。 (您不能「降低可見性」,即從例如公共或受保護到子類中的私有。)
最好的解決方法是重寫該方法並拋出運行時異常,如UnsupportedOperationException
。
是有可能改變的參數的個數爲具有超類中相同名稱的子類的方法?
不,您不能更改簽名。您可以創建另一個具有相同名稱和不同數量參數的方法,但這將是一個不同的(重載)方法,並且基類中的方法仍然可見。
解決方法是在超類中創建方法'protected',然後有兩個實現。一個只是讓方法'公開'(即授予訪問父API),而另一個創建調用父API的新方法。第二種類型隱藏了父API(但子類仍然可以看到它們)。 – 2014-10-07 13:11:11
第二個問題的答案是正確的,但我認爲它的措辭是誤導性的。通過更改參數的數量和類型來重載方法名稱是完全可以的。此外,重載的方法名稱的訪問限定符沒有限制(只要簽名不匹配另一個繼承的方法)。但是,超類方法仍然可見。 – 2014-10-07 13:14:08
這不是*改變*參數的數量,即*添加*另一個方法與不同數量的參數。 – aioobe 2014-10-07 13:19:02
你不能完全隱藏從超類的方法,它總是可以調用,例如,
MyBase o = new MyClass();
o.test(1, 2);
但是,你可以在一個特定的方式覆蓋的方法:
class MySuper {
public void test(int a, int b) {; }
}
class MyClass extends MySuper {
@Deprecated
@Override
public void test(int a, int b) {
throw new UnsupportedOperationException("Do not call this method, call test(int a) instead!");
}
public void test(int a) { ; }
}
Java不支持能見度降低。
有一種方法可以做這樣的事情,但它是複雜的:
Delegate
,該類型實現方法public void test(int a, int b)
test(a,b)
到Delegate
,另一個創建一個新方法test(a)
,最終使用一個Delegate
實例。所以實現舊代碼的類型永遠不會被外部世界看到(它可能是一個包私有類)。
當然,那麼新類型的對象將不再是基類的實例。 – 2014-10-07 13:33:50
這就是爲什麼新類型實現相同的接口。正如我所說,這不是很好,很清楚,等等。 – 2014-10-07 13:35:30
對不起 - 我在評論中不清楚。原始基類具有某些方法,而新類型沒有,因此在客戶端代碼被編寫爲使用基類的這些方法的情況下,它們不可用。您提出了一個與OP似乎面臨的問題不同的好架構。 – 2014-10-07 13:38:54
不,您不能在子項中隱藏公共方法,例如將方法隱藏在那裏。
原因是有一個子類的實例,你可能總是把它轉換到基類,並在那裏調用方法。
所以這種行爲是合乎邏輯的。要麼重新設計類層次結構,要麼創建一個新類,如果這成爲一個太醜陋的API。
但是你可以覆蓋的方法和
/**
* Use <code>test(a)</code> instead.
* @param a.
* @param b.
*/
@Deprecated
@Override
public void test(int a, int b) {
throw new UnsupportedOperationException("Use test(int) instead.");
}
public void test(int a) { // Overloaded method
int b = ...;
super.test(a, b);
}
重載的方法是可行的:同一個名字,不同的參數類型。
我是否設法回答您的問題?還是有些不清楚? – aioobe 2014-10-13 15:02:59