Jeśli chodzi o Javę, gdy ktoś pyta:
co to jest polimorfizm?
Czy przeciążenie lub zastąpienie byłoby akceptowalną odpowiedzią?
Myślę, że jest w tym coś więcej.
JEŚLI masz abstrakcyjną klasę podstawową, która zdefiniowała metodę bez implementacji i zdefiniowałeś tę metodę w podklasie, czy to wciąż jest nadrzędne?
Myślę, że przeciążenie nie jest z pewnością właściwą odpowiedzią.
java
oop
polymorphism
overloading
overriding
Brian G.
źródło
źródło
Odpowiedzi:
Najwyraźniejszym sposobem wyrażenia polimorfizmu jest użycie abstrakcyjnej klasy bazowej (lub interfejsu)
Ta klasa jest abstrakcyjna, ponieważ
goPee()
metody nie można zdefiniować dla ludzi. Można go zdefiniować tylko w podklasach „Mężczyzna” i „Kobieta”. Ponadto człowiek jest pojęciem abstrakcyjnym - nie można stworzyć człowieka, który nie jest ani mężczyzną, ani kobietą. To musi być jeden lub drugi.Dlatego odraczamy implementację za pomocą klasy abstrakcyjnej.
i
Teraz możemy powiedzieć całemu pokojowi wypełnionemu ludźmi, żeby się wysikał.
Uruchomienie tego spowoduje:
źródło
goPee
nie przyjmuje pola grawitacyjnego jako danych wejściowych. Ta zależność od stanu globalnego utrudnia testowanie jednostkoweCatheterizedIntersexAstronaut
i pokazuje, że podklasowanie nie zawsze może być najlepszą metodą komponowania cech.Polimorfizm to zdolność instancji klasy do zachowania się tak, jakby była instancją innej klasy w drzewie dziedziczenia, najczęściej jednej z klas przodków. Na przykład w Javie wszystkie klasy dziedziczą po Object. Dlatego możesz utworzyć zmienną typu Object i przypisać do niej instancję dowolnej klasy.
przesłanianiejest rodzajem funkcji występującej w klasie, która dziedziczy po innej klasie. Funkcja przesłonięcia „zastępuje” funkcję odziedziczoną z klasy podstawowej, ale robi to w taki sposób, że jest wywoływana nawet wtedy, gdy wystąpienie jej klasy udaje inny typ poprzez polimorfizm. Nawiązując do poprzedniego przykładu, możesz zdefiniować własną klasę i zastąpić funkcję toString (). Ponieważ ta funkcja jest dziedziczona z Object, będzie nadal dostępna, jeśli skopiujesz instancję tej klasy do zmiennej typu Object. Zwykle, jeśli wywołasz metodę toString () w swojej klasie, gdy udaje ona obiekt, to wersja toString, która faktycznie będzie odpalać, jest zdefiniowana w samym obiekcie. Ponieważ jednak funkcja jest przesłonięta, definicja metody toString () z Twojej klasy jest używana nawet wtedy, gdy instancja klasy „
Przeciążenie polega na zdefiniowaniu wielu metod o tej samej nazwie, ale o różnych parametrach. Nie ma to związku z nadpisywaniem ani polimorfizmem.
źródło
Ad hoc polymorphism
jest tym, co opisałeś w sekcji Przeładowanie i jest przypadkiem polimorfizmu.Polimorfizm oznacza więcej niż jedną formę, ten sam obiekt wykonujący różne operacje zgodnie z wymaganiami.
Polimorfizm można osiągnąć za pomocą dwóch sposobów
Przeciążenie metody oznacza napisanie dwóch lub więcej metod w tej samej klasie przy użyciu tej samej nazwy metody, ale parametry przekazywania są różne.
Przesłonięcie metody oznacza, że używamy nazw metod w różnych klasach, co oznacza, że metoda klasy nadrzędnej jest używana w klasie potomnej.
W Javie w celu osiągnięcia polimorfizmu zmienna referencyjna superklasy może przechowywać obiekt podklasy.
Aby osiągnąć polimorfizm, każdy programista musi używać tych samych nazw metod w projekcie.
źródło
Oto przykład polimorfizmu w pseudo-C # / Java:
Funkcja Main nie zna typu zwierzęcia i zależy od zachowania konkretnej implementacji metody MakeNoise ().
Edycja: Wygląda na to, że Brian pobił mnie na pięcie. Zabawne, że użyliśmy tego samego przykładu. Ale powyższy kod powinien pomóc wyjaśnić pojęcia.
źródło
Zarówno zastępowanie, jak i przeciążanie są wykorzystywane do osiągnięcia polimorfizmu.
Możesz mieć metodę w klasie, która jest nadpisana w jednej lub więcej podklas. Metoda robi różne rzeczy w zależności od tego, która klasa została użyta do utworzenia obiektu.
Możesz także mieć metodę, która jest przeciążona dwoma lub więcej zestawami argumentów. Metoda robi różne rzeczy w zależności od typu przekazanych argumentów.
źródło
Masz rację, że przeciążenie nie jest odpowiedzią.
Żadne nie jest nadrzędne. Przesłanianie to sposób, w jaki uzyskujesz polimorfizm. Polimorfizm to zdolność obiektu do zmiany zachowania w zależności od jego typu. Najlepiej jest to wykazane, gdy obiekt wywołujący polimorfizm nie jest świadomy tego, jaki jest konkretny typ obiektu.
źródło
Mówiąc konkretnie, przeciążenie lub zastąpienie nie daje pełnego obrazu. Polimorfizm to po prostu zdolność obiektu do specjalizacji swojego zachowania w zależności od jego typu.
Nie zgadzam się z niektórymi odpowiedziami tutaj, ponieważ przeciążenie jest formą polimorfizmu (polimorfizm parametryczny) w przypadku, gdy metoda o tej samej nazwie może zachowywać się inaczej, dając różne typy parametrów. Dobrym przykładem jest przeciążenie operatora. Możesz zdefiniować „+”, aby akceptować różne typy parametrów - powiedzmy łańcuchy lub int - i na podstawie tych typów „+” będzie się zachowywać inaczej.
Polimorfizm obejmuje także metody dziedziczenia i przesłonięcia, chociaż mogą być abstrakcyjne lub wirtualne w typie podstawowym. Jeśli chodzi o polimorfizm oparty na dziedziczeniu, Java obsługuje tylko dziedziczenie pojedynczej klasy, co ogranicza zachowanie polimorficzne do pojedynczego łańcucha typów podstawowych. Java obsługuje implementację wielu interfejsów, co jest kolejną formą zachowania polimorficznego.
źródło
Polimorfizm oznacza po prostu „Wiele form”.
Nie jest wymagane dziedziczenie w celu osiągnięcia ... ponieważ implementacja interfejsu, która wcale nie jest dziedziczeniem, spełnia potrzeby polimorficzne. Prawdopodobnie implementacja interfejsu spełnia potrzeby polimorficzne „Lepsze” niż dziedziczenie.
Na przykład, czy stworzyłbyś superklasę do opisywania wszystkich rzeczy, które potrafią latać? Nie powinienem myśleć. Najlepiej byłoby, gdybyś stworzył interfejs opisujący lot i zostaw to.
Ponieważ interfejsy opisują zachowanie, a nazwy metod opisują zachowanie (dla programisty), rozważenie przeciążenia metody jako mniejszej formy polimorfizmu nie jest zbyt daleko idące.
źródło
Klasyczny przykład: Psy i koty to zwierzęta, zwierzęta mają metodę makeNoise. Mogę iterować przez szereg zwierząt wywołujących na nich makeNoise i oczekuję, że zrobią tam odpowiednią implementację.
Kod wywoławczy nie musi wiedzieć, jakie to konkretne zwierzę.
To, co uważam za polimorfizm.
źródło
Polimorfizm to zdolność obiektu do pojawiania się w wielu formach. Wiąże się to z wykorzystaniem funkcji dziedziczenia i funkcji wirtualnych do zbudowania rodziny obiektów, które można zamieniać. Klasa podstawowa zawiera prototypy funkcji wirtualnych, być może niezaimplementowanych lub z domyślnymi implementacjami, jak nakazuje aplikacja, a każda z różnych klas pochodnych implementuje je inaczej, aby wpływać na różne zachowania.
źródło
Ani:
Przeciążenie występuje wtedy, gdy masz tę samą nazwę funkcji, która przyjmuje różne parametry.
Przesłanianie ma miejsce wtedy, gdy klasa potomna zastępuje metodę rodzica jedną z jej własnych (to samo w sobie nie stanowi polimorfizmu).
Polimorfizm wiąże się późno, np. Wywoływane są metody klasy podstawowej (rodzicielskiej), ale dopiero wtedy, gdy środowisko wykonawcze dowie się, jaki jest rzeczywisty obiekt - może to być klasa potomna, której metody są różne. Wynika to z faktu, że można użyć dowolnej klasy potomnej, w której zdefiniowano klasę podstawową.
W Javie często spotyka się polimorfizm w bibliotece kolekcji:
Lista jest klasą podstawową, kompilator nie ma pojęcia, czy liczy się lista połączona, wektor, tablica lub niestandardowa implementacja listy, o ile działa ona jak Lista:
Gdybyś był przeciążony, miałbyś:
a kompilator wybierze poprawną wersję countStuff (), aby dopasować parametry.
źródło
Chociaż polimorfizm jest już szczegółowo wyjaśniony w tym poście, ale chciałbym położyć większy nacisk na jego część.
Spróbujmy zbudować prostą aplikację do telewizora z dziedziczeniem / polimorfizmem i bez niego. Po każdej wersji aplikacji wykonujemy małą retrospektywę.
Załóżmy, że jesteś inżynierem oprogramowania w firmie telewizyjnej i jesteś proszony o napisanie oprogramowania dla kontrolerów głośności, jasności i koloru, aby zwiększyć lub zmniejszyć ich wartości na polecenie użytkownika.
Zaczynasz od pisania zajęć dla każdej z tych funkcji, dodając
Teraz masz naszą pierwszą wersję działającej aplikacji gotową do wdrożenia. Czas przeanalizować dotychczasowe prace.
Postanawiasz żyć z tym tak długo, jak długo aplikacja będzie działać zgodnie z oczekiwaniami.
Zaczynasz pisać nową klasę (ResetFunctionV2) dla nowej funkcjonalności i mapujesz wejściowy kod mapowania dla tej nowej funkcji.
Przygotuj aplikację dzięki funkcji Reset. Ale teraz zaczynasz zdawać sobie z tego sprawę
Teraz zaczynasz myśleć, że ta nowa funkcja, która ma zostać dodana, przypomina funkcję Resetuj, a problemy z aplikacją (V2) zostaną pomnożone, jeśli nie zmienisz współczynnika swojej aplikacji.
Zaczynasz myśleć o używaniu dziedziczenia, aby móc skorzystać z polimorficznej zdolności JAVA i dodajesz nową klasę abstrakcyjną (ControllerV3) do
Dzięki tym ulepszeniom masz gotową wersję 3 aplikacji telewizyjnej.
Chociaż większość problemów wymienionych na liście problemów w wersji V2 została rozwiązana z wyjątkiem
Znowu myślisz o rozwiązaniu tego problemu, ponieważ teraz masz także inną funkcję (aktualizacja sterownika przy uruchomieniu). Jeśli go nie naprawisz, zostanie również zreplikowane do nowych funkcji.
Dzielisz więc kontrakt zdefiniowany w klasie abstrakcyjnej i piszesz 2 interfejsy
I niech twoja pierwsza konkretna klasa zastosuje je jak poniżej
Mam nadzieję że to pomoże :-)
źródło
Termin przeciążenie odnosi się do posiadania wielu wersji czegoś o tej samej nazwie, zwykle metod o różnych listach parametrów
Więc te funkcje mogą zrobić to samo, ale masz możliwość wywołania go z identyfikatorem lub nazwą. Nie ma nic wspólnego z dziedziczeniem, klasami abstrakcyjnymi itp.
Przesłanianie zwykle odnosi się do polimorfizmu, jak opisano w pytaniu
źródło
przeciążenie ma miejsce, gdy zdefiniujesz 2 metody o tej samej nazwie, ale o różnych parametrach
przesłonięcie polega na zmianie zachowania klasy podstawowej za pomocą funkcji o tej samej nazwie w podklasie.
Polimorfizm jest więc związany z nadpisywaniem, ale nie przeciążaniem.
Jeśli jednak ktoś dał mi prostą odpowiedź „nadpisanie” na pytanie „Co to jest polimorfizm?” Poprosiłbym o dalsze wyjaśnienia.
źródło
przesłonięcie jest bardziej jak ukrywanie odziedziczonej metody poprzez zadeklarowanie metody o takiej samej nazwie i sygnaturze jak metoda wyższego poziomu (super metoda), to dodaje zachowanie polimorficzne do klasy. innymi słowy, decyzja o wyborze metody poziomu, która ma zostać wywołana, zostanie podjęta w czasie wykonywania, a nie w czasie kompilacji. prowadzi to do koncepcji interfejsu i implementacji.
źródło
Z java samouczka
Słownikowa definicja polimorfizmu odnosi się do zasady w biologii, w której organizm lub gatunek może mieć wiele różnych form lub stadiów. Zasadę tę można także zastosować do programowania obiektowego i języków takich jak język Java. Podklasy klasy mogą definiować własne unikalne zachowania, a jednocześnie udostępniać niektóre z tych samych funkcji klasy nadrzędnej.
Biorąc pod uwagę przykłady i definicję, zastępowanie powinny być zaakceptowane odpowiedź.
Jeśli chodzi o twoje drugie zapytanie:
Należy to nazwać przesłonięciem.
Spójrz na ten przykład, aby zrozumieć różne typy zastępowania.
super.methodName()
jako pierwszą instrukcjęfragment kodu:
wynik:
źródło
Myślę, że faceci mieszają koncepcje. Polimorfizm to zdolność obiektu do zachowania się inaczej w czasie wykonywania. Aby to osiągnąć, potrzebujesz dwóch wymagań:
Powiedziawszy, że przeciążenie oznacza coś innego niż zastąpienie w zależności od używanego języka. Na przykład w Javie nie istnieje nadpisywanie, ale przeciążanie . Przeciążone metody z inną sygnaturą niż klasa podstawowa są dostępne w podklasie. W przeciwnym razie zostałyby zastąpione (proszę zauważyć, że mam na myśli fakt, że nie ma możliwości wywołania metody klasy bazowej spoza obiektu).
Jednak w C ++ tak nie jest. Każda przeciążona metoda, niezależnie od tego, czy podpis jest taki sam, czy nie (różna ilość, inny typ) jest również zastępowana . To znaczy, że metoda klasy bazowej nie jest już dostępna w podklasie, kiedy jest wywoływana spoza obiektu podklasy, oczywiście.
Więc odpowiedź brzmi, gdy mówimy o przeciążeniu Java . W każdym innym języku może być inny, jak to się dzieje w c ++
źródło
Polimorfizm jest bardziej prawdopodobny, jeśli chodzi o jego znaczenie ... OVERRIDING w java
Chodzi o różne zachowanie obiektu SAME w różnych sytuacjach (w sposób programowania ... możesz wywoływać różne ARGUMENTY)
Myślę, że poniższy przykład pomoże ci zrozumieć ... Chociaż nie jest to czysty kod Java ...
Ale jeśli zmienimy ARGUMENT ... ZACHOWANIE zostanie zmienione ...
Osoba (tutaj „Obiekt”) jest taka sama ...
źródło
Polimorfizm to wiele implementacji obiektu lub można powiedzieć wiele form obiektu. Powiedzmy, że masz klasę
Animals
jako abstrakcyjną klasę podstawową i ma ona metodę o nazwie,movement()
która określa sposób poruszania się zwierzęcia. Teraz w rzeczywistości mamy różne rodzaje zwierząt i poruszają się one inaczej, niektóre z nich mają 2 nogi, inne z 4 i niektóre bez nóg itp. Aby zdefiniować różnemovement()
dla każdego zwierzęcia na ziemi, musimy zastosować polimorfizm. Musisz jednak zdefiniować więcej klas, tj. KlasDogs
Cats
Fish
itp. Następnie musisz rozszerzyć te klasy z klasy podstawowejAnimals
i zastąpić jej metodęmovement()
nową funkcją ruchu opartą na każdym zwierzęciu, które posiadasz. Możesz także użyćInterfaces
aby to osiągnąć. Słowo kluczowe tutaj jest nadrzędne, przeciążenie jest inne i nie jest uważane za polimorfizm. przy przeciążeniu możesz zdefiniować wiele metod „o tej samej nazwie”, ale o różnych parametrach w tym samym obiekcie lub klasie.źródło
Polimorfizm dotyczy zdolności języka do równomiernego traktowania różnych obiektów za pomocą pojedynczych interfejsów; jako taki jest związany z przesłonięciem, więc interfejs (lub klasa podstawowa) jest polimorficzny, implementator jest obiektem, który przesłania (dwie ściany tego samego medalu)
w każdym razie różnicę między tymi dwoma terminami lepiej wyjaśnić za pomocą innych języków, takich jak c ++: obiekt polimorficzny w c ++ zachowuje się jak odpowiednik java, jeśli funkcja podstawowa jest wirtualna, ale jeśli metoda nie jest wirtualna, skok kodu jest rozstrzygany statycznie , a prawdziwy typ nie jest sprawdzany w czasie wykonywania, więc polimorfizm obejmuje zdolność obiektu do zachowania się inaczej w zależności od interfejsu użytego do uzyskania do niego dostępu; dam przykład w pseudokodzie:
(zakładając, że makeRumor NIE jest wirtualny)
java tak naprawdę nie oferuje tego poziomu polimorfizmu (zwanego także krojeniem obiektów).
zwierzę a = nowy pies (); pies b = nowy pies ();
w obu przypadkach wypisuje tylko woff .. ponieważ aib odnosi się do psa klasy
źródło
źródło