it-swarm.com.de

Was ist der Unterschied zwischen Abstraktion und Polymorphismus?

Ich scheine zwei OOP Konzepte nicht sehr gut zu verstehen. Könnten Sie erklären, was Abstraktion und Polymorphismus sind, vorzugsweise mit realen Beispielen und Code?

Vielen Dank.

30
Sambath Prum

Abstraktion

Stellen Sie sich eine Bruchklasse vor:

class fraction:
    int denominator
    int numerator

Nun zwei Objekte davon:

fraction(obj1): denominator=-1 numerator=-1
fraction(obj2): denominator=1  numerator=1

Beide Objekte haben den Wert 1: (1/1) == (-1)/(-1). Sie würden nicht erwarten, dass sie sich nach außen anders verhalten. Das ist Abstraktion. Sie abstrahieren die Daten, die Ihr Objekt enthält, in eine logische Ansicht, selbst wenn sich hinter den Kulissen andere Dinge befinden. Theoretisch haben Sie eine Äquivalenzbeziehung mit verschiedenen Äquivalenzgruppen:

[1]=(1, 1), (-1, -1), (5, 5), ...
[2]=(2, 4), (-2, -4), ...
...

Und es gibt eine Abstraktionsfunktion, die die inneren Details nach außen abstrahiert:

f((1, 1)) = [1]
f((-1, -1)) = [1]

Es bildet von konkrete Werte den abstrakten Werten eines Objekts ab. Dazu schreiben Sie beispielsweise einen Konstruktor (-1, -1) in (1, 1) und schreiben eine Equals-Funktion für Ihre Klasse. 

Polymorphismus

Stellen Sie sich einen Stift und zwei abgeleitete Klassen vor:

class pen:
    void draw(int x, int y)

class pen_thin extends pen:
    void draw(int x, int y) { color(x, y) = green; }

class pen_thick extends pen:
    void draw(int x, int y) { color(x, y) = green; 
                              color(x, y+1) = green; }
and two objects:
    pen_thin(p1)
    pen_thick(p2)

Beide Stifte können zeichnen. Ihr allgemeiner "Stift" kann sich nicht selbst zeichnen. Es ist nur eine Schnittstelle zu pen_thin, pen_thick und vielen anderen Stiften. Sie sagen: obj1.draw (1, 0); Ob obj1 ein dicker oder dünner Stift ist, ist für Sie als Benutzer und den Compiler zur Kompilierzeit egal. Der Anruf verhält sich polymorph. Es ist dynamischer Polymorphismus (geschieht zur Laufzeit) und das ist, was die Leute normalerweise meinen. Statischer Polymorphismus geschieht zur Kompilierzeit:

class colorizer:
    void colorize(shirt s)
    void colorize(pants p)

Das nennt man Überladung. Sie rufen obj.colorize(something) an. Wenn Sie es mit einer Hemdreferenz aufrufen, wird die Version als Hemd bezeichnet. Und wenn Sie es mit einer Hosenreferenz aufrufen, wird die Hosenversion aufgerufen. Die hier getroffene Auswahl ist zur Kompilierzeit .

Diese beiden Merkmale gehören zu den wichtigsten Merkmalen des objektorientierten Paradigmas.

Abstraktion.

Die Objektorientierung modelliert die Software als Objekte der realen Welt. Es wäre jedoch zu schwierig (und nutzlos), ALLE Eigenschaften eines Kunden oder alle Eigenschaften eines Mitarbeiters zu modellieren. 

Durch Auflisten nur der interessanten Attribute eines Objekts kann OO dieses Objekt effektiv für eine bestimmte Domäne verwenden. Das ist Abstraktion.

Zum Beispiel kann ein Mitarbeiter in einem HR-System sehr andere Eigenschaften haben als ein Online-BookStore. Wir abstrahieren die Details, die nützlich sind.

Polymorphismus.

Objekte können sich je nach "Typ" unterschiedlich verhalten, wobei dieselbe Schnittstelle beibehalten wird. 

Was bedeutet das? 

Zum Beispiel kann ein Online-Shop-System zwei Unterklassen von Employee haben

A) Interne Mitarbeiter. 

B) Auftragnehmer 

Und eine Methode, um den Rabatt für interne Einkäufe zu berechnen 

Der Rabatt eines internen Mitarbeiters wird wie folgt berechnet: 10% + 2% für jedes Arbeitsjahr im Unternehmen + 2% für jedes .. mmhh-Kind 

Der Rabatt eines Auftragnehmers beträgt 10%

Der folgende Code zur Berechnung des zu zahlenden Betrags:

 public Amount getAmountToPay( Product product, Employee internalCustomer ) { 
      Amount amount = product.getPrice();
      amount.applyDiscount( internalCustomer.getDiscount() );
      return amount;
 }

Würde unterschiedliche Ergebnisse für die zwei verschiedenen Arten von Angestellten ergeben

class Employee { 
    public int getDiscount();
}


class InternalEmployee extends Employee { 
     public int getDiscount() { 
        return 10 + 2 * getWorkedYears() + 2 * getNumberOfChilds();
     }
 }

 class Contractor extends Employee { 
      public int getDiscount() { 
          return 10;
     }
 }

Dies ist der Polymorphismus in Aktion. Anstatt etwas zu haben

 Amount amount = product.getPrice();

 if( employee.isContractor() ) { 
      amount.applyDiscount( 10 );
 } else if( employee.isSomthingElse() ) {
      amount.applyDiscount( 10 * 2 * getYrs() + 2 * getChilds() );
 } else if ( employee.contidions, condigions, conditions ) {
      amount.applyDiscount( getSomeStrageRuleHere() );
 }

Wir lassen die Laufzeit wählen, welche berechnet werden soll. Ist wie das Programm verhält sich je nach Typ unterschiedlich:

      Amount amount = product.getPrice();
      amount.applyDiscount( internalCustomer.getDiscount() );
      return amount;

Übrigens, in diesem Beispiel ist "Amount" eine Abstraktion eines Konzepts des realen Lebens, das auch als Doppel- oder Integer-Zahl dargestellt werden kann. Vielleicht haben wir jedoch Interessensmethoden, die besser in ihrer eigenen Klasse wären.

Ich hoffe das hilft.

13
OscarRyz

Abstraktion und Polymorphismus sind kritische Begriffe, die keinesfalls auf OO beschränkt sind. Zusätzlich zur Verwirrung wird das Wort "Abstraktion" auf verschiedene Weise verwendet. Hier ist ein kurzer Spickzettel mit einem Beispiel:

  • Datenabstraktion bedeutet Ausblenden von Informationen. Verborgen ist normalerweise die Darstellung einer Datenstruktur. Beispiel: Ich implementiere Sets, aber ich sage Ihnen nicht, ob ein Set als Liste, ein ausgeglichener Binärbaum oder ein unsymmetrischer Binärbaum dargestellt wird. Richtig gemacht, Ich kann die Darstellung ändern, ohne Ihren Code zu beschädigen.

  • Polymorphismus bedeutet Wiederverwendung mit verschiedenen Typen. Bei meinem Set-Beispiel könnten Sie also Sätze von Sozialversicherungsnummern, Sätze von vollständigen Namen oder Sätze von Fruitbats erstellen, die alle denselben Code verwenden.

Natürlich können Sie eine Klasse definieren, die sowohl abstrakt als auch polymorph ist.

Polymorphismus ist weiter verwirrend, weil Polymorphismus kann auf zwei Arten implementiert werden. In parametrischer Polymorphismus können Sie die Menge mit den Werten von any type oder möglicherweise einem beliebigen Typ, der eine Einschränkung erfüllt, wiederverwenden. Die offensichtlichsten Beispiele sind C++ - Vorlagen; wenn du schreibst

class Set <T> { ... }

Dann ist T die Art der Objekte, die in der Menge enthalten sind (die Notation <T> zeigt einen sogenannten "Typparameter" an, was ihn zu parametrisch polymorphism macht).

In Untertyp Polymorphismus können Sets nur mit Objekten wiederverwendet werden, deren Typen Untertypen eines bestimmten Typs sind. Beispielsweise können Sie möglicherweise nur Sätze von Objekten erstellen, die eine Methode mit weniger als oder gleich bieten. In einer wahren objektorientierten Sprache wie Smalltalk oder Ruby, die sogenannte Duck Typing (uns Theoretiker mit Spitzkopf) manchmal Behavioral Subtyping anbieten, ist die Methode vorhanden gut genug. In einer Sprache wie Java oder C++, die Subtyping mit Vererbung zusammenfasst, kann der Polymorphismus beschränkt auf Unterklassen einer bestimmten Klasse sein. (Java verwirrt das Problem außerdem, indem eine Form der Untertypen für Klassen und eine andere für Schnittstellen verwendet wird.)

Schließlich sprechen alte Furzlinge wie ich über prozedurale Abstraktion, was nur bedeutet, eine Reihe von Anweisungen zu verwenden, die häufig zusammen verwendet werden, und diese in eine Prozedur oder Methode zu ploppieren, die Sie dann wiederverwenden können. Es ist wahrscheinlich nicht wichtig für deine Frage.

Fühlen Sie sich besser damit, verwirrt zu sein?

11
Norman Ramsey

Abstraktion bezieht sich auf das Darstellen wesentlicher Merkmale ohne Einbeziehung der Hintergrunddetails oder -erklärungen. Klassen verwenden das Konzept der Abstraktion und werden als Liste abstrakter Attribute definiert.

Ein Beispiel für eine Software-Abstraktion ist die Object.equals(Object o)-Methode von Java. Sie wissen, dass dieses Objekt mit dem als Parameter übergebenen Objekt verglichen wird, aber Sie wissen nicht, oder Sie müssen nicht genau wissen, wie das Objekt implementiert wird (es sei denn, Sie sind der Implementierer der Klasse).

Polymorphismus bedeutet die Fähigkeit, mehr als eine Form anzunehmen. Eine Methode kann in verschiedenen Fällen unterschiedliche Verhaltensweisen aufweisen. Das Verhalten hängt von den in der Operation verwendeten Datentypen ab.

Eines der klassischen Beispiele für Polymorphismus verwendet einen Vererbungsbaum, der in der Klasse Animal verwurzelt ist. Alle Animal's haben eine makeNoise()-Methode, aber die Dog-Klasse und die Cat-Klasse implementieren sie unterschiedlich. Auf diese Weise können Sie sich auf alle Hunde und Katzen beziehen, die einen Referenztyp für Tiere verwenden.

Animal a = new Dog();
Animal b = new Cat();

Jetzt können Sie makeNoise() für beide Animal-Instanzen aufrufen und wissen, dass das entsprechende Geräusch erzeugt wird. Dies ist besonders nützlich, wenn Sie über eine Sammlung von Tieren verfügen und zur Laufzeit nicht genau wissen, um welche Art von Tieren es sich tatsächlich handelt.

6
Bill the Lizard

Beide Begriffe werden in der objektorientierten Programmierung häufig verwendet, sind jedoch nicht speziell auf diesen Kontext beschränkt. 

Abstraktion ist eine Verallgemeinerung von etwas anderem; eine Stufe höher in der Perspektive. Eine Hierarchie kann zum Beispiel als Abstraktion der Organisationsstruktur eines Unternehmens betrachtet werden. Im Allgemeinen wird es in Zusammenhang mit den darunter liegenden Dingen verwendet (z. B. deren Basistypen). Der Punkt der Abstraktion ist, weniger Code zu schreiben, der allgemeiner ist, so dass Sie ihn für eine größere Anzahl von Problemen ausführen können. Eine Kalkulationstabelle ist zum Beispiel eine Abstraktion, die eine bestimmte Art der Informationsspeicherung ermöglicht. Mehr?

Polymorphismus ist auch eine Verallgemeinerung, die jedoch in einem Laufzeitkontext auftritt. Eine Reihe verschiedener Objekttypen sind polymorph, wenn es einen Weg gibt, auf sie zuzugreifen, wenn sie nicht voneinander zu unterscheiden sind. Das heißt, dass alle Objekte gleich aussehen und sich auch so anfühlen, auch wenn sie es nicht sind. Der Zweck ist, den Code erheblich zu reduzieren. Sie können eine verallgemeinerte Lösung schreiben, um das Speichern aller unterschiedlichen Permutationen für jeden unterschiedlichen Typ zu sparen. Wenn Sie eine Grafikbibliothek schreiben, schreiben Sie einfach abstrakten Code, um 'Shapes' zu verarbeiten. Dann müssen Sie Code für jeden unterschiedlichen Typ wie Kreise, Quadrate usw. schreiben.

Beides sind Begriffe, die sich auf Eigenschaften im Code konzentrieren, mit denen der Programmierer mit weniger mehr erreichen kann. Weniger Code hat weniger Fehler, ist stabiler und einfacher zu warten. Die Alternative ist die Verwendung von "roher Gewalt", um Millionen und Millionen von Zeilen mit sehr spezifischem (und sehr fragilem) Code herauszuschlagen. Es ist schwieriger, mehr Code zu reparieren, und es ist viel schwieriger, auf dem neuesten Stand zu bleiben.

Paul 

3
Paul W Homer

kurze antwort: abstraktion ist konzeptuell , polymorphismus ist verhalten

3
Steven A. Lowe

Abstraktion und Polymorphismus ähneln sich in der Natur mit einem anderen Zweck.

Für ex.

Führerschein : Sie erhalten einen Führerschein, in dem die Klasse der Fahrzeuge angegeben ist, die Sie fahren dürfen. In der Lizenz wird die von der Behörde zugelassene Fahrzeugklasse angegeben, es wird jedoch nicht festgelegt oder angegeben, welches bestimmte Fahrzeug oder welche Marke Sie fahren sollen. Das ist Abstraktion.

hier Lizenz ist eine Abstract-Klasse und ihre Methode, die erlaubte Fahrzeuge ist ihre Abstract-Methode .

Nun, hier ist Polymorphismus eine andere Art und Weise, wie eine individuelle Lizenz von der Behörde verschiedenen Personen zugeteilt wird. Einige werden für leichte Fahrzeuge ausgestellt, während einige für schwere und einige für Nutzfahrzeuge nach unterschiedlichen Anforderungen vergeben werden. Hier ist License eine Basisklasse und andere Arten von Lizenzen sind ihre Kinderklassen, die ebenfalls der ist-a-Beziehung gehorchen. Kommerzielle Lizenz ist eine Lizenz.

Abstraktion ist also eine allgemeine Richtlinie, die den Nachfolgerklassen Unabhängigkeit bei der Implementierung bietet, während Polymorphismus ein differenzierter Ansatz ist, der die von der Elternklasse festgelegten Methoden/Regeln überschreibt.

2
dhirwan

P.S: Vor kurzem habe ich angefangen, Java zu lernen. Antwort basiert auf meiner Beobachtung. Bitte korrigieren Sie mich, falls ich falsch liege. 

Grundsätzlich funktionieren Abstraktion und Polymorphismus in der Programmierung fast genauso. 

nehmen wir zum Beispiel ein Auto .. 

es ist egal, ob es sich um einen Ford-Minivan, einen Ferrari-Exoten, einen Land-Rover-SUV oder eine BMW-Limousine handelt. Sie alle folgen einem grundlegenden Design eines Autos, dh einem Motor, einem Lenkrad, einem Getriebe, Lichtern, Blinkern und Liste geht weiter. Was sie unterscheidet, ist ihre spezifische Implementierung, wie Ferrari einen stärkeren Motor als ein Mini-Van haben könnte, ein SUV könnte ein anderes Getriebe haben Daher wurde ein Auto (Superklasse hier) von Unterklassen (Limousine, suv, mini-van, exotisch) Dies ist Polymorphismus , eine Grundidee, die vererbt oder durch Hinzufügen anderer Spezifikationen implementiert wird. ein 4-Rad-Fahrzeug (Superklasse) wird in verschiedenen Formen (Unterklassen) implementiert

Nun, Abstraktion bedeutet definitionsgemäß, die Details zu verbergen und den Benutzer sehen zu lassen, was von ihm verlangt wird. 

Nehmen wir noch einmal ein Beispiel für ein Auto. Sie verwenden ein Getriebe, wissen jedoch nicht genau, wie genau das Getriebe funktioniert und wie schnell es läuft. 

Nun zum Coding Part.

Abstrakte Klassen sind unvollständige Klassen. Damit eine Klasse abstrakt ist, da der Name darauf hinweist, dass sie eine unvollständige Methode haben muss, die von der Unterklasse, die die Oberklasse erbt, vervollständigt werden muss .

abstract class car {
  abstract void gear();
}

class sedan extends car {
 public void gear()
 {
  //complete the method
 }
}

sie können auch keine Objekte abstrakter Klassen erstellen, da die Klasse nicht vollständig ist. Diese abstrakten Klassen können jedoch statische Methoden, Argumente und konkrete Methoden haben. ABER um abstrakt zu sein, benötigen sie eine abstrakte Methode. Eine grundlegende abstrakte Oberklasse ist also in anderen Unterklassen implementiert, wo sie diese vervollständigen Durch einen Blick auf die Methodendeklaration können wir abschätzen, was genau die Methode tut und was sie zurückgeben wird. Wir wissen jedoch nicht, wie genau die abstrakte Methode implementiert wird.

Durch die Verwendung abstrakter Klassen oder Schnittstellen können wir eine Abstraktion in Java erreichen. Da wir alle wissen, dass abstrakte Klassen enthalten, enthalten Schnittstellen abstrakte Methoden

Wir können nur abschätzen, wie sie funktionieren werden. Wir erfahren, wie sie funktionieren, sobald wir die Methodenimplementierung in den Klassen bereitgestellt haben, die die entsprechende abstrakte Klasse oder Schnittstelle implementieren.

HENCE hilft abstrakt Polymorphismus. 

0
Alok

Die Verwirrung über die tatsächliche Bedeutung der Abstraktion im Kontext der Objektorientierung ist nachvollziehbar: Sie fügt den Konzepten von Vererbung, Einkapselung und sogar Polymorphismus nur wenig hinzu. Wenn Sie diese drei Konzepte beherrschen, besteht kein Grund, sich zu sehr mit "Abstraktion" zu befassen, wenn sie von Natur aus in sie eingebettet ist (insbesondere Vererbung).

Beachten Sie zunächst, dass der Begriff "Abstraktion" mehrere Bedeutungen hat und es nicht falsch ist, beispielsweise anzugeben, dass die Verkapselung eine Abstraktion erfordert : wenn Sie verwenden Zugriffsmodifizierer, um die Attribute einer Klasse zu schützen, während die Methoden verfügbar gemacht werden, die mit ihnen umgehen (das ist die Kapselung). Der Benutzer der Klasse muss sich nicht mehr darum kümmern, wie er selbst mit ihnen umgeht. Wenn Sie also eine Klasse entwerfen, abstrahieren Sie , indem Sie Methoden und Attribute richtig kapseln - alles, was der Benutzer der Klasse tun muss, ist, sie zu verwenden durch Aufrufen der richtigen Methoden, und dies ist eine Form der Abstraktion.

Wenn Sie klar denken, ist Polymorphismus auch eine Form der Abstraktion : Ihr Code ruft eine von einer Klasse bereitgestellte Methode auf und Sie haben keine Ahnung, wie sie ist werde so lange handeln, bis der tatsächliche Klassentyp bestimmt ist (zur Laufzeit). Es ist also richtig festzustellen, dass das polymorphe Verhalten eine Art Abstraktion ist.

Wenn Abstraktion jedoch als eigenständiger Begriff zur Beschreibung der Merkmale von OOP verwendet wird, muss dies als die ordnungsgemäße Darstellung des diskutierten Systems in Form einer geeigneten Klassenhierarchie verstanden werden. Als solches ist Abstraktion das Ergebnis der mentalen Prozesse des Designers, die in einem geeigneten Design für die Klassen gipfeln, die in einem Programm verwendet werden sollen. Um einen (ausgezeichneten!) Beitrag zu zitieren der im javarevisited-Blog zu finden ist :

... Abstraktion verbirgt Details auf Entwurfsebene, während Kapselung Details auf Implementierungsebene verbirgt.

Während die obige Aussage korrekt ist, finde ich den Teil "Details ausblenden" falsch angegeben - ich würde es als so etwas wie umformulieren

Die Abstraktion befasst sich mit Designdetails und entscheidet, wie die Klassenhierarchie aussehen soll. Die Kapselung verbirgt die Implementierung von Details .

Um fair mit dem Autor zu sein, genau diese Idee passt wunderbar zu seinem Artikel. Der Begriff "Abstraktion" mit dieser Konnotation kommt auch in guten Büchern wie Head First Object-Oriented Analysis and Design vor, und ich zitiere eine Aussage von dort:

Wenn Sie an zwei oder mehr Stellen ein gemeinsames Verhalten feststellen, sollten Sie dieses Verhalten in eine Klasse abstrahieren und dann in den gemeinsamen Klassen wiederverwenden

Beachten Sie die Verwendung der Abstraktion hier: " Schauen Sie, um dieses Verhalten in eine Klasse zu abstrahieren". Wenn zu abstrakt bedeutet , eine Klassenhierarchie wie vorgeschlagen richtig zu entwerfen oben könnte Abstraktion definiert werden als die Darstellung einer Domäne durch bequeme Verwendung von Klassen, wobei die Konzepte der Vererbung und Kapselung ausgenutzt werden.

Im speziellen Fall von Java wird die Abstraktion mithilfe von Interfaces und abstrakte Klassen implementiert, während die Kapselung mit den Modifikatoren private, protected und package access implementiert wird .

Einfach ausgedrückt ist Abstraktion konzeptuell und Poly ist Verhalten. Um eine Abstraktion in OOP zu erreichen, benötigen Sie Poly. 

Abstraktion in der objektorientierten Programmierung ist ein Konzept oder Entwurfsmuster, das ich sagen kann, was eine bessere Isolierung, lose Kopplung und damit Testbarkeit sowie Wiederverwendbarkeit und Erweiterbarkeit ermöglicht. Um alles zu erreichen, benötigen wir Poly, Vererbung/Erweiterung usw. 

0