假设我有这些代码(并且这些类在同一名称空间中):
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()中放置这两行代码时,如果我使用正确的访问修饰符声明变量numberOfLegs,则可以/允许它。为什么我不能在班级本身中做到这一点?我应该怎么做才能允许它?
请注意,类Snake中的第二行代码无效,这些是它产生的错误: 1)错误1无效令牌' ='在类,结构或接口成员声明中 2)错误2' myNamespaceName.Snake.myAnimalObject'是一个'字段'但是像''类型'
感谢。我只是想了解这一点。
编辑: 好的,谢谢你们。我知道施工人员和继承人,但不知何故,我被迫做了这件事,而且他们很难做到并且不那么聪明。"方式,用于学习目的(?)。而且我甚至不得不将默认值设置为4.感谢您的回复。另外,我刚刚编写了这些课程。
答案 0 :(得分:3)
因为可执行代码应放在构造函数中或某些方法/属性中。 你不能将代码放在类中,把它放在构造函数中。
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;
}
}
答案 1 :(得分:1)
首先,您无法在类初始化程序中执行此操作:
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
类都定义了这些值需要的是什么
答案 2 :(得分:0)
您应该使用继承。使动物成为一个抽象类,所有动物的基类。在这种情况下,构图(你现在使用的)没有多大意义。
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)
是对基类构造函数的调用,因此您使用参数0调用Animal(int legs)
。
答案 3 :(得分: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)
{
}
}