假设我有这些代码(并且这些类在同一个名称空间中):
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
,它需要是internal
或public
:
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)
{
}
}