2014-10-07 87 views
1

我有一些抽象的超類和一些實現的方法。子類中的隱藏方法

是否有可能隱藏在子類從這個超類繼承自該超類的方法?我不想在某些子類中的超類中看到某些方法。最後但並非最不重要的是,是否可以更改超類中具有相同名稱的子類中某個方法的參數個數?

假設我們在超類中有一個方法public void test(int a, int b),但現在我想要調用超類功能的子類中的方法public void test(int a),並且超類中的方法不再可見。

+0

我是否設法回答您的問題?還是有些不清楚? – aioobe 2014-10-13 15:02:59

回答

4

是否有可能在從這個超類繼承的子類中隱藏這個超類的方法?

如果您的方法在超類私有的,它不會在子類中可見(或任何其他人)。

如果您需要在基類中的方法,但是是公開的,不存在由例如與私有實現覆蓋它掩藏它在子類中的方法。 (您不能「降低可見性」,即從例如公共或受保護到子類中的私有。)

最好的解決方法是重寫該方法並拋出運行時異常,如UnsupportedOperationException

是有可能改變的參數的個數爲具有超類中相同名稱的子類的方法?

不,您不能更改簽名。您可以創建另一個具有相同名稱和不同數量參數的方法,但這將是一個不同的(重載)方法,並且基類中的方法仍然可見。

+0

解決方法是在超類中創建方法'protected',然後有兩個實現。一個只是讓方法'公開'(即授予訪問父API),而另一個創建調用父API的新方法。第二種類型隱藏了父API(但子類仍然可以看到它們)。 – 2014-10-07 13:11:11

+1

第二個問題的答案是正確的,但我認爲它的措辭是誤導性的。通過更改參數的數量和類型來重載方法名稱是完全可以的。此外,重載的方法名稱的訪問限定符沒有限制(只要簽名不匹配另一個繼承的方法)。但是,超類方法仍然可見。 – 2014-10-07 13:14:08

+0

這不是*改變*參數的數量,即*添加*另一個方法與不同數量的參數。 – aioobe 2014-10-07 13:19:02

1

你不能完全隱藏從超類的方法,它總是可以調用,例如,

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) { ; } 
} 
0

Java不支持能見度降低。

有一種方法可以做這樣的事情,但它是複雜的:

  1. 您需要創建父類型的接口。這個接口不需要有方法。
  2. 您可以創建另一個新類型Delegate,該類型實現方法public void test(int a, int b)
  3. 您可以刪除當前父類型。
  4. 您創建兩個實現該接口的新類型。一個代理test(a,b)Delegate,另一個創建一個新方法test(a),最終使用一個Delegate實例。

所以實現舊代碼的類型永遠不會被外部世界看到(它可能是一個包私有類)。

+0

當然,那麼新類型的對象將不再是基類的實例。 – 2014-10-07 13:33:50

+0

這就是爲什麼新類型實現相同的接口。正如我所說,這不是很好,很清楚,等等。 – 2014-10-07 13:35:30

+0

對不起 - 我在評論中不清楚。原始基類具有某些方法,而新類型沒有,因此在客戶端代碼被編寫爲使用基類的這些方法的情況下,它們不可用。您提出了一個與OP似乎面臨的問題不同的好架構。 – 2014-10-07 13:38:54

1

不,您不能在子項中隱藏公共方法,例如將方法隱藏在那裏。

原因是有一個子類的實例,你可能總是把它轉換到基類,並在那裏調用方法。

所以這種行爲是合乎邏輯的。要麼重新設計類層次結構,要麼創建一個新類,如果這成爲一個太醜陋的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); 
} 

重載的方法是可行的:同一個名字,不同的參數類型。