我正在使用具有類層級的Java庫:Java:如何在不修改類文件的情況下添加到基類
例如,類C1和C2都可以擴展B類
有沒有一種方法可以讓我向B類添加功能(屬性,方法),以便它可以在沒有修改3個文件的情況下爲子類C1 & C2提供?
如果不是,那麼重寫所有3個班級的做法是否正確?
我正在使用具有類層級的Java庫:Java:如何在不修改類文件的情況下添加到基類
例如,類C1和C2都可以擴展B類
有沒有一種方法可以讓我向B類添加功能(屬性,方法),以便它可以在沒有修改3個文件的情況下爲子類C1 & C2提供?
如果不是,那麼重寫所有3個班級的做法是否正確?
假設你不能夠修改B中的一些原因,使得擴展它爲您的中介類:
public class ClassC extends ClassB {
//additional functionality
}
然後很簡單:
public class Class1 extends ClassC {...}
如果你可以修改乙,其他類已經繼承了這些方法,您不必擔心重寫它們,除非您標記方法abstract
通過這種方式,您可以修改類「C1」和「C2」,而不僅僅是修改一個類「B」。 – SudoRahul
對。我不想這樣做。 – GroovyDotCom
@GroovyDotCom你不想做哪個部分,爲什麼? – Rogue
有沒有辦法讓我向B類添加功能(屬性,方法),以便在不修改3個文件的情況下,它可用於子類C1 & C2?
您將只需修改類B
。如果添加方法,它們將自動被類別C1
和C2
繼承,因此您不需要修改這些類。
您只需要修改B類。如果向B添加受保護或公共方法,則C1和C2將自動能夠調用它,而無需進行任何更改。
只需修改B類。無需更改其他文件。
似乎這個問題有點模糊,很難說不知道你的意圖。
如果你想增強你的類在運行時的行爲,那麼你可以看看像Javassit或CGLib等,它允許你改變類並添加新的功能,而無需修改源代碼原始來源。
如果你正在開發一些東西,並試圖找到一個允許你在不改變現有類的源代碼的情況下添加功能的設計,那麼你可以看看Dectorator模式。
如果您手頭只有三個類,並且您不想/不允許修改它們,但您仍然希望添加功能而不更新它們。那麼在Java中是不可能的,對不起。 (許多其他語言無論如何都提供這樣的功能)
無論如何你必須修改類B
。可以有兩種方法(假設你可以修改B
)。
第一:讓你想在B
直接做更改,因爲C1
和C2
延長B
已經,方法和字段將在那些階級作爲階級(僅當它們public or protected
,這是)可用。但這需要在B
中進行大量更改。
第二個:有一個抽象類擴展了B
。在這種情況下,對B
的小改動應該足以擴展該抽象類。這樣,您添加到抽象類的所有內容都可以在層次結構中的以下所有類中使用。只要確保在抽象類中沒有任何抽象方法。
public abstract class ParentOfB {
// Additional functionality
}
public class B extends ParentOfB { // The only change in B
}
之所以ParentOfB
是抽象的,是因爲你不想使用這些功能的任何其他類沒有繼承B
。如果你需要其他地方的功能,你可以使ParentOfB
只是一個普通的課程。
如果您不能修改B
那麼你將不得不把它擴大,並修改C1
和C2
,而不是延長B
新類。
如果您不能修改任何這些類的,那麼你可以做這樣的事情:
BX
延伸B
C1X
延伸BX
,幷包含一個內C1
對象。除了委託在BX
新方法,所有的方法調用底層C1
對象C2X
遵循同樣的邏輯C1X
這是不漂亮。可能無法正常工作。例如,如果新方法需要處理底層對象的私有數據,那麼這將不起作用。但考慮到這些限制,我認爲沒有其他辦法。如果Java有多重繼承,它可以工作C1X
擴展C1
和BX
,但缺點,恐怕這個骯髒的解決方案是最好的,你可以擁有。 (如果它甚至有效)。
這可以工作,但並不像你說的那樣漂亮。我只是有一個想法,也許這可以做得更乾淨C1X擴展C1和實現增加的功能作爲接口委託給通用代碼的接口。想想我會先試試這個。 – GroovyDotCom
@GroovyDotCom它怎麼樣了? – janos
根據你的發佈我的回答。沒有投票,所以我不確定是否有人同意。 – GroovyDotCom
這是我想出的答案。這是Janos寫的一個變體,但我認爲它更好。我不需要更改任何類,可以重新使用任何子類中的擴展,並繼續從新的擴展子類繼承。儘管如此,仍然需要委託方法。
因此,例如: 注意以下D1已經是如何從B1,C1和B_EXTRA_IMPL
public class B1 {
public void b1() {
System.out.println("B1");
}
}
public class C1 extends B1 {
public void c1() {
System.out.println("C1");
}
}
-------------------------- Adding New B1 Functionality to C1 ---------------------
public interface B_EXTRA {
void b_extra();
}
public class B_EXTRA_IMPL implements B_EXTRA {
public B1 m_b1;
B_EXTRA_IMPL(B1 base) {
m_b1 = base;
}
@Override
public void b_extra() {
System.out.println("b_extra");
}
}
public class C1X extends C1 implements B_EXTRA {
B_EXTRA_IMPL b_extra;
C1X() {
super();
b_extra = new B_EXTRA_IMPL((B1)this);
}
public void b1()
{
System.out.println("B1");
}
@Override
public void b_extra() {
b_extra.b_extra();
}
}
public class D1 extends C1X {
}
public class Main {
public static void main(String[] args) {
D1 d = new D1();
d.b1();
d.c1();
d.b_extra();
}
}
繼承你必須至少是修改B中。 –