2012-08-15 38 views
0

我對C#.NET還是比較陌生,所以我確信有一些明顯的東西我錯過了,但是這裏是:我無法從某個特定的類中獲取某些變量。獲取繼承變量

有問題的類看起來是這樣的:

class AridPlanet : Arid 
    { 
     public const int area = 95; 

    } 

正如你可以看到這個類從下面的類繼承:

abstract class Arid : Astro 
    { 
     public const int metal = 2; 
     public const int gas = 2; 
     public const int crystals = 0; 
     public const int fertility = 5; 

    } 

這反過來又從下面的類繼承:

abstract class Astro 
    { 
     public int metal; 
     public int gas; 
     public int crystals; 
     public int fertility; 
     public int area; 

    } 

我試圖獲得以下變量:

class Base 
    { 
     private int metal; 
     private int gas; 
     private int crystals; 
     private int fertility; 
     private int area; 
     private List<Structure> structures = new List<Structure>(); 
     private int position; 
     private Astro selectedAstro; 

     public Base(Astro astro, int position) 
     { 
      this.selectedAstro = astro; 
      this.metal = selectedAstro.metal; 
      this.gas = selectedAstro.gas; 
      this.crystals = selectedAstro.crystals; 
      this.fertility = selectedAstro.fertility; 
      this.area = selectedAstro.area; 
      this.position = position; 

     //Code ommited 
    } 
    } 

astro參數被傳遞給Base構造爲特定天文類型,例如AridMoon

當我運行的代碼,看看有什麼Base變量被分配到我看到他們都分配爲0。對我來說,這表明該代碼試圖從AridPlanet最頂端的超分配變量,是Astro

但是,正如我理解繼承,編譯器應該看看前面指出的類,然後再轉到超類。

有什麼想法會出錯?我相信這很簡單,我誤解了。

+0

常量不是變量(或領域 - 這將是正確的術語)。 – Lucero 2012-08-15 01:15:05

+0

你可能想看看你的編譯器警告...... – 2012-08-15 01:19:28

+0

當然,它們不會改變,所以常量是有意義的,或者可能是'readonly'我不完全確定它們的區別。無論哪種情況,我都無法獲取值並分配它們。 – Arcadian 2012-08-15 01:19:59

回答

2

如果引用天文天文,你實際上將獲得在天文定義的常量。您必須將其轉換爲特定的子類以獲取在該子類中定義的常量。

您可能正在尋找的是虛擬屬性。

您可以定義

abstract class Base 
{ 
    abstract public int Metal { get; } 
} 

然後你就可以實現抽象方法在子類中

public class AridPlanet : Base 
{ 
    const int ARID_PLANET_METAL = 2; 
    public override int Metal { get { return ARID_PLANET_METAL; } } 
} 

我跳過了您的層次結構的中間水平,但希望它說明了這一點。中級類可以重寫抽象定義。他們的子類可以選擇提供額外的覆蓋或接受來自中間類的。

+0

金屬{get; }在Base中未被標記爲虛擬。 – Jagannath 2012-08-15 01:40:34

+1

@Jagannath抽象意味着虛擬。 – Lucero 2012-08-15 01:42:35

1

讓我用一個例子這裏來說明你做了什麼:

  • 創建一個類「汽車」,並定義一些性能車必須有
  • 創建一個類「跑車」,它擴展了「汽車「類,併爲屬性賦值
  • 使用」Car「類的一個實例爲什麼它不知道Sportscar。

它看起來好像你正在尋找使用多態性。使用接口或抽象類(如Eric所示)作爲基類來確定每個派生類必須具有哪些信息和功能。當你創建一個你的子類型的新實例時,你可以將它存儲爲你的接口的類型,並且對實例的所有調用都將被委派給子類。重要的部分是,你調用的是哪個構造函數。

1

我覺得這是你應該做的:

class AridPlanet : Arid 
{ 
    public AridPlanet() 
    { 
     area = 95; 
    } 
} 

abstract class Arid : Astro 
{ 
    public Arid() 
    { 
     metal = 2; 
     gas = 2; 
     crystals = 0; 
     fertility = 5; 
    } 

} 

然後天文類字段訪問修飾符更改爲保護,創造各自的只讀屬性公共訪問。

編輯:

abstract class Astro 
{ 
    protected int metal; 
    protected int gas; 
    protected int crystals; 
    protected int fertility; 
    protected int area; 

    public int Metal { get { return metal; } } 
    public int Gas { get { return gas; } } 
    public int Crystals { get { return crystals; } } 
    public int Fertility { get { return fertility; } } 
    public int Area { get { return area; } } 
} 

class BaseCalc 
{ 
    private int metal; 
    private int gas; 
    private int crystals; 
    private int fertility; 
    private int area; 
    //private List<Structure> structures = new List<Structure>(); 
    private int position; 
    private Astro selectedAstro; 

    public BaseCalc(Astro astro, int position) 
    { 
     this.selectedAstro = astro; 
     this.metal = selectedAstro.Metal; 
     this.gas = selectedAstro.Gas; 
     this.crystals = selectedAstro.Crystals; 
     this.fertility = selectedAstro.Fertility; 
     this.area = selectedAstro.Area; 
     this.position = position; 

     //Code ommited 
    } 
} 
+0

我不完全確定你的意思是「用公共訪問創建相應的只讀屬性」,因爲受保護的字段不能被「基類」類訪問。但除此之外,你的回答表明該程序首先看Astro,而不是我指出的子類。正如我上面所說,這不是我理解繼承的工作方式。 – Arcadian 2012-08-15 02:59:35

+0

我編輯了答案。如果你想了解繼承是如何工作的,那裏有很多例子。這裏是msdn的繼承解釋鏈接:http://msdn.microsoft.com/en-us/library/ms173149.aspx – mbm 2012-08-15 04:46:56