2015-03-25 84 views
1

讓我們說,我有一個抽象類A.在那裏,我得到了一些內部類喜歡這裏:抽象類的構造函數的繼承對象

public abstract class A 
{ 
     public InnerOne x; 
     public InnerTwo y; 
     public A(){ 
      this.x = new InnerOne(); 
      this.y = new InnerTwo(); 
     } 
     public class InnerOne 
     { 
      public virtual double value(){ 
       return 0; 
      } 
     } 
     public class InnerTwo 
     { 
      public virtual double value(){ 
       return 0; 
      } 
     } 
} 

然後我得到了它的兒童像這樣的:

public class B: A 
    { 
      public B():base(){ 

      } 
      public class InnerOne: A.InnerOne 
      { 
       public override virtual double value(){ 
        return 100; 
       } 
      } 
      public class InnerTwo: A.InnerTwo 
      { 
       public override virtual double value(){ 
        return 100; 
       } 
      } 
    } 

所以我認爲當我打電話B這樣的構造函數時,我會通過創建它的內部類實例來初始化xy。但實際上並不是這樣的。當我打電話給vaule函數時,它返回零。

A newobject = new B(); 
var bv1 = B.x.value(); 
var bv2 = B.y.value(); 

有沒有辦法迫使B類來初始化它的xy領域由它的內部類對象(不與父抽象類對象),而無需重新編寫它的構造?

+0

爲什麼你不希望修改乙構造? – 2015-03-25 11:34:59

+0

有沒有理由不能或不想簡單地在'B'的構造函數中賦值它們? – juharr 2015-03-25 11:35:01

+0

@MichałKomorowski和juharr如果裏面有太多的課程怎麼辦? – DanilGholtsman 2015-03-25 11:37:34

回答

1

即使你已經定義了A或B中的類,他們仍然是大衆,他們在外面A或B.它的訪問從A或B之外definied一類沒什麼兩樣

想象中的一樣代碼定義在A類和B類之外的InnerOneInnerTwo。它將具有上述相同的行爲。你的困惑根源在於誤解了內部類的用法。

爲了得到100,在B裏面,你需要用一個覆蓋這些值的實例顯式替換X和Y變量的實例。除非你做這些,你不會得到100

public class B: A 
    { 
      public B():base(){ 
      X = new OverridenInnerOne(); 
      Y = new OverridenInnerTwo(); 
      } 
      public class OverridenInnerOne: A.InnerOne 
      { 
       public override virtual double value(){ 
        return 100; 
       } 
      } 
      public class OverridenInnerTwo: A.InnerTwo 
      { 
       public override virtual double value(){ 
        return 100; 
       } 
      } 
    } 
1

的「內部類」方面(嵌入式類定義)只在這裏分心,沒有發揮任何作用。

並回答這個問題:不,你不能有'虛擬構造函數'這樣工作。

當然有很多方法可以獲得100而不是0作爲返回值,但是這個問題太過於人爲地提出了一個問題。

+0

哦,多數民衆贊成在悲傷:c – DanilGholtsman 2015-03-25 14:56:18

+0

抽象類中有太多的內部類,每個都有'價值'功能。 我創建的內部類實例只是爲了從內部類中獲取值函數,這就是爲什麼我想在構造函數中少用一些:c – DanilGholtsman 2015-03-25 14:58:07

+0

再次:備份並詢問實際問題。也許有人可以幫忙,但不是這樣。 – 2015-03-25 18:25:45

1

B.xB.yA.InnerOneA.InnerTwo實例,所以你看到的返回值0,因爲這些都無關B.InnerOneB.InnerTwo

以下B構造函數分配xy,其將返回100

public B(){ 
    this.x = new InnerOne(); 
    this.y = new InnerTwo(); 
} 

如果你想在A你期望的方式工作的B.InnerOneB.InnerTwo情況下,你需要通過您需要從B構造函數中創建內部類型,並在A構造函數中創建它們的實例,如下所示:

public B():base(typeof(InnerOne),typeof(InnerTwo)) { ... } 

使用Activator.CreateInstance可讓您在A的構造函數中創建這些類型。

如果您始終希望A以這種方式使用,Enigmativity的通用解決方案會更好,或者,這種方式允許您爲A擁有多個構造函數,以便您可以選擇傳遞不同的類型。

1

你可以做到這一點,但你必須改變類A的定義 - 它會變得超級毛茸茸。

這裏的A

public abstract class A<I1, I2> 
    where I1 : A<I1, I2>.InnerOne, new() 
    where I2 : A<I1, I2>.InnerTwo, new() 
{ 
    public InnerOne x; 
    public InnerTwo y; 
    public A() 
    { 
     this.x = new I1(); 
     this.y = new I2(); 
    } 
    public class InnerOne 
    { 
     public virtual double value() 
     { 
      return 0; 
     } 
    } 
    public class InnerTwo 
    { 
     public virtual double value() 
     { 
      return 0; 
     } 
    } 
} 

而這裏的B

public class B: A<B.InnerOne, B.InnerTwo> 
{ 
    public B():base(){ } 
    public class InnerOne: A<InnerOne, InnerTwo>.InnerOne 
    { 
     public override double value() 
     { 
      return 100; 
     } 
    } 
    public class InnerTwo: A<InnerOne, InnerTwo>.InnerTwo 
    { 
     public override double value() 
     { 
      return 100; 
     } 
    } 
} 
+0

哦,有趣的方式 – DanilGholtsman 2015-03-25 11:41:11

+0

這是一個「橋樑模式」的OOP形式。 – Enigmativity 2015-03-25 11:48:40

+2

用Google搜索了一下:) http://en.wikipedia.org/wiki/Bridge_pattern – 2015-03-25 12:06:21