СДЕЛАЙТЕ СВОИ УРОКИ ЕЩЁ ЭФФЕКТИВНЕЕ, А ЖИЗНЬ СВОБОДНЕЕ

Благодаря готовым учебным материалам для работы в классе и дистанционно

Скидки до 50 % на комплекты
только до 09.06.2025

Готовые ключевые этапы урока всегда будут у вас под рукой

Организационный момент

Проверка знаний

Объяснение материала

Закрепление изученного

Итоги урока

Виртуальные свойства и методы в C#

Категория: Информатика

Нажмите, чтобы узнать подробности

Данный методический материал содержит презентацию к уроку "Виртуальные свойства и методы в С#". Материал предназначен для подготовки к занятиям по данной теме, а также  для студентов, изучающих язык С# в дисциплинах "Основы алгоритмизации и программирования" и "Прикладное программирование".

Просмотр содержимого документа
«Виртуальные свойства и методы в C#»

Виртуальные методы и свойства в С #

Виртуальные методы и свойства в С #

 При наследовании может возникнуть необходимость изменить в классе-наследнике функционал метода, который был унаследован от базового класса. В этом случае класс-наследник может переопределять методы и свойства базового класса.  Те методы и свойства, которые будут доступными для переопределения, в базовом классе помечаются модификатором  virtual . Такие методы и свойства называют виртуальными .  А чтобы переопределить метод в классе-наследнике, этот метод определяется с модификатором  override .  Переопределенный метод в классе-наследнике должен иметь тот же набор параметров, что и виртуальный метод в базовом классе.

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

Те методы и свойства, которые будут доступными для переопределения, в базовом классе помечаются модификатором  virtual . Такие методы и свойства называют виртуальными .

А чтобы переопределить метод в классе-наследнике, этот метод определяется с модификатором  override . Переопределенный метод в классе-наследнике должен иметь тот же набор параметров, что и виртуальный метод в базовом классе.

class Person {      public string FirstName { get; set; }      public string LastName { get; set; }      public Person(string firstName, string lastName)      {          FirstName = firstName;          LastName = lastName;      }      public virtual void Display()      {          Console.WriteLine($

class Person

{

     public string FirstName { get; set; }

     public string LastName { get; set; }

     public Person(string firstName, string lastName)

     {

         FirstName = firstName;

         LastName = lastName;

     }

     public virtual void Display()

     {

         Console.WriteLine($"{FirstName} {LastName}");

     }

}

class Employee : Person {      public string Company { get; set; }      public Employee(string firstName, string lastName, string company)          : base(firstName, lastName)      {          Company = company;      } }

class Employee : Person

{

     public string Company { get; set; }

     public Employee(string firstName, string lastName, string company)

         : base(firstName, lastName)

     {

         Company = company;

     }

}

 Здесь класс Person представляет человека. Класс Employee наследуется от Person и представляет сотруднника предприятия. Этот класс кроме унаследованных свойств имеет еще одно свойство - Company.  Чтобы сделать метод Display доступным для переопределения, этот метод определен с модификатором  virtual . Поэтому мы можем переопределить этот метод. Допустим, нас устраивает реализация метода из базового класса. В этом случае объекты Employee будут использовать реализацию метода Display из класса Person:

Здесь класс Person представляет человека. Класс Employee наследуется от Person и представляет сотруднника предприятия. Этот класс кроме унаследованных свойств имеет еще одно свойство - Company.

Чтобы сделать метод Display доступным для переопределения, этот метод определен с модификатором  virtual . Поэтому мы можем переопределить этот метод. Допустим, нас устраивает реализация метода из базового класса. В этом случае объекты Employee будут использовать реализацию метода Display из класса Person:

static void Main(string[] args) {      Person p1 = new Person(

static void Main(string[] args)

{

     Person p1 = new Person("Bill", "Gates");

     p1.Display(); // вызов метода Display из класса Person

     Employee p2 = new Employee("Tom", "Smith", "Microsoft");

     p2.Display(); // вызов метода Display из класса Person 

     Console.ReadKey();

}

Консольный вывод:

Bill Gates

Tom Smith работает в Microsoft

 Виртуальные методы базового класса определяют интерфейс всей иерархии, то есть в любом производном классе, который не является прямым наследником от базового класса, можно переопределить виртуальные методы. Например, мы можем определить класс Manager, который будет производным от Employee, и в нем также переопределить метод Display.  При переопределении виртуальных методов следует учитывать ряд ограничений:  Виртуальный и переопределенный методы должны иметь один и тот же модификатор доступа. То есть есть если виртуальный метод определен с помощью модификатора public, то и переопредленный метод также должен иметь модификатор public.  Нельзя переопределить или объявить виртуальным статический метод.

Виртуальные методы базового класса определяют интерфейс всей иерархии, то есть в любом производном классе, который не является прямым наследником от базового класса, можно переопределить виртуальные методы. Например, мы можем определить класс Manager, который будет производным от Employee, и в нем также переопределить метод Display.

При переопределении виртуальных методов следует учитывать ряд ограничений:

  • Виртуальный и переопределенный методы должны иметь один и тот же модификатор доступа. То есть есть если виртуальный метод определен с помощью модификатора public, то и переопредленный метод также должен иметь модификатор public.
  • Нельзя переопределить или объявить виртуальным статический метод.
Также как и методы, можно переопределять свойства : class Credit {      public virtual decimal Sum { get; set; } } class LongCredit : Credit {      private decimal sum;      public override decimal Sum      {          get          {              return sum;          }        

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

class Credit

{

     public virtual decimal Sum { get; set; }

}

class LongCredit : Credit

{

     private decimal sum;

     public override decimal Sum

     {

         get

         {

             return sum;

         }

       

1000)              {                  sum = value;              }          }      } } class Program {      static void Main(string[] args)      {          LongCredit credit = new LongCredit { Sum = 6000 }; " width="640"

  set

         {

             if(value 1000)

             {

                 sum = value;

             }

         }

     }

}

class Program

{

     static void Main(string[] args)

     {

         LongCredit credit = new LongCredit { Sum = 6000 };

         credit.Sum = 490;          Console.WriteLine(credit.Sum);          Console.ReadKey();      } }   Кроме конструкторов, мы можем обратиться с помощью ключевого слова  base  к другим членам базового класса. В нашем случае вызов base.Display(); будет обращением к методу Display() в классе Person:

         credit.Sum = 490;

         Console.WriteLine(credit.Sum);

         Console.ReadKey();

     }

}

Кроме конструкторов, мы можем обратиться с помощью ключевого слова  base  к другим членам базового класса. В нашем случае вызов base.Display(); будет обращением к методу Display() в классе Person:

class Employee : Person {      public string Company { get; set; }         public Employee(string lastName, string firstName, string company)              :base(firstName, lastName)      {          Company = company;      }         public override void Display()      {          base.Display();          Console.WriteLine($

class Employee : Person

{

     public string Company { get; set; }

  

     public Employee(string lastName, string firstName, string company)

             :base(firstName, lastName)

     {

         Company = company;

     }

  

     public override void Display()

     {

         base.Display();

         Console.WriteLine($" работает в {Company}");

     }

}

Запрет переопределения методов  Можно запретить переопределение методов и свойств. В этом случае их надо объявлять с модификатором  sealed : class Employee : Person {      public string Company { get; set; }      public Employee(string firstName, string lastName, string company)                  : base(firstName, lastName)      {          Company = company;      }      public override sealed void Display()      {          Console.WriteLine($

Запрет переопределения методов

Можно запретить переопределение методов и свойств. В этом случае их надо объявлять с модификатором  sealed :

class Employee : Person

{

     public string Company { get; set; }

     public Employee(string firstName, string lastName, string company)

                 : base(firstName, lastName)

     {

         Company = company;

     }

     public override sealed void Display()

     {

         Console.WriteLine($"{FirstName} {LastName} работает в {Company}");

     }

}

 При создании методов с модификатором sealed надо учитывать, что sealed применяется в паре с override , то есть только в переопределяемых методах.  И в этом случае мы не сможем переопределить метод Display в классе, унаследованном от Employee.

При создании методов с модификатором sealed надо учитывать, что sealed применяется в паре с override , то есть только в переопределяемых методах.

И в этом случае мы не сможем переопределить метод Display в классе, унаследованном от Employee.

Сокрытие  Ранее было рассмотрено определение и переопределение виртуальных методов. Другим способом изменить функциональность метода, унаследованного от базового класса, является  сокрытие .  Сокрытие представляет определение в классе-наследнике метода или свойства, которые соответствует по имени и набору параметров методу или свойству базового класса. Для сокрытия членов класса применяется ключевое слово  new .  Если в базовом классе метод не был объявлен виртуальным, в производном классе все равно можно объявить другой метод с такой же сигнатурой. Новый метод   скроет  метод базового класса.

Сокрытие

Ранее было рассмотрено определение и переопределение виртуальных методов. Другим способом изменить функциональность метода, унаследованного от базового класса, является  сокрытие .

Сокрытие представляет определение в классе-наследнике метода или свойства, которые соответствует по имени и набору параметров методу или свойству базового класса. Для сокрытия членов класса применяется ключевое слово  new .

Если в базовом классе метод не был объявлен виртуальным, в производном классе все равно можно объявить другой метод с такой же сигнатурой. Новый метод   скроет  метод базового класса.

 При этом компилятор, решая, какой метод вызвать, всегда будет рассматривать тип данных, на который указывает переменная, как тип данных заданный при ее объявлении.  Скрытие  (переопределение) элементов класса – это явное описание в классе-наследнике с новыми характеристиками уже существующих элементов из наследуемого класса.  public class MyClass  {  public int MyNumber;  }  public class OurClass : MyClass  {  public double MyNumber;  }   Переопределено поле MyNumber (в родительском классе имело целочисельный тип, а в производном – дробный). Поле целого типа скрыто новым описанием.

При этом компилятор, решая, какой метод вызвать, всегда будет рассматривать тип данных, на который указывает переменная, как тип данных заданный при ее объявлении.

Скрытие  (переопределение) элементов класса – это явное описание в классе-наследнике с новыми характеристиками уже существующих элементов из наследуемого класса.

public class MyClass

{

public int MyNumber;

}

public class OurClass : MyClass

{

public double MyNumber;

}

Переопределено поле MyNumber (в родительском классе имело целочисельный тип, а в производном – дробный). Поле целого типа скрыто новым описанием.

 Если бы поле MyNumber не было переопределено, то в классе OurClass (производный) по умолчанию было бы доступен только родительское поле MyNumber типа int. А выражение: oc.MyNumber = 5.5; вызывало ошибку типов.   Если метод скрывает метод или свойство базового класса, то к его определению необходимо добавить ключевое слово new .  Этот модификатор подскажет компилятору о факте сокрытия .

Если бы поле MyNumber не было переопределено, то в классе OurClass (производный) по умолчанию было бы доступен только родительское поле MyNumber типа int. А выражение: oc.MyNumber = 5.5; вызывало ошибку типов.

Если метод скрывает метод или свойство базового класса, то к его определению необходимо добавить ключевое слово new .

Этот модификатор подскажет компилятору о факте сокрытия .

public class Customer {  public string GetFunnyString()  {  return

public class Customer

{

public string GetFunnyString()

{

return "Cusomer funny!";

}

}

...

public class Nevermore60Customer : Customer

{

public new string GetFunnyString()

{

return "Nevermore60 funny!”;

}

}

...  Customer Cust1;  Nevermore60Customer Cust2; Cust1 = new Customer();  Console.WriteLine(Cust1.GetFunnyString());  Cust1 = new Nevermore60Customer();  Console.WriteLine(Cust1.GetFunnyString());  Cust2 = new Nevermore60Customer(); Console.WriteLine(Cust2.GetFunnyString()); ... }  Результат: Cusomer funny! Cusomer funny! Nevermore60 funny!

...

Customer Cust1;

Nevermore60Customer Cust2; Cust1 = new Customer();

Console.WriteLine(Cust1.GetFunnyString());

Cust1 = new Nevermore60Customer();

Console.WriteLine(Cust1.GetFunnyString());

Cust2 = new Nevermore60Customer(); Console.WriteLine(Cust2.GetFunnyString());

...

}

Результат:

Cusomer funny! Cusomer funny! Nevermore60 funny!


Скачать

Рекомендуем курсы ПК и ППК для учителей

Вебинар для учителей

Свидетельство об участии БЕСПЛАТНО!