Na forum 4programmers.net korzystamy z plików cookies. Część z nich jest niezbędna do funkcjonowania
naszego forum, natomiast wykorzystanie pozostałych zależy od Twojej dobrowolnej zgody, którą możesz
wyrazić poniżej. Klikając „Zaakceptuj Wszystkie” zgadzasz się na wykorzystywanie przez nas plików cookies
analitycznych oraz reklamowych, jeżeli nie chcesz udzielić nam swojej zgody kliknij „Tylko niezbędne”.
Możesz także wyrazić swoją zgodę odrębnie dla plików cookies analitycznych lub reklamowych. W tym celu
ustaw odpowiednio pola wyboru i kliknij „Zaakceptuj Zaznaczone”. Więcej informacji o technologii cookie
znajduje się w naszej polityce prywatności.
Witajcie,
próbuje zrozumieć istotę polimorfizmu. Skoro to traktowanie w ten sam sposób różnych danych, to zapewne chodzi o metodę writeFullName. No ale co dalej?
function Person() {
this.namw = "";
this.surname = "";
}
function Programme() {
this.knownLanguage = "";
}
Programmer.protoype = new Person();
function writeFullName(p) {
console.lg(p.name + " " + p.surname);
}
var a = new Person();
a.name = "Jan";
a.surname = "Kowalski";
var b = new Programmer();
b.name = "Mario";
b.surname = "Rossi";
b.knownLanguage = "JavaScript";
writeFullName(a);
writeFullName(b);
0
Czy ten kod działa? Masz literówki, które pozbawiają ten przykład sensu.
2
O polimorfizmie można mówić gdy tworzymy jednolity sposób obsługi danych różnego typu. Przykładowo masz obiekt Person i obiekt Programmer, a następnie masz metodę np. describe(), która dla obiektu Person wyświetli imię i nazwisko, a dla obiektu Programmer dodatkowo wyświetli np. język w którym programuje. Co istotne jeżeli użyjesz metody describe() obiektu po którym dziedziczysz na obiekcie typu, który po nim dziedziczy to nadal wszystko będzie działać czyli obiekt Programmer w kontekście klasy nadrzędnej Person przedstawi się tylko imieniem i nazwiskiem.
Pamiętaj, że ES6 wprowadził klasy, które ukrywają pod spodem prototypy. Z tego też powodu należy się nauczyć polimorfizmu w kontekście prototypów oraz klas. W obu przypadkach będzie to działać tak samo, ale zapis będzie nieco inny.
Invariants of the Supertype Must Be Preserved in a Subtype
Preconditions Cannot Be Strengthened in a Subtype
Postconditions Cannot Be Weakened in a Subtype.
Osobiście najczęściej spotykam się z naruszeniem pkt. 2. Czyli ktoś w klasie bazowej pozwala na wszystko, np. działania na liczbach, a w klasie dziedziczącej dodaje jakiegoś if'a, który pozwala tylko na liczby dodatnie.
1
To, co się dzieje w powyższym kodzie już dobrze wytłumaczył @Haskell, w sumie nie ma nic więcej do dodania. W JavaScript to trochę słabo widać, bo tutaj sprawdzanie typów odbywa się przez duck-typing, bo do funkcji możesz przekazać dosłownie wszystko. Ale trochę więcej o polimorfizmie:
Poly, czyli wiele (poligon - wielokąt, poliglota - osoba mówiąca w wielu językach)
Morph, czyli zmiana formy (z ang. to morph oznacza przemieniać, płynnie przechodzić z jednego obrazu w drugi).
Czyli polimorfizm, to możliwość posiadania tego samego interfejsu dla różnych typów.
Załóżmy, że mamy byt figura (geometryczna). Możemy mieć figury koło, kwadrat, prostokąt i trójkąt. Te figury różnią się miedzy sobą, ale każdy z tych bytów jest figurą, a w związku z tym ma pole powierzchni. Jeżeli mamy jakiś zbiór figur i chcemy poznać ich sumaryczne pole powierzchni, to dzięki polimorfizmowi wiemy, że każdy byt, jeżeli tylko jest figurą, to ma metodę do obliczenia pola powierzchni, którą możemy bezpiecznie użyć.
W JS moim zdaniem to bardzo trudno zrozumieć, bo nie ma interfejsów jako takich (znanych z Javy, PHP, czy C#), ale wyglądało by to mniej więcej tak:
class Triangle {
constructor(a, h) {
this.a = a;
this.h = h;
}
area() {
return 0.5 * this.a * this.h;
}
}
class Rectangle {
constructor(a, b) {
this.a = a;
this.b = b;
}
area() {
return this.a * this.b;
}
}
class Circle {
constructor(r) {
this.r = r;
}
area() {
return Math.PI * Math.pow(this.r, 2);
}
}
function calculateTotalArea(shapes) {
let total = 0;
for (shape of shapes) {
if (typeof shape.area === 'function') { // <-- przykład duck typingu
total += shape.area();
}
}
return total;
}
const shapes = [new Triangle(5, 10), new Rectangle(5, 10), new Circle(5)];
console.log(calculateTotalArea(shapes));
1 użytkowników online, w tym zalogowanych: 0, gości: 1