поздравления. у меня есть следующий класс:
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 имеет дело только с одной поставкой. но массив отражает направления, в которые может быть помещена поставка.
По моему опыту, каждый раз, когда я хотел удалить свойство из класса в унаследованном классе, мой дизайн класса был ошибочным. Один из способов решить эту проблему - создать новый базовый класс без свойства ShipUnit, а затем наследовать этот базовый класс два раза, один раз для вашего конкретного типа Ship и один раз для вашего конкретного типа ShipPlacementArray. В обоих подклассах вы можете реализовать ShipUnit по мере необходимости.
что я хотел бы знать, так это как мне удалить определенную функциональность базового класса?
Никак. Смысл наследования не в этом. Смысл наследования в том, чтобы наследовать функциональность базового класса - всю ее - и добавлять/изменять вещи. Это нужно для отношений "есть-есть", например, "автомобиль есть транспортное средство."
Мой вопрос в том, как мне реализовать код, который полностью скрывает базовый класс shipUnit?
Похоже, вы хотите, чтобы ShipPlacementArray
был оберткой, или контейнером, для нескольких Ship
объектов. Это не похоже на случай, когда следует использовать наследование.
Задайте себе вопрос: "является ли ShipPlacementArray
разновидностью Ship
?"
С помощью модификатора new в C# вы можете скрыть наследуемый член от члена базового класса. Посмотрите эту страницу для справки.
можно использовать оператор "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. Таким образом, можно "скрыть" член, но нельзя отключить его функциональность или доступность.
В дополнение к другим отличным ответам, в стороне я бы сказал, что инкапсуляция может быть лучшим вариантом. Часто я сначала думал, что хочу унаследовать от класса, а позже обнаружил, что действительно хочу инкапсулировать его. Вы делаете это, просто объявляя новый экземпляр исходного класса в частном поле. Затем вы создаете общедоступные свойства и функцию, которые просто вызывают исходный класс, как показано ниже, что дает вам точный контроль над тем, что раскрывается. Это также способ обойти недостатки наследования, такие как дополнительная сложность и невозможность выполнения множественного наследования (по уважительной причине):
class SomeNew
{
private SomeOld someOld = new SomeOld();//could have done this in constructor instead
public DoSomething()
{
someOld.DoSomething();
}
}
Я не знаю, это просто надуманный пример или реальная проблема. Но я бы сказал, что наследование в данном случае нежелательно. У вас есть Ship и ShipPlacementArray. «Массив» в конце делает его более похожим на тип данных массива. Итак, убрав это, у вас есть ShipPlacement.
Мне кажется, это место где-то, так что, может быть, оно должно быть членом класса Корабль?
«Предпочитайте композицию объектов над наследованием классов» - если вы ищут новое поведение от базового класса, тогда не похоже, что вы все равно захотите наследовать, потому что это разные типы. Возможно, Ship и ShipPlacementArray должны наследовать общий интерфейс, но, конечно, не от общий базовый класс. Везде, где вам нужно будет использовать любой из них, вы можете использовать интерфейс, но там, где вам нужна матрица ShipUnit, вы должны явно использовать тип ShipPlacementArray.
вы можете используйте оператор «новый». как в
public new ShipUnit[][] shipUnit { get; set; } // in the derived class
Вы можете использовать ключевое слово новое
, например:
public new ShipUnit[][] shipUnit { get; set; }
Я не совсем понимаю, что вы хотите смоделировать с помощью наследования, но я совершенно уверен, что это неправильный инструмент. Я предполагаю, что агрегация или композиция - это то, что вам нужно.
вы можете использовать ключевое слово new или добавить virtual в объявление базового класса и переопределить это в производном классе.