如何制作抽象静态属性
How to make abstract static properties
我知道这可以通过使用接口为方法完成。但是接口不能有字段或静态属性(这无济于事,因为它会为实现该接口的所有 classes 指定一个值)。我还可以在摘要 class 处为属性设置默认值。但理想情况下,我想强制每个继承 class 实现这些属性的值。然后仍然可以在抽象 class 级别的抽象方法中使用的值。
每个属性的好处:
- 抽象的;基础 class 要求实现此 属性 但未指定值。
- 静止的;每种实现类型只存储一个值,而不是每个对象。
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';
}
解决这个问题的标准模式是:
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
)每次只有效存储一次class.
另请注意,我已删除您的 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;
}
但这并没有什么大的好处。
首先,接口可以有属性,但不能有字段(如问题评论中所示)。
public interface IPiece
{
int Points {get;} // readonly properties in interfaces must be defined like this
char Letter {get;}
}
您还需要让您的抽象 class 从接口继承,以便它可以访问其中定义的属性。因为它是一个抽象class,所以必须将属性标记为抽象
public abstract class Piece : IPiece
{
public abstract int Points {get;}
public abstract char Letter {get;}
}
从那里,您可以创建抽象 class(Piece)的实现(King)。由于这不是抽象实现,此时您必须提供属性的实现。
public class King : Piece
{
public override int Points {get; private set;} = 0;
public override char Letter {get; private set;} = 'K';
}
查看 here 以获取有关 属性 继承的更多示例。
您不能有静态摘要属性。 class 的静态成员不受多态性影响。如果你希望在抽象 class 中定义一个 属性 ,它应该被所有实现共享并且你 在编译时不知道它 ,你可以为它创建一个 Singleton 类型,如果它没有在您的代码中定义类型,则创建一个包装器。然后你可以有这样的东西:
public abstract class Piece // or interface
{
public SingletonIntWrapper Points { get; }
public SingletonCharWrapper Letter { get; }
}
您应该使用 const
或 static readonly
后场。 (有差异)。抽象 class 和接口也是多余的。要么让你所有的 pieces 派生自 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; } }
}
注意:
现在你仍然不能以非常有用的方式使用 public const
或 static readonly
。因为没有实例就无法达到值的定义。例如,在枚举所有值以确定根据字符构造什么 Piece
时,您无法获得 King.LETTER 的值。
我知道这可以通过使用接口为方法完成。但是接口不能有字段或静态属性(这无济于事,因为它会为实现该接口的所有 classes 指定一个值)。我还可以在摘要 class 处为属性设置默认值。但理想情况下,我想强制每个继承 class 实现这些属性的值。然后仍然可以在抽象 class 级别的抽象方法中使用的值。
每个属性的好处:
- 抽象的;基础 class 要求实现此 属性 但未指定值。
- 静止的;每种实现类型只存储一个值,而不是每个对象。
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';
}
解决这个问题的标准模式是:
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
)每次只有效存储一次class.
另请注意,我已删除您的 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;
}
但这并没有什么大的好处。
首先,接口可以有属性,但不能有字段(如问题评论中所示)。
public interface IPiece
{
int Points {get;} // readonly properties in interfaces must be defined like this
char Letter {get;}
}
您还需要让您的抽象 class 从接口继承,以便它可以访问其中定义的属性。因为它是一个抽象class,所以必须将属性标记为抽象
public abstract class Piece : IPiece
{
public abstract int Points {get;}
public abstract char Letter {get;}
}
从那里,您可以创建抽象 class(Piece)的实现(King)。由于这不是抽象实现,此时您必须提供属性的实现。
public class King : Piece
{
public override int Points {get; private set;} = 0;
public override char Letter {get; private set;} = 'K';
}
查看 here 以获取有关 属性 继承的更多示例。
您不能有静态摘要属性。 class 的静态成员不受多态性影响。如果你希望在抽象 class 中定义一个 属性 ,它应该被所有实现共享并且你 在编译时不知道它 ,你可以为它创建一个 Singleton 类型,如果它没有在您的代码中定义类型,则创建一个包装器。然后你可以有这样的东西:
public abstract class Piece // or interface
{
public SingletonIntWrapper Points { get; }
public SingletonCharWrapper Letter { get; }
}
您应该使用 const
或 static readonly
后场。 (有差异)。抽象 class 和接口也是多余的。要么让你所有的 pieces 派生自 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; } }
}
注意:
现在你仍然不能以非常有用的方式使用 public const
或 static readonly
。因为没有实例就无法达到值的定义。例如,在枚举所有值以确定根据字符构造什么 Piece
时,您无法获得 King.LETTER 的值。