Что такое полиморфизм в Javascript?



Я прочитал некоторые возможные статьи, которые я мог бы найти в интернете на полиморфизм. Но я думаю, что не мог полностью понять смысл этого и его важность. В большинстве статей не говорится, почему это важно и как я могу добиться полиморфного поведения в ООП (конечно, в JavaScript).



Я не могу представить какой-либо пример кода, потому что у меня нет идеи как это реализовать, поэтому мои вопросы ниже:




  1. что это?

  2. зачем нам это нужно ?

  3. как это работает?

  4. как я могу добиться такого полиморфного поведения в javascript?


У меня есть этот пример. Но легко понять, каким будет результат этого кодекса. Это не дает четкого представления о самом полиморфизме.



function Person(age, weight) {
this.age = age;
this.weight = weight;
this.getInfo = function() {
return "I am " + this.age + " years old " +
"and weighs " + this.weight +" kilo.";
}
}
function Employee(age, weight, salary) {
this.salary = salary;
this.age = age;
this.weight = weight;
this.getInfo = function() {
return "I am " + this.age + " years old " +
"and weighs " + this.weight +" kilo " +
"and earns " + this.salary + " dollar.";
}
}

Employee.prototype = new Person();
Employee.prototype.constructor = Employee;
// The argument, 'obj', can be of any kind
// which method, getInfo(), to be executed depend on the object
// that 'obj' refer to.

function showInfo(obj) {
document.write(obj.getInfo() + "<br>");
}

var person = new Person(50,90);
var employee = new Employee(43,80,50000);
showInfo(person);
showInfo(employee);
892   6  

6 ответов:

полиморфизм является одним из принципов объектно-ориентированного программирования (ООП). Это практика проектирования объектов для совместного использования поведения и возможности переопределения общего поведения с конкретными. Полиморфизм использует наследование для того, чтобы это произошло.

в ООП все считается моделируемым как объект. Эта абстракция может быть принята вплоть до гаек и болтов для автомобиля, или так же широко, как просто тип автомобиля с годом, маркой и модель.

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

получаете возвращаясь к примеру людей и сотрудников, все сотрудники-это люди, но все люди не являются сотрудниками. То есть люди будут суперклассом, а служащие-подклассом. Люди могут иметь возраст и вес, но у них нет зарплаты. Сотрудники-это люди, поэтому они по своей сути будут иметь возраст и вес, но также и потому, что они сотрудники, у них будет зарплата.

Итак, чтобы облегчить это, мы сначала выпишем супер класс (Человек)

function Person(age,weight){
 this.age = age;
 this.weight = weight;
}

и мы дадим человеку возможность поделиться своей информацией

Person.prototype.getInfo = function(){
 return "I am " + this.age + " years old " +
    "and weighs " + this.weight +" kilo.";
};

Далее мы хотим иметь подкласс Person, Employee

function Employee(age,weight,salary){
 this.age = age;
 this.weight = weight;
 this.salary = salary;
}
Employee.prototype = new Person();

и мы переопределим поведение getInfo, определив тот, который больше подходит для сотрудника

Employee.prototype.getInfo = function(){
 return "I am " + this.age + " years old " +
    "and weighs " + this.weight +" kilo " +
    "and earns " + this.salary + " dollar.";  
};

они могут быть использованы аналогично исходному коду использовать

var person = new Person(50,90);
var employee = new Employee(43,80,50000);

console.log(person.getInfo());
console.log(employee.getInfo());

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

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

лучшее объяснение по этому вопросу, которое я когда-либо читал, - это статья От Luca Cardelli известный теоретик типа. Статья называется о понимании типов, абстракции данных и полиморфизма.

что это?

Карделли определяет несколько типов полиморфизма в этом статья:

  • универсальный
    • параметрический
    • включение
  • специальные
    • oveloading
    • принуждение

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

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

тем не менее, JavaScript имеет форму наследования типов, которая эмулирует те же идеи полиморфизма подтипа (классифицированного как полиморфизм включения по Карделли выше) в аналогично тому, что мы обычно делаем в других объектно-ориентированных языках программирования, как Java или C#, как уже говорилось в другой ответ.

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

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

Зачем Нам Это Нужно?

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

как это работает?

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

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

что это?

Поли= много, морфизм=форма или изменение поведения.

зачем оно нужно ?

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

Как это работает?

мы пишем несколько реализаций функции X, где каждая реализация принимает различные типы параметров или числом параметров. На основе типа или количества параметров компилятор (во время выполнения) решает, какая реализация X должна выполняться, когда X вызывается из некоторого кода.

Как я могу добиться такого полиморфного поведения в javascript?

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

какова цель полиморфизма?

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

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

как это относится к Javascript?

Javascript имеет слабую, динамическую систему типов. Такая система типов эквивалентна строгой системе типов, содержащей только один тип. Мы можем думать о таком типе как огромный тип объединения (псевдо синтаксис):

type T =
 | Undefined
 | Null
 | Number
 | String
 | Boolean
 | Symbol
 | Object
 | Array
 | Map
 | ...

каждое значение будет связано с одним из этих типов альтернатив во время выполнения. И поскольку Javascript слабо типизирован, каждое значение может изменить свой тип любым количество раз.

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

но это не должно мешать нам думать о типах в наших программах. Из-за отсутствия типов в Javascript нам нужно вывести их во время процесса кодирования. Наш разум должен встать на защиту пропавших без вести компилятор, т. е. как только мы смотрим на программу, мы должны распознавать не только алгоритмы, но и базовые (возможно, полиморфные) типы. Эти типы помогут нам построить более надежные и более надежные программы.

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

параметрический полиморфизм (он же дженерики)

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

// parametric polymorphic functions

const id = x => x;

id(1); // 1
id("foo"); // "foo"

const k = x => y => x;
const k_ = x => y => y;

k(1) ("foo"); // 1
k_(1) ("foo"); // "foo"

const append = x => xs => xs.concat([x]);

append(3) ([1, 2]); // [1, 2, 3]
append("c") (["a", "b"]); // ["a", "b", "c"]

специальный полиморфизм (он же перегрузка)

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

специальный полиморфизм делает функцию совместимой с большим доменом типов. В следующем примере показано назначение "map-over" и то, как типы могут реализовать это ограничение. Вместо набора функций ограничение "mappable" включает только один map функция:

// Option type
class Option {
  cata(pattern, option) {
    return pattern[option.constructor.name](option.x);
  }
  
  map(f, opt) {
    return this.cata({Some: x => new Some(f(x)), None: () => this}, opt);
  }
};

class Some extends Option {
  constructor(x) {
    super(x);
    this.x = x;
  }
};

class None extends Option {
  constructor() {
    super();
  }
};


// ad-hoc polymorphic function
const map = f => t => t.map(f, t);

// helper/data

const sqr = x => x * x;

const xs = [1, 2, 3];
const x = new Some(5);
const y = new None();

// application

console.log(
  map(sqr) (xs) // [1, 4, 9]
);

console.log(
  map(sqr) (x) // Some {x: 25}
);

console.log(
  map(sqr) (y) // None {}
);

полиморфизм подтипа

поскольку другие ответы уже охватывают полиморфизм подтипа, я его пропускаю.

структурный полиморфизм (он же strutrual subtyping)

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

const weight = {value: 90, foo: true};
const speed =  {value: 90, foo: false, bar: [1, 2, 3]};

к сожалению, speed является подтипом weight и как только мы сравниваем value свойства мы практически сравнение яблок с апельсинами.

JavaScript-это интерпретируемый язык, а не компилируемый язык.

полиморфизм времени компиляции (или статический полиморфизм) полиморфизм времени компиляции-это не что иное,как перегрузка метода в java, c++

поэтому перегрузка метода в javascript невозможна.

но динамический (время выполнения) полиморфизм-это полиморфизм, существующий во время выполнения таким образом, переопределение метода возможно в javascript

другой пример-PHP.

Polymorphism means Ability to call the same method on different objects and each object responds in different way is called **POLYMORPHISM**.

    function Animal(sound){
    this.sound=sound;
    this.speak=function(){
    			return this.sound;
    	}
    }
//one method 
    function showInfo(obj){
    		console.log(obj.speak());
    }
//different objects
    var dog = new Animal("woof");
    var cat = new Animal("meow");
    var cow = new Animal("humbow");
//responds different ways
    showInfo(dog);
    showInfo(cat);
    showInfo(cow);

Comments

    Ничего не найдено.