更改实例变量的默认值



假设我有这些代码(并且这些类在同一个名称空间中):

 class Animal
 {
    int numberOfLegs = 4; // initialized
    public int returnNumberOfLegs()
    {
      return numberOfLegs;
    }
 }
class Snake
{
   internal Animal myAnimalObject = new Animal();
   myAnimalObject.numberOfLegs = 0; // why is this line not allowed? 
}
class Program
{
   public static void Main(string [] args)
   {
      Snake mySnakeObject = new Snake();
      Console.WriteLine("Snake");
      Console.WriteLine("Number of Legs: {0}", mySnakeObject.myAnimalObject.returnNumberOfLegs());
   }
}

观察Snake类。当我在Main()中放置这2行代码时,如果我使用正确的访问修饰符声明变量numberOfLegs,这是可能的/允许的,并且可以工作。为什么我不能在Snake类本身中这样做?我该怎么做才能允许它?

注意,类Snake的第二行代码是无效的,下面是它产生的错误:错误1类、结构或接口成员声明中无效的令牌'='2)错误2 'myNamespaceName.Snake。myAnimalObject'是一个'字段',但像'type'一样使用

谢谢。我只是想了解一下这个。

编辑:好的,谢谢大家。我知道构造函数和继承,但不知何故,出于学习目的,我被迫以"困难且不那么聪明"的方式来做。我甚至需要设置默认值为4。谢谢你的回复。再说,这些课是我自己编的。

因为可执行代码应该放在构造函数或某些方法/属性中。不能将代码放在类中,而应放在构造函数中。

    class Snake
    {
        internal Animal myAnimalObject = new Animal();
        public Snake()
        {
              myAnimalObject.numberOfLegs = 0;
        }
    }

    internal Animal myAnimalObject = new Animal();
类体中的

是一种语法糖;编译器将创建构造函数并将代码行放入其中。它看起来像

    class Snake
    {
        internal Animal myAnimalObject;
        public Snake()
        {
              myAnimalObject = new Animal();
              myAnimalObject.numberOfLegs = 0;
        }
    }

首先,你不能在类初始化器中这样做:

myAnimalObject.numberOfLegs = 0;

由于不是设置类成员本身,而是与类成员交互,因此必须在构造函数中进行设置:

public Snake()
{
    myAnimalObject.numberOfLegs = 0;
}

同样,为了访问numberOfLegs,它需要是internalpublic:

internal int numberOfLegs = 4; // initialized
然而,对于整个场景来说,这似乎是一个非常奇怪的抽象。虽然我的一部分人赞成使用组合而不是继承,但这似乎更像是继承得到保证的情况。看起来Animal在默认情况下真的不应该初始化numberOfLegs的任何值。事实上,Animal甚至不应该是一个具体的对象,因为现实世界的概念被建模。相反,我可能会尝试这样做:
abstract class Animal
{
    public abstract int NumberOfLegs { get; }
}
class Snake : Animal
{
    public override int NumberOfLegs { get { return 0; } }
}

这个想法是,Snake Animal, Animal本身不能存在,除非它是Animal的特定类型Animal的每个单独类型内部控制自己的值,所有抽象Animal类所做的就是定义这些值需要是什么。

您应该使用继承。使Animal成为一个抽象类,所有动物的基类。在这种情况下,组合(你现在使用的)没有多大意义。

abstract class Animal
{
    protected int numberOfLegs = 4; // default number of legs
    public int NumberOfLegs { get { return numberOfLegs; } }
    public Animal(int legs)
    {
        numberOfLegs = legs; // initialize number of legs
    }
}

所有具体的动物都是从这个类派生出来的。

class Snake : Animal
{   
   public Snake() : base(0) // specify that number of legs is 0
   {
   }
}

base(0)是对基类构造函数的调用,所以你调用Animal(int legs)的参数是0。

这样做:

abstract class Animal
{
    private readonly int numberOfLegs; 
    protected Animal(int nrLegs = 4)
    {
       numberOfLegs = nrLegs;
    }
    public int returnNumberOfLegs()
    {
      return numberOfLegs;
    }
}
class Snake : Animal
{
   public Snake() : base(0)
   {
   }
}

相关内容

  • 没有找到相关文章

最新更新