Наследование классов C#

поздравления. у меня есть следующий класс:

public class Ship
{
    public enum ValidShips
    {
        Minesweeper,
        Cruiser,
        Destroyer,
        Submarine,
        AircraftCarrier
    }

    public enum ShipOrientation
    {
        North,
        East,
        South,
        West
    }

    public enum ShipStatus
    {
        Floating,
        Destroyed
    }

    public ValidShips shipType { get; set; }

    public ShipUnit[] shipUnit { get; set; }

    public ShipOrientation shipOrientation { get; set; }

    public ShipStatus shipStatus { get; set; }

    public Ship(ValidShips ShipType, int unitLength)
    {
        shipStatus = ShipStatus.Floating;

        shipType = ShipType;

        shipUnit = new ShipUnit[unitLength];

        for (int i = 0; i < unitLength; i++)
        {
            shipUnit[i] = new ShipUnit();
        }
    }
}

я хотел бы наследовать этот класс как так:

public class ShipPlacementArray : Ship
{

}

это имеет смысл.

то, что я хотел бы знать, - то, как я удаляю определенную функциональность базового класса?

например:

    public ShipUnit[] shipUnit { get; set; } // from base class

я хотел бы, чтобы это было:

    public ShipUnit[][] shipUnit { get; set; } // in the derived class

мой вопрос состоит в том, как я реализую код, который скрывает базовый класс shipUnit полностью?

иначе я закончу с двумя shipUnit реализациями в производном классе.

спасибо в течение Вашего времени.

ShipPlacementArray имеет дело только с одной поставкой. но массив отражает направления, в которые может быть помещена поставка.

7
задан iTEgg 22 February 2010 в 14:47
поделиться

11 ответов

По моему опыту, каждый раз, когда я хотел удалить свойство из класса в унаследованном классе, мой дизайн класса был ошибочным. Один из способов решить эту проблему - создать новый базовый класс без свойства ShipUnit, а затем наследовать этот базовый класс два раза, один раз для вашего конкретного типа Ship и один раз для вашего конкретного типа ShipPlacementArray. В обоих подклассах вы можете реализовать ShipUnit по мере необходимости.

7
ответ дан 6 December 2019 в 06:14
поделиться

что я хотел бы знать, так это как мне удалить определенную функциональность базового класса?

Никак. Смысл наследования не в этом. Смысл наследования в том, чтобы наследовать функциональность базового класса - всю ее - и добавлять/изменять вещи. Это нужно для отношений "есть-есть", например, "автомобиль есть транспортное средство."

Мой вопрос в том, как мне реализовать код, который полностью скрывает базовый класс shipUnit?

Похоже, вы хотите, чтобы ShipPlacementArray был оберткой, или контейнером, для нескольких Ship объектов. Это не похоже на случай, когда следует использовать наследование.

Задайте себе вопрос: "является ли ShipPlacementArray разновидностью Ship?"

15
ответ дан 6 December 2019 в 06:14
поделиться

С помощью модификатора new в C# вы можете скрыть наследуемый член от члена базового класса. Посмотрите эту страницу для справки.

2
ответ дан 6 December 2019 в 06:14
поделиться

можно использовать оператор "new". как и в

public new ShipUnit[][] shipUnit { get; set; } // in the derived class
-121--3777333-

Пример JavaScript фактически не является перенаправлением . Нет средств ответа 301/302 . Это просто запрос, который происходит во время определенного события Javascript после того, как страница прибыла. Если сделать это во время загрузки страницы, то это будет иметь больше накладных расходов, чем реальное перенаправление, и это не будет работать на JS-отключенных браузерах.

Перенаправления инициируются со стороны сервера с 301/302 ответом. По умолчанию для всех языков/фреймворков webapp установлено значение 302. Обычно его можно сделать 301, добавив один дополнительный параметр или строку кода, указывающую на это. Преимущество 301 заключается в том, что конкретный запрос не будет индексироваться (больше) поисковыми ботами.

-121--2165399-

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

Так, например, вы можете сделать в вашем производном классе:

public new ShipUnit[][] shipUnit { get; set; }

Но тогда я могу сделать:

((Ship)ShipPlacementArray_instance).shipUnit

И это будет ссылка на исходный shipUnit. Таким образом, можно "скрыть" член, но нельзя отключить его функциональность или доступность.

2
ответ дан 6 December 2019 в 06:14
поделиться

В дополнение к другим отличным ответам, в стороне я бы сказал, что инкапсуляция может быть лучшим вариантом. Часто я сначала думал, что хочу унаследовать от класса, а позже обнаружил, что действительно хочу инкапсулировать его. Вы делаете это, просто объявляя новый экземпляр исходного класса в частном поле. Затем вы создаете общедоступные свойства и функцию, которые просто вызывают исходный класс, как показано ниже, что дает вам точный контроль над тем, что раскрывается. Это также способ обойти недостатки наследования, такие как дополнительная сложность и невозможность выполнения множественного наследования (по уважительной причине):

class SomeNew
{
  private SomeOld someOld = new SomeOld();//could have done this in constructor instead

  public DoSomething()
  {
    someOld.DoSomething();
  }
}
1
ответ дан 6 December 2019 в 06:14
поделиться

Я не знаю, это просто надуманный пример или реальная проблема. Но я бы сказал, что наследование в данном случае нежелательно. У вас есть Ship и ShipPlacementArray. «Массив» в конце делает его более похожим на тип данных массива. Итак, убрав это, у вас есть ShipPlacement.

Мне кажется, это место где-то, так что, может быть, оно должно быть членом класса Корабль?

1
ответ дан 6 December 2019 в 06:14
поделиться

«Предпочитайте композицию объектов над наследованием классов» - если вы ищут новое поведение от базового класса, тогда не похоже, что вы все равно захотите наследовать, потому что это разные типы. Возможно, Ship и ShipPlacementArray должны наследовать общий интерфейс, но, конечно, не от общий базовый класс. Везде, где вам нужно будет использовать любой из них, вы можете использовать интерфейс, но там, где вам нужна матрица ShipUnit, вы должны явно использовать тип ShipPlacementArray.

1
ответ дан 6 December 2019 в 06:14
поделиться

вы можете используйте оператор «новый». как в

public new ShipUnit[][] shipUnit { get; set; } // in the derived class
0
ответ дан 6 December 2019 в 06:14
поделиться

Вы можете использовать ключевое слово новое , например:

public new ShipUnit[][] shipUnit { get; set; }
0
ответ дан 6 December 2019 в 06:14
поделиться

Я не совсем понимаю, что вы хотите смоделировать с помощью наследования, но я совершенно уверен, что это неправильный инструмент. Я предполагаю, что агрегация или композиция - это то, что вам нужно.

0
ответ дан 6 December 2019 в 06:14
поделиться

вы можете использовать ключевое слово new или добавить virtual в объявление базового класса и переопределить это в производном классе.

0
ответ дан 6 December 2019 в 06:14
поделиться
Другие вопросы по тегам:

Похожие вопросы: