2014-11-03 26 views
1

我已經繼承了一個只有一個子類的抽象父類,都在 單獨的文件中。在eclipse中摺疊父類和子類的java類

它們很大很醜。而且它們不再正確地結構化。 我要重構他們更好 - 但作爲這個的一部分,我想 首先想要將它們合併成一個類。即從事情是這樣的:

public abstract class ParentClass implements SomeInterface { 

    ParenClass(SomeOtherClass v) { 
    aMember = v; 
    } 

    @NonNull final SomeOtherClass aMember; 

    abstract void doSomething(); 

    // Several hundred lines of other functions and members. 
} 

public class ChildClass extends ParentClass { 

    ChildClass(AnotherClass v2) { 
     super(v2.getSomething()); 
     this.childMember = v2.somethingElse(); 
    } 

    @NonNull final SomeOtherClass aMember; 

    @Override void doSomething() { 
     //... 
    } 

    // Several hundred lines of other functions and members 
} 

兩個類的合併版本(實際上可以被命名爲像原來的班任 雖然...)

public class MergedParentAndChild implements SomeInterface { 

    JustOneClass(AnotherClass v2) { 
     this.aMember = v2.getSomething(); 
     this.childMember = v2.somethingElse(); 
    } 

    void doSomething() { 
     //... 
    } 
    // Lots of other functions etc. 
} 

我做這個在所有成員手動使用「拉起」重構,但它是費時的 它得到的構造函數錯誤,並與最終成員和抽象函數等問題等

也許eclipse可能有一個快速的方法,直接在i重構列表。我似乎無法找到它。

有沒有一種快速簡單的方法來做到這一點?

+0

什麼是你需要重構?對不起,我遲到了,我似乎無法想象XD – JClassic 2014-11-03 02:27:12

+0

我試圖用一個班級來替換一個不必要的兩個班級。分離到父類和子類是不適當的(或不再合適)並阻礙進一步的重構。我可以手工完成,或者對每個函數/字段逐個進行「拉起」重構,但不幸的是會有很多成員以及大量類似的問題。 – 2015-01-21 01:05:58

+0

是我的答案混淆? XD對不起,如果是 – JClassic 2015-01-21 21:53:24

回答

3

使用「拉」重構是不是重複/痛苦的,因爲我想最初以爲。我要借用JClassic的例子並對其進行一些修改(以使它更差更糟)並顯示會發生什麼

這是原始代碼。 。

public class Temp { 

    public static interface I1 { 
     public void interfaceFn1(); 
     public void interfaceFn2(); 
    } 

    public static abstract class A implements I1 { 
     int a; 
     public void foo(){ 
      System.out.printf("%s In A a=%d\n", this, a); 
     } 

     @Override public void interfaceFn1() { 
      System.out.println("In A.interfaceFn1"); 
     } 
    } 

    public static class AA extends A { 
     int aa; 

     @Override 
     public void foo(){ 
      super.foo(); 
      System.out.printf("%s In AA a=%d, aa=%d\n", this, a , aa); 
     } 

     @Override public void interfaceFn2() { 
      System.out.println("In A.interfaceFn1"); 
     } 
    } 
} 

如果然後把光標的AA的功能之一,並選擇「 」拉「 重構(Alt鍵 + + 牛逼ü) - 你得到如下的對話框。

Pull up dialog

然後點擊選擇右側,明年所有。

您會在看起來像這樣的對話框中看到有關重複函數的警告,這會導致編譯錯誤。您可以忽略這些,稍後再修復它們。

enter image description here

然後將要完成你的代碼看起來像這樣:

public class Temp { 

    public static interface I1 { 
     public void interfaceFn1(); 
     public void interfaceFn2(); 
    } 

    public static abstract class A implements I1 { 
     int a; 
     int aa; 
     public void foo(){ 
      System.out.printf("%s In A a=%d\n", this, a); 
     } 

     @Override public void interfaceFn1() { 
      System.out.println("In A.interfaceFn1"); 
     } 

     @Override public void foo() { 
      super.foo(); 
      System.out.printf("%s In AA a=%d, aa=%d\n", this, a , aa); 
     } 

     @Override public void interfaceFn2() { 
      System.out.println("In A.interfaceFn1"); 
     } 
    } 

    public static class AA extends A { 
    } 
} 

您現在可以卸下類AAA修復錯誤(的foo()重複是主要的問題) 。在代碼中導致這樣的:

public class Temp { 

    public static interface I1 { 
     public void interfaceFn1(); 
     public void interfaceFn2(); 
    } 

    public static abstract class A implements I1 { 
     int a; 
     int aa; 
     private void fooBase(){ 
      System.out.printf("%s In A.fooBase a=%d\n", this, a); 
     } 

     @Override public void interfaceFn1() { 
      System.out.println("In A.interfaceFn1"); 
     } 

     public void foo() { 
      fooBase(); 
      System.out.printf("%s In AA a=%d, aa=%d\n", this, a , aa); 
     } 

     @Override public void interfaceFn2() { 
      System.out.println("In A.interfaceFn1"); 
     } 
    } 
} 

最大剩下的問題是到AA所有創造/引用切換到A。但是,如果您選擇了use destination type where possible這將減少您需要修復的地方數量。

我懷疑仍然有構造函數會導致一些問題的情況,但在大多數情況下這似乎可以。

2

這是真的很難(如果不是不可能的)自動2個層次結構類的組合:考慮以下問題:你有兩個班

public static class A { 
    int a; 
    public void foo(){ 
     //do stuff 
    } 
} 

public static class AA extends A { 
    int aa; 

    @Override 
    public void foo(){ 
     //do stuff 
    } 
} 

當你將它們合併,你碰到的問題:

public static class AMerged{ 
    int a; 
    int aa; //this is fine 
    public void foo(){ //but use who's implementation? 
     //do what? 
    } 
} 

有了這個,你遇到了方法名稱相同的問題,同樣的變量是相同的,我將使用誰的實現?孩子還是父母?正如你所看到的,在合併你遇到的兩個類時會遇到很多問題,所以自動化幾乎是不可能的。

即使是抽象類是沒有辦法他們除了做結合手動