Как сделать абстрактные статические свойства - PullRequest
0 голосов
/ 05 декабря 2018

Я знаю, что это можно сделать для методов с помощью интерфейса.Но интерфейсы не могут иметь полей или статических свойств (что не помогло бы, поскольку указывало бы одно значение для всех классов, реализующих интерфейс).Я также мог бы иметь значения по умолчанию для свойств в абстрактном классе.Но в идеале я хотел бы заставить каждый наследующий класс реализовывать значения для этих свойств.Значения, которые затем могут использоваться в абстрактных методах на уровне абстрактного класса.

Преимущества каждого свойства:
- Abstract;Базовый класс требует, чтобы это свойство было реализовано, но не указывает значение.
- Static;хранить только одно значение для каждого типа реализации, а не для каждого объекта.

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';
}

Ответы [ 4 ]

0 голосов
/ 06 декабря 2018

Вам следует использовать минусовое поле 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 очень полезным способом.Потому что вы не можете получить определение значения без экземпляра.Например, вы не можете получить значение King.LETTER при перечислении всех значений, чтобы определить, что Piece построить на основе символа.

0 голосов
/ 05 декабря 2018

Во-первых, интерфейсы могут иметь свойства, но они не могут иметь полей (как указано в комментариях к вопросу).

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;}
}

Оттуда вы можете создать реализацию (King) вашего абстрактного класса (Piece).Поскольку это не абстрактная реализация, вы должны предоставить реализации свойств в это время.

public class King : Piece
{
    public override int Points {get; private set;} = 0;
    public override char Letter {get; private set;} = 'K';
}

Посмотрите здесь для дальнейших примеров наследования свойств.

0 голосов
/ 05 декабря 2018

Вы не можете иметь статическое абстрактное свойство.Статические члены класса не подвержены полиморфизму.Если вы хотите иметь свойство, определенное в абстрактном классе, которое должно использоваться всеми реализациями, и вы не знаете его во время компиляции , вы можете создать для него тип Singleton или обертка, если тип не определен в вашем коде.Тогда вы можете получить что-то вроде этого:

public abstract class Piece // or interface
{
    public SingletonIntWrapper Points { get; }
    public SingletonCharWrapper Letter { get; }
}
0 голосов
/ 05 декабря 2018

Стандартный шаблон для решения этой проблемы:

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;
}

, но в этом нет особой выгоды.

...