Рубрики
ООП ООП "Интерфейс" ООП принцип "Полиморфизм"

ООП Интерфейс «Понятие»

  • определить контракт взаимодействия между классами
  • определяем поведение, которое впоследствии будет реализовано в каком-то классе
  • как будут вести себя наследники без каких-либо деталей
  • нет ни какой реализации
  • абстрактные методы
  • не может быть конструкторов
  • не может содержать поля классов
  • описывается сигнатура методов
  • публичный контракт взаимодействия
    по умолчанию все члены интерфейса имеют модификатор public
  • Полиморфизм
    Передаётся тип данных — это тип интерфейса
    в качестве параметра будет принимать объект класса, который у нас будет реализовывать интерфейс.
  • интерфейс может содержать свойство
    свойство — это методы, которые маскируются
Рубрики
C# основы.ООП ООП ООП "Класс" ООП принцип "Инкапсуляция" ООП принцип "Наследование" ООП принцип "Полиморфизм"

Общий Класс

общий класс создаётся благодаря наследованию
базовый класс класс, который наследуется

Характерные Особенности

присущие множеству связанных элементов

Рубрики
ООП принцип "Полиморфизм"

ООП принцип Полиморфизм «Понятие»

Полиморфизм

определение
это что-то многообразное т.е. имеет поли много форм

в контексте ООП полиморфизм можно воспринимать как некоторый принцип, который позволяет одному и тому же фрагменту кода работать с разными типами данных. Это очень важный принцип и на нём основано подавляющее количество паттернов в принципе проектирования. Но все принципы ООП связаны и без того же наследования полиморфизм не был бы возможен.

выделяют два основных типа полиморфизма

  • параметрический является истинным

Рассмотрим иерархию (Человека, Работник, Программист). Все они встретились в одной комнате и задача их познакомится т.е. каждый из этих объектов должен сказать какие-то приветственные слова и объяснить кто он.

  • Объект, созданный из класса Person
    говорит «Привет я человек Вася».
  • Объект, созданный из класса Employee
    говорит «Привет я работник Петя»
  • Объект, созданный из класса Devoloper
    говорит «Привет я прогер Евпатий»

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

class Person{
...
public greeting(){
 console.log('Привет я человек и меня зовут ${this._firstName}');
}
...
}
class Employee extends Person{
...
public greeting(){
 console.log('Привет я работник и меня зовут ${this._firstName}');
}
...
}
class Developer extends Employee {
...
public greeting(){
 console.log('Привет я программист и меня зовут ${this._firstName}');
}
...
}

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

первый массив объектов, созданных из Person
второй массив объектов, созданных из Работников
третий массив объектов, созданных из Разработчиков

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

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

Создадим массив, который содержит все как разработчика, так и обычного работника, так просто человека. Сразу укажем, что это у нас массив типа данных т.е. явным образом мы не указываем, что у нас там помимо Person, находятся там и разработчик Developer, работник Employee. Мы просто указываем, что это массив типа Person.

const personList:Person[] = [developer,employee,person]

После чего мы создаём функцию и называем её «массовое приветствие» и аргументом она принимает массив типа Person и сразу же вызываем эту функцию с нашим массивом

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

function massGreeting(persons:Person[]){
for (let i =0; i < persons.length; i++){
 const person = persons[i];
 person.greeting();
}
}
massGreeting(personList);

Смотри в логи и видем следующий результат: каждый из объектов поприветствовал нужным образом т.е.

  • разработчик сказал, что он разработчик
  • работник сказал, что он работник
  • человек сказал, что он человек

Не смотря, что класс Developer или класс Employee внутри этой функции не задействованы вообще ни как, но отработали соответствующие методы т.е. данное поведение называется полиморфизмом. Мы работаем с объектами, у которых функция greeting работает по разному. При этом в нашем примере там идёт всего лишь вывод в логи, но там может быть какая-то другая логика (более сложная). При этом у нас в массиве находится три разных типа, но функция massGreeting работает с ними всеми одинаково, но при это когда вызывается соответствующий метод, то логика в этом методе разная. В этом и заключается смысл полиморфизма т.е. в данном случае у нас форм, но работаем по сути мы с ними одинаково.

  • ad-hoc является мнимым

В примере класс калькулятор Calculator. В нём есть два метода, которые называются одинаково add и принимают одинаковые параметры, но разных типов. Первый метод работает с числовым типом number, а второй со строковым string. Если мы вызовем метод с двумя 5 то в результате получим 10 т.е. результат суммы этих чисел. Если вызовем со строками, то по сути получим контикинацию «55» т.е. получается, что один метод работает как бы с двумя типами данных. Это происходит за счёт перегрузки методов и такой полиморфизм считается мнимым.

Так мнимым полиморфизмом (так называемым add-hoc полиморфизмом) считается приведение типов. Это когда мы явно какой-то дочерний класс преобразовываем к родительскому.

class Calculator {
 add(a: number, b: number): number {
  return a + b;
 }

 add(a: string, b:string): string {
  return a + b;
 }
}
add(5,5)  -> reult = 10;
add("5","5") -> result = "55";