1. 程式人生 > >java多個子類自動呼叫父類不包含的函式

java多個子類自動呼叫父類不包含的函式

問題描述

在用javafx做畢設的時候需要對形狀新增上下文選單。為了程式碼的封裝性,我選擇了新定義一個MyContextMenu繼承ContextMenu。在解決在Shape這種非Controller新增ContexMenu的問題後發現,雖然我能將之前的形狀物件傳過來,但是我只能用兩個形狀的公共父類也就是作為我自己的類的初始化引數。在我的程式碼中的實際情況就是:我的自定義原型MyCircle和自定義MyEllipse是分別繼承Circle和Ellipse的,而他們的公共父類是Shape,這裡我的ContextMenu裡面選用的引數為Shape的父介面Node。
這樣就有一個問題,就是我無法將Node強制轉換為MyCircle或者MyEllipse,所以也就無法呼叫他們雖然都有的方法。比如Shape裡沒有delete方法,我在各自的類裡邊都是寫了delete方法的。

簡化問題

其實仔細一想,把這個問題抽象化,就能夠更好得看清這個問題的本質。
有一個X父類,A、B繼承X,這是已有的無法修改的類。然後現在我要寫一個MA, MB,分別繼承A和B。可以畫圖為
類關係圖
然後我們需要在另外的類裡面呼叫X,A,B中沒有的,MA和MB內卻有的方法。

解決方法一

第一時間就能想到的解決方案,就是檢查傳過來的引數是否是MA,是否是MB等等等。。。。這個很簡單,但是,事實上我有許多的形狀,這個方法就顯得有些笨,就得寫一堆其實一模一樣的沒什麼用的程式碼,通篇的instanceof。而且,雖然不是一個優秀的程式設計師,但是,總得有優秀的夢想,這種程式碼,看著都讓人難受想想也是下下策。於是思考其他的方法。

解決方法二

其實因為想到了方法一,想到了instanceof,就突然想到直接新建一個介面Y。MA,MB實現介面Y。然後在外部呼叫時instanceof Y, 然後將引數X強制轉換成Y,呼叫Y.delete()。突然發現問題就這麼神奇的解決。驚歎自己前面是那麼得蠢。
程式碼示例:(這裡只寫一個呼叫處的程式碼)

public class C {
    public C(X x) {
        if (x instanceof Y) {
            ((Y)x).delete();
        }
    }
}

總結

解決問題後,往前看,發現這其實是一個很簡單的java介面的應用,但是一開始並沒有能夠想到,自己思考以後覺得可能還是沒有能夠把問題給抽象出來,所以一時間沒有能夠聯想到這個方法。吃一塹,長一智,畢設已經快接近尾聲了,希望畢業以後能夠儘量避免這種低階的問題吧。