Язык программирования C#9 и платформа .NET5 - Троелсен Эндрю - Страница 137
- Предыдущая
- 137/642
- Следующая
Добавьте к операторам верхнего уровня показанный ниже код, с помощью которого можно подтвердить то, что вам уже известно: позиционные типы записей работают точно так же, как типы записей.
PositionalCar pc = new PositionalCar("Honda", "Pilot", "Blue");PositionalMiniVan pm = new PositionalMiniVan("Honda", "Pilot", "Blue", 10);Console.WriteLine($"Checking PositionalMiniVan is-a PositionalCar: {pm is PositionalCar}");Эквивалентность с унаследованными типами записей
Вспомните из главы 5, что для определения эквивалентности типы записей используют семантику значений. Еще одна деталь относительно типов записей связана с тем, что тип записи является частью соображения, касающегося эквивалентности. Скажем, взгляните на следующие тривиальные примеры:
public record MotorCycle(string Make, string Model);public record Scooter(string Make, string Model) : MotorCycle(Make,Model);Игнорируя тот факт, что унаследованные классы обычно расширяют базовые классы, в приведенных простых примерах определяются два разных типа записей, которые имеют те же самые свойства. В случае создания экземпляров с одинаковыми значениями для свойств они не пройдут проверку на предмет эквивалентности из-за того, что принадлежат разным типам. В качестве примера рассмотрим показанный далее код и результаты его выполнения:
MotorCycle mc = new MotorCycle("Harley","Lowrider");Scooter sc = new Scooter("Harley", "Lowrider");Console.WriteLine($"MotorCycle and Scooter are equal: {Equals(mc,sc)}");Вот вывод:
Record type inheritance!MotorCycle and Scooter are equal: FalseРеализация модели включения/делегации
Вам уже известно, что повторное использование кода встречается в двух видах. Только что было продемонстрировано классическое отношение "является". Перед тем, как мы начнем исследование третьего принципа ООП (полиморфизма), давайте взглянем на отношение "имеет" (также известное как модель включения/делегации или агрегация). Возвратитесь к проекту
EmployeesBenefitPackage.csnamespace Employees{ // Этот новый тип будет функционировать как включаемый класс. class BenefitPackage { // Предположим, что есть другие члены, представляющие // медицинские/стоматологические программы и т.п. public double ComputePayDeduction() { return 125.0; } }}Очевидно, что было бы довольно странно устанавливать отношение "является" между классом
BenefitPackageEmployee// Теперь сотрудники имеют льготы.partial class Employee{ // Contain a BenefitPackage object. protected BenefitPackage EmpBenefits = new BenefitPackage();...}На данной стадии вы имеете объект, который благополучно содержит в себе другой объект. Тем не менее, открытие доступа к функциональности содержащегося объекта внешнему миру требует делегации. Делегация — просто действие по добавлению во включающий класс открытых членов, которые работают с функциональностью содержащегося внутри объекта.
Например, вы могли бы изменить класс
EmployeeEmpBenefitsGetBenefitCost()partial class Employee{ // Содержит объект BenefitPackage. protected BenefitPackage EmpBenefits = new BenefitPackage(); // Открывает доступ к некоторому поведению, связанному со льготами. public double GetBenefitCost() => EmpBenefits.ComputePayDeduction(); // Открывает доступ к объекту через специальное свойство. public BenefitPackage Benefits { get { return EmpBenefits; } set { EmpBenefits = value; } }}В показанном ниже обновленном коде верхнего уровня обратите внимание на взаимодействие с внутренним типом
BenefitsPackageEmployeeConsole.WriteLine("***** The Employee Class Hierarchy *****\n");...Manager chucky = new Manager("Chucky", 50, 92, 100000, "333-23-2322", 9000);- Предыдущая
- 137/642
- Следующая
