我知道可以通过使用接口对方法进行此操作。但是接口不能具有字段或静态属性(这将无济于事,因为它将为实现该接口的所有类指定一个值)。我还可以为抽象类的属性设置默认值。但理想情况下,我想强制每个继承的类为这些属性实现值。然后,仍可以在抽象类级别的抽象方法中使用的值。
每种财产的好处:
-摘要;基类要求实现此属性,但不指定值。
- 静态的;每种类型的实现只存储一个值,而不是每个对象。
public interface IPiece
{
readonly int Points;
readonly char Letter;
}
public abstract class Piece
{
public static readonly int Points;
public static readonly char Letter;
}
public class King : Piece, IPiece
{
public int Points = 0;
public int Letter = 'K';
}
答案 0 :(得分:2)
解决此问题的标准模式是:
public interface IPiece
{
int Points { get; }
char Letter { get; }
}
public class King : IPiece
{
public int Points => 0;
public char Letter => 'K';
}
根本不需要使用static
,因为0
和K
是文字,因此(像static
)每个类仅有效地存储一次。
还请注意,我已经删除了您的abstract class
-它没有任何用处,因为其中没有逻辑。没有逻辑的abstract class
在概念上等同于interface
(您已经拥有),因此在此阶段是不必要的。
如果您确实要使用static
,则可以使用:
public class King : IPiece
{
private static int points = 0;
private static char letter = 'K';
public int Points => points;
public char Letter => letter;
}
但这并没有太大的好处。
答案 1 :(得分:1)
首先,接口可以具有属性,但不能具有字段(如问题注释中所述)。
public interface IPiece
{
int Points {get;} // readonly properties in interfaces must be defined like this
char Letter {get;}
}
您还需要让抽象类从接口继承,以使其能够访问其中定义的属性。因为它是一个抽象类,所以必须将属性标记为抽象
public abstract class Piece : IPiece
{
public abstract int Points {get;}
public abstract char Letter {get;}
}
从那里,您可以创建抽象类(Piece)的实现(King)。由于这不是抽象实现,因此您必须在此时提供属性的实现。
public class King : Piece
{
public override int Points {get; private set;} = 0;
public override char Letter {get; private set;} = 'K';
}
看看here,了解有关属性继承的更多示例。
答案 2 :(得分:1)
您不能具有静态的抽象属性。该类的静态成员没有多态性。如果您希望在抽象类中定义一个应由所有实现共享的属性,并且在编译时不知道,则可以为其创建Singleton类型,或包装(如果未在代码中定义类型)。然后您可以拥有类似这样的东西:
public abstract class Piece // or interface
{
public SingletonIntWrapper Points { get; }
public SingletonCharWrapper Letter { get; }
}
答案 3 :(得分:0)
您应该使用const
或static readonly
后备字段。 (有差异)。同样,抽象类和接口是多余的。要么让您的所有作品都衍生自Piece,要么让他们实现IPiece。
public interface IPiece
{
int Points { get; }
char Letter { get; }
}
public abstract class Piece : IPiece
{
public abstract int Points { get; }
public abstract char Letter { get; }
}
public class King : Piece
{
public const int POINTS = 0;
public const char LETTER = 'K';
public override int Points { get { return POINTS; } }
public override char Letter { get { return LETTER; } }
}
注意:
现在,您仍然无法以非常有用的方式使用公共const
或static readonly
。因为没有实例就无法达到值的定义。例如,在枚举所有值以确定要基于字符构造的Piece
时,您无法获得King.LETTER的值。