获取继承的变量

时间:2012-08-15 01:11:34

标签: c# .net inheritance polymorphism

我仍然是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参数作为特定的astro类型传递给Base构造函数,例如AridMoon

当我运行代码以查看分配给Base变量的内容时,我发现它们都被分配给0.对我来说,这表明代码正在尝试从最顶层的超类中分配变量AridPlanet的{​​{1}}。Astro

但是,正如我理解继承一样,编译器应该先查看指定的类,然后再继续使用超类。

关于出了什么问题的任何想法?我确信这是一件很简单的事,我误解了。

3 个答案:

答案 0 :(得分:2)

如果您引用 Astro astro ,您实际上将获得 Astro 中定义的常量。您必须将其强制转换为特定的子类才能获得该子类中定义的常量。

您可能正在寻找的是虚拟属性。

您可以定义

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; } }
}

我跳过了你的层次结构的中间级别,但希望它说明了这一点。中间类可以覆盖抽象定义。它们的子类可以选择提供额外的覆盖或接受来自中间类的覆盖。

答案 1 :(得分:1)

让我在这里用一个例子来说明你的所作所为:

  • 创建一个“Car”类并定义汽车必须拥有的一些属性
  • 创建一个“Sportscar”类,扩展“Car”类并为属性赋值
  • 使用“Car”类的实例,这是一个奇迹,为什么它不知道Sportscar。

看起来好像在寻找使用多态性。使用接口或抽象类(如Eric所示)作为基类,确定每个派生类必须具有的信息和功能。创建子类型的新实例时,可以将其存储为接口类型,并将对实例的所有调用委派给子类。重要的是,你调用哪个构造函数。

答案 2 :(得分:1)

我认为这是你应该做的:

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

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

}

然后将 Astro 类字段访问修饰符更改为受保护,并使用公开访问权限创建相应的只读属性

修改

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
    }
}