...

Полиморфизм c что это за программа

C # – Полиморфизм

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

Полиморфизм может быть статическим или динамическим. В статическом полиморфизме ответ на функцию определяется во время компиляции. В динамическом полиморфизме он решается во время выполнения.

Статический полиморфизм

Механизм связывания функции с объектом во время компиляции называется ранним связыванием. Он также называется статической привязкой. C # предоставляет два метода для реализации статического полиморфизма. Они –

  • Перегрузка функций
  • Перегрузка оператора

Мы обсудим перегрузку оператора в следующей главе.

Перегрузка функции

Вы можете иметь несколько определений для одного и того же имени функции в той же области. Определение функции должно отличаться друг от друга по типам и / или количеству аргументов в списке аргументов. Вы не можете перегружать объявления функций, которые отличаются только возвращаемым типом.

В следующем примере показано использование функции print () для печати различных типов данных:

using System; namespace PolymorphismApplication < class Printdata < void print(int i) < Console.WriteLine("Printing int: ", i ); > void print(double f) < Console.WriteLine("Printing float: " , f); > void print(string s) < Console.WriteLine("Printing string: ", s); > static void Main(string[] args) < Printdata p = new Printdata(); // Call print to print integer p.print(5); // Call print to print float p.print(500.263); // Call print to print string p.print("Hello C++"); Console.ReadKey(); >> >

Когда приведенный выше код компилируется и выполняется, он производит следующий результат:

Printing int: 5 Printing float: 500.263 Printing string: Hello C++

Динамический полиморфизм

C # позволяет создавать абстрактные классы, которые используются для обеспечения частичной реализации класса интерфейса. Реализация завершается, когда производный класс наследуется от него. Абстрактные классы содержат абстрактные методы, которые реализуются производным классом. Производные классы имеют более специализированную функциональность.

Вот правила об абстрактных классах:

  • Вы не можете создать экземпляр абстрактного класса
  • Вы не можете объявить абстрактный метод вне абстрактного класса
  • Когда класс объявляется запечатанным , его нельзя унаследовать, абстрактные классы не могут быть объявлены герметичными.

Следующая программа демонстрирует абстрактный класс:

using System; namespace PolymorphismApplication < abstract class Shape < public abstract int area(); >class Rectangle: Shape < private int length; private int width; public Rectangle( int a = 0, int b = 0) < length = a; width = b; >public override int area () < Console.WriteLine("Rectangle class area :"); return (width * length); >> class RectangleTester < static void Main(string[] args) < Rectangle r = new Rectangle(10, 7); double a = r.area(); Console.WriteLine("Area: ",a); Console.ReadKey(); > > >

Когда приведенный выше код компилируется и выполняется, он производит следующий результат:

Rectangle class area : Area: 70

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

Следующая программа демонстрирует это:

using System; namespace PolymorphismApplication < class Shape < protected int width, height; public Shape( int a = 0, int b = 0) < width = a; height = b; >public virtual int area() < Console.WriteLine("Parent class area :"); return 0; >> class Rectangle: Shape < public Rectangle( int a = 0, int b = 0): base(a, b) < >public override int area () < Console.WriteLine("Rectangle class area :"); return (width * height); >> class Triangle: Shape < public Triangle(int a = 0, int b = 0): base(a, b) < >public override int area() < Console.WriteLine("Triangle class area :"); return (width * height / 2); >> class Caller < public void CallArea(Shape sh) < int a; a = sh.area(); Console.WriteLine("Area: ", a); > > class Tester < static void Main(string[] args) < Caller c = new Caller(); Rectangle r = new Rectangle(10, 7); Triangle t = new Triangle(10, 5); c.CallArea(r); c.CallArea(t); Console.ReadKey(); >> >

Когда приведенный выше код компилируется и выполняется, он производит следующий результат:

Rectangle class area: Area: 70 Triangle class area: Area: 25

Polymorphism

Polymorphism is often referred to as the third pillar of object-oriented programming, after encapsulation and inheritance. Polymorphism is a Greek word that means “many-shaped” and it has two distinct aspects:

  • At run time, objects of a derived class may be treated as objects of a base class in places such as method parameters and collections or arrays. When this polymorphism occurs, the object’s declared type is no longer identical to its run-time type.
  • Base classes may define and implement virtualmethods, and derived classes can override them, which means they provide their own definition and implementation. At run-time, when client code calls the method, the CLR looks up the run-time type of the object, and invokes that override of the virtual method. In your source code you can call a method on a base class, and cause a derived class’s version of the method to be executed.

Virtual methods enable you to work with groups of related objects in a uniform way. For example, suppose you have a drawing application that enables a user to create various kinds of shapes on a drawing surface. You don’t know at compile time which specific types of shapes the user will create. However, the application has to keep track of all the various types of shapes that are created, and it has to update them in response to user mouse actions. You can use polymorphism to solve this problem in two basic steps:

  1. Create a class hierarchy in which each specific shape class derives from a common base class.
  2. Use a virtual method to invoke the appropriate method on any derived class through a single call to the base class method.

First, create a base class called Shape , and derived classes such as Rectangle , Circle , and Triangle . Give the Shape class a virtual method called Draw , and override it in each derived class to draw the particular shape that the class represents. Create a List object and add a Circle , Triangle , and Rectangle to it.

public class Shape < // A few example members public int X < get; private set; >public int Y < get; private set; >public int Height < get; set; >public int Width < get; set; >// Virtual method public virtual void Draw() < Console.WriteLine("Performing base class drawing tasks"); >> public class Circle : Shape < public override void Draw() < // Code to draw a circle. Console.WriteLine("Drawing a circle"); base.Draw(); >> public class Rectangle : Shape < public override void Draw() < // Code to draw a rectangle. Console.WriteLine("Drawing a rectangle"); base.Draw(); >> public class Triangle : Shape < public override void Draw() < // Code to draw a triangle. Console.WriteLine("Drawing a triangle"); base.Draw(); >> 

To update the drawing surface, use a foreach loop to iterate through the list and call the Draw method on each Shape object in the list. Even though each object in the list has a declared type of Shape , it’s the run-time type (the overridden version of the method in each derived class) that will be invoked.

// Polymorphism at work #1: a Rectangle, Triangle and Circle // can all be used wherever a Shape is expected. No cast is // required because an implicit conversion exists from a derived // class to its base class. var shapes = new List < new Rectangle(), new Triangle(), new Circle() >; // Polymorphism at work #2: the virtual method Draw is // invoked on each of the derived classes, not the base class. foreach (var shape in shapes) < shape.Draw(); >/* Output: Drawing a rectangle Performing base class drawing tasks Drawing a triangle Performing base class drawing tasks Drawing a circle Performing base class drawing tasks */ 

In C#, every type is polymorphic because all types, including user-defined types, inherit from Object.

Polymorphism overview

Virtual members

When a derived class inherits from a base class, it includes all the members of the base class. All the behavior declared in the base class is part of the derived class. That enables objects of the derived class to be treated as objects of the base class. Access modifiers ( public , protected , private and so on) determine if those members are accessible from the derived class implementation. Virtual methods gives the designer different choices for the behavior of the derived class:

  • The derived class may override virtual members in the base class, defining new behavior.
  • The derived class may inherit the closest base class method without overriding it, preserving the existing behavior but enabling further derived classes to override the method.
  • The derived class may define new non-virtual implementation of those members that hide the base class implementations.

A derived class can override a base class member only if the base class member is declared as virtual or abstract. The derived member must use the override keyword to explicitly indicate that the method is intended to participate in virtual invocation. The following code provides an example:

public class BaseClass < public virtual void DoWork() < >public virtual int WorkProperty < get < return 0; >> > public class DerivedClass : BaseClass < public override void DoWork() < >public override int WorkProperty < get < return 0; >> > 

Fields can’t be virtual; only methods, properties, events, and indexers can be virtual. When a derived class overrides a virtual member, that member is called even when an instance of that class is being accessed as an instance of the base class. The following code provides an example:

DerivedClass B = new DerivedClass(); B.DoWork(); // Calls the new method. BaseClass A = B; A.DoWork(); // Also calls the new method. 

Virtual methods and properties enable derived classes to extend a base class without needing to use the base class implementation of a method. For more information, see Versioning with the Override and New Keywords. An interface provides another way to define a method or set of methods whose implementation is left to derived classes.

Hide base class members with new members

If you want your derived class to have a member with the same name as a member in a base class, you can use the new keyword to hide the base class member. The new keyword is put before the return type of a class member that is being replaced. The following code provides an example:

public class BaseClass < public void DoWork() < WorkField++; >public int WorkField; public int WorkProperty < get < return 0; >> > public class DerivedClass : BaseClass < public new void DoWork() < WorkField++; >public new int WorkField; public new int WorkProperty < get < return 0; >> > 

Hidden base class members may be accessed from client code by casting the instance of the derived class to an instance of the base class. For example:

DerivedClass B = new DerivedClass(); B.DoWork(); // Calls the new method. BaseClass A = (BaseClass)B; A.DoWork(); // Calls the old method. 

Prevent derived classes from overriding virtual members

Virtual members remain virtual, regardless of how many classes have been declared between the virtual member and the class that originally declared it. If class A declares a virtual member, and class B derives from A , and class C derives from B , class C inherits the virtual member, and may override it, regardless of whether class B declared an override for that member. The following code provides an example:

public class A < public virtual void DoWork() < >> public class B : A < public override void DoWork() < >> 

A derived class can stop virtual inheritance by declaring an override as sealed. Stopping inheritance requires putting the sealed keyword before the override keyword in the class member declaration. The following code provides an example:

public class C : B < public sealed override void DoWork() < >> 

In the previous example, the method DoWork is no longer virtual to any class derived from C . It’s still virtual for instances of C , even if they’re cast to type B or type A . Sealed methods can be replaced by derived classes by using the new keyword, as the following example shows:

public class D : C < public new void DoWork() < >> 

In this case, if DoWork is called on D using a variable of type D , the new DoWork is called. If a variable of type C , B , or A is used to access an instance of D , a call to DoWork will follow the rules of virtual inheritance, routing those calls to the implementation of DoWork on class C .

Access base class virtual members from derived classes

A derived class that has replaced or overridden a method or property can still access the method or property on the base class using the base keyword. The following code provides an example:

public class Base < public virtual void DoWork()</*. */ > > public class Derived : Base < public override void DoWork() < //Perform Derived's work here //. // Call DoWork on base class base.DoWork(); >> 

For more information, see base.

It is recommended that virtual members use base to call the base class implementation of that member in their own implementation. Letting the base class behavior occur enables the derived class to concentrate on implementing behavior specific to the derived class. If the base class implementation is not called, it is up to the derived class to make their behavior compatible with the behavior of the base class.

Feedback

Submit and view feedback for

Полиморфизм c что это за программа

В результате будет создан файл .cs с именем класса Phone . В нём будет объявлен класс с помощью ключевого слова class и объявление класса может иметь следующий вид:

 Самоучитель по C# для начинающих за 30 минут. Часть 2: ООП и коллекции

В результате выполнения выведены значения полей и отработаны методы класса. Но для более эффективного программирования классов используются конструкторы.

Больше полезных материалов вы найдете на нашем телеграм-канале «Библиотека шарписта»

Конструкторы

Конструктор – метод, имеющий имя класса, который используется для создания и инициализации объектов. Конструктор вызывается при создании объекта класса и его можно использовать для инициализации начальных значений полей.

Существуют следующие типы конструкторов:

  • конструктор без параметров;
  • параметризованный конструктор;
  • конструктор по умолчанию.

Конструктор по умолчанию создается в языке C#, если в классе не реализованы конструкторы.

Имя конструктора должно совпадать с именем класса и не может иметь тип возвращаемого значения.

Модифицируем класс Phone , добавив в него конструктор без параметров и с параметрами:

 Самоучитель по C# для начинающих за 30 минут. Часть 2: ООП и коллекции

Конструкторы, как и другие методы можно перегружать, используя разные параметры.

Модификаторы доступа

Модификаторы доступа используется для установки уровня доступа/видимости для классов, полей, методов и свойств. К модификаторам доступа относятся такие ключевые слова, как public , private , protected и internal , ранее использовался нами только public .

Модификатор Описание
public Код доступен для всех классов
private Код доступен только в пределах одного класса
Protected Код доступен в пределах одного класса или в классе, который наследуется от этого класса
Internal Код доступен только в пределах собственной сборки, но не из другой сборки

Если мы объявим поля нашего класса Phone или методы как private , то они станут недоступны для использования в других классах, например в Program . Ограничение доступа и является основой принципа ООП – инкапсуляции.

Инкапсуляция и свойства

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

  • объявить поля/переменные как private ;
  • обеспечить public get и set методы через свойства для доступа и изменения значения private поля.

Доступ к private переменным возможен только внутри одного и того же класса. Иногда нужно получить к ним доступ вне класса – и это можно сделать с помощью свойств.

Свойство похоже на комбинацию переменной и метода и имеет два метода: get() и set() .

 Самоучитель по C# для начинающих за 30 минут. Часть 2: ООП и коллекции

Поля можно сделать доступными только для чтения, используя get() или только для записи, используя set() .

C# позволяет использовать автоматические свойства, где не нужно определять поле для свойства, а достаточно написать get; и set; внутри свойства. Изменив класс Phone , следующим образом:

 Самоучитель по C# для начинающих за 30 минут. Часть 2: ООП и коллекции

Результат показывает, что класс Smartphone успешно унаследовал от класса Phone поля и метод.

Наследование позволяет существенно сократить объем кода, так как не требуется повторная реализация участков кода в других классах.

Полиморфизм и перегрузка методов

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

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

Например, базовый класс Device , у которого есть метод enabledScreen() . Производными классами устройств могут быть смартфоны, планшеты и у них также есть собственная реализация вывода информации на экран:

 Самоучитель по C# для начинающих за 30 минут. Часть 2: ООП и коллекции

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

Абстрактные классы и методы

Абстракция данных – это процесс сокрытия определенных деталей и показа пользователю только важной информации. Абстракция может быть достигнута либо с помощью абстрактных классов, либо с помощью интерфейсов.

Ключевое слово abstract используется для классов и методов:

  • абстрактный класс – это ограниченный класс, который нельзя использовать для создания объектов (для доступа к нему он должен быть унаследован от другого класса);
  • абстрактный метод: может использоваться только в абстрактном классе и не имеет тела. Тело предоставляется производным классом.

Абстрактный класс может иметь как абстрактные, так и обычные методы. Создавать объекты абстрактных классов нельзя. Для создания объектов должен использоваться класс наследник.

Рассмотрим на примере:

 Самоучитель по C# для начинающих за 30 минут. Часть 2: ООП и коллекции

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

Словарь

Класс Dictionary реализует структуру данных Отображение, которую иногда называют Словарь или Ассоциативный массив. Идея довольно проста: в обычном массиве доступ к данным мы получаем через целочисленный индекс, а в словаре используется ключ, который может быть числом, строкой или любым другим типом данных, который реализует метод GetHashCode() . При добавлении нового объекта в такую коллекцию для него указывается уникальный ключ, который используется для последующего доступа к нему.

Пустой словарь можно объявить так:

 Самоучитель по C# для начинающих за 30 минут. Часть 2: ООП и коллекции

Продемонстрировано использование основных свойств и методов класса Dictoniary .

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

Материалы по теме

  • Руководство по С# для начинающих: массивы и цикл foreach
  • 8 шагов от новичка до профессионала: дорожная карта разработчика на C#
  • ТОП-10 книг по C#: от новичка до профессионала

При подготовке материала использовались источники:
https://unetway.com/tutorial/c-sharp-polymorphism
https://learn.microsoft.com/en-us/dotnet/csharp/fundamentals/object-oriented/polymorphism
https://proglib.io/p/samouchitel-po-c-dlya-nachinayushchih-za-30-minut-chast-2-oop-i-kollekcii-2022-03-08

Добавить комментарий