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 类型astro传递给Base构造函数,例如AridMoon.

当我运行代码查看Base变量被分配给什么时,我看到它们都被分配给 0。对我来说,这表明代码正在尝试从最顶层的超类中分配AridPlanet变量Astro

但是,据我了解继承,编译器应该先查看指定的类,然后再转到超类。

对出了什么问题有任何想法吗?我确定这是我误解的简单事情。

4

3 回答 3

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

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

于 2012-08-15T01:16:41.873 回答
1

让我在这里用一个例子来说明你做了什么:

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

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

于 2012-08-15T01:37:23.943 回答
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
    }
}
于 2012-08-15T02:47:06.000 回答