Wie man einem 6-Jährigen objektorientierte Programmierkonzepte erklärt

Haben Sie bemerkt, dass bei Vorstellungsgesprächen immer wieder dieselben Klischeefragen gestellt werden - immer und immer wieder?

Ich bin sicher, Sie wissen, was ich meine.

Zum Beispiel:

Wo siehst du dich in fünf Jahren?

oder noch schlimmer:

Was ist für Sie die größte Schwäche?

Ugh ... gib mir eine Pause. Ich halte die Beantwortung dieser Frage für eine große Schwäche! Jedenfalls nicht mein Punkt.

So trivial Fragen wie diese auch sein mögen, sie sind wichtig, weil sie Hinweise auf Sie geben. Ihr aktueller Geisteszustand, Ihre Einstellung, Ihre Perspektive.

Bei der Beantwortung sollten Sie vorsichtig sein, da Sie möglicherweise etwas preisgeben, das Sie später bereuen.

Heute möchte ich über eine ähnliche Art von Frage in der Programmierwelt sprechen:

Was sind die Hauptprinzipien der objektorientierten Programmierung?

Ich war auf beiden Seiten dieser Frage. Es ist eines dieser Themen, das so oft gestellt wird, dass Sie sich nicht erlauben können, es nicht zu wissen.

Junior- und Einsteigerentwickler müssen dies normalerweise beantworten. Weil es für den Interviewer eine einfache Möglichkeit ist, drei Dinge zu sagen:

  1. Hat sich der Kandidat auf dieses Interview vorbereitet?

    Bonuspunkte, wenn Sie sofort eine Antwort hören - dies zeigt einen ernsthaften Ansatz.

  2. Ist der Kandidat nach der Tutorial-Phase?

    Das Verständnis der Prinzipien der objektorientierten Programmierung (OOP) zeigt, dass Sie über das Kopieren und Einfügen von Tutorials hinausgegangen sind - Sie sehen die Dinge bereits aus einer höheren Perspektive.

  3. Ist das Verständnis des Kandidaten tief oder flach?

    Das Kompetenzniveau in dieser Frage entspricht häufig dem Kompetenzniveau in den meisten anderen Fächern . Vertrau mir.

Die vier Prinzipien der objektorientierten Programmierung sind Kapselung , Abstraktion , Vererbung ,und Polymorphismus .

Diese Worte mögen für einen Junior-Entwickler beängstigend klingen. Und die komplexen, zu langen Erklärungen in Wikipedia verdoppeln manchmal die Verwirrung.

Deshalb möchte ich für jedes dieser Konzepte eine einfache, kurze und klare Erklärung geben. Es mag wie etwas klingen, das Sie einem Kind erklären, aber ich würde diese Antworten gerne hören, wenn ich ein Interview führe.

Verkapselung

Angenommen, wir haben ein Programm. Es gibt einige logisch unterschiedliche Objekte, die miteinander kommunizieren - gemäß den im Programm definierten Regeln.

Die Kapselung wird erreicht, wenn jedes Objekt seinen Status innerhalb einer Klasse privat hält . Andere Objekte haben keinen direkten Zugriff auf diesen Status. Stattdessen können sie nur eine Liste öffentlicher Funktionen aufrufen - sogenannte Methoden.

Das Objekt verwaltet also seinen eigenen Status über Methoden - und keine andere Klasse kann ihn berühren, es sei denn, dies ist ausdrücklich zulässig. Wenn Sie mit dem Objekt kommunizieren möchten, sollten Sie die bereitgestellten Methoden verwenden. Sie können den Status jedoch (standardmäßig) nicht ändern.

Nehmen wir an, wir bauen ein kleines Sims-Spiel. Es gibt Menschen und es gibt eine Katze. Sie kommunizieren miteinander. Wir möchten die Kapselung anwenden, also kapseln wir die gesamte "cat" -Logik in aCatKlasse. Es kann so aussehen:

Hier ist der "Zustand" der Katze die privaten Variablenmood , hungryund energy. Es hat auch eine private Methode meow(). Es kann es nennen, wann immer es will, die anderen Klassen können der Katze nicht sagen, wann sie miauen soll.

Was sie tun können, ist in den öffentlichen Methoden definiertsleep() , play()und feed(). Jeder von ihnen ändert den internen Status irgendwie und kann aufrufen meow(). Somit wird die Bindung zwischen dem privaten Staat und öffentlichen Methoden hergestellt.

Dies ist die Kapselung.

Abstraktion

Abstraktion kann als natürliche Erweiterung der Einkapselung angesehen werden.

Im objektorientierten Design sind Programme oft extrem groß. Und separate Objekte kommunizieren viel miteinander. Daher ist es schwierig, eine große Codebasis wie diese über Jahre hinweg aufrechtzuerhalten - mit Änderungen auf dem Weg.

Abstraktion ist ein Konzept, das dieses Problem lösen soll.

Das Anwenden von Abstraktion bedeutet, dass jedes Objekt nur einen allgemeinen Mechanismus für die Verwendung verfügbar machen sollte.

Dieser Mechanismus sollte interne Implementierungsdetails verbergen. Es sollten nur Operationen angezeigt werden, die für die anderen Objekte relevant sind.

Denken Sie - eine Kaffeemaschine. Es macht eine Menge Sachen und macht schrullige Geräusche unter der Haube. Aber alles, was Sie tun müssen, ist Kaffee einzulegen und einen Knopf zu drücken.

Vorzugsweise sollte dieser Mechanismus einfach zu verwenden sein und sich im Laufe der Zeit selten ändern. Stellen Sie sich das als eine kleine Menge öffentlicher Methoden vor, die jede andere Klasse aufrufen kann, ohne zu „wissen“, wie sie funktionieren.

Ein weiteres reales Beispiel für Abstraktion?

Überlegen Sie, wie Sie Ihr Telefon verwenden:

Sie interagieren mit Ihrem Telefon, indem Sie nur wenige Tasten verwenden. Was ist unter der Haube los? Sie müssen es nicht wissen - Implementierungsdetails sind ausgeblendet. Sie müssen nur eine kurze Reihe von Aktionen kennen.

Implementierungsänderungen - beispielsweise ein Software-Update - wirken sich selten auf die von Ihnen verwendete Abstraktion aus.

Erbe

OK, wir haben gesehen, wie Kapselung und Abstraktion uns helfen können, eine große Codebasis zu entwickeln und aufrechtzuerhalten.

Aber wissen Sie, was ein weiteres häufiges Problem beim OOP-Design ist?

Objekte sind oft sehr ähnlich. Sie teilen die gemeinsame Logik. Aber sie sind nicht ganz gleich. Pfui…

Wie können wir also die gemeinsame Logik wiederverwenden und die eindeutige Logik in eine separate Klasse extrahieren? Ein Weg, dies zu erreichen, ist die Vererbung.

Dies bedeutet, dass Sie eine (untergeordnete) Klasse erstellen, indem Sie von einer anderen (übergeordneten) Klasse ableiten. Auf diese Weise bilden wir eine Hierarchie.

Die untergeordnete Klasse verwendet alle Felder und Methoden der übergeordneten Klasse (gemeinsamer Teil) wieder und kann ihre eigenen (eindeutiger Teil) implementieren.

Zum Beispiel:

Wenn unser Programm öffentliche und private Lehrer, aber auch andere Arten von Menschen wie Schüler verwalten muss, können wir diese Klassenhierarchie implementieren.

Auf diese Weise fügt jede Klasse nur das hinzu, was für sie erforderlich ist, während die gemeinsame Logik mit den übergeordneten Klassen wiederverwendet wird.

Polymorphismus

Wir sind auf das komplexeste Wort gekommen! Polymorphismus bedeutet im Griechischen „viele Formen“.

Wir kennen also bereits die Macht der Vererbung und nutzen sie gerne. Aber da kommt dieses Problem.

Angenommen, wir haben eine Elternklasse und einige Kinderklassen, die davon erben. Manchmal möchten wir eine Sammlung verwenden - zum Beispiel eine Liste -, die eine Mischung all dieser Klassen enthält. Oder wir haben eine Methode für die Elternklasse implementiert - aber wir möchten sie auch für die Kinder verwenden.

Dies kann durch Verwendung von Polymorphismus gelöst werden.

Einfach ausgedrückt, bietet Polymorphismus die Möglichkeit, eine Klasse genau wie ihre übergeordnete Klasse zu verwenden, sodass keine Verwechslung mit dem Mischen von Typen besteht.Aber jede Kinderklasse behält ihre eigenen Methoden bei.

Dies geschieht normalerweise durch Definieren einer (übergeordneten) Schnittstelle, die wiederverwendet werden soll. Es werden einige gängige Methoden beschrieben. Anschließend implementiert jede untergeordnete Klasse eine eigene Version dieser Methoden.

Jedes Mal, wenn eine Sammlung (z. B. eine Liste) oder eine Methode eine Instanz des übergeordneten Elements erwartet (in der allgemeine Methoden beschrieben sind), sorgt die Sprache dafür, dass die richtige Implementierung der gemeinsamen Methode bewertet wird - unabhängig davon, welches Kind übergeben wird.

Schauen Sie sich eine Skizze der Implementierung geometrischer Figuren an. Sie verwenden eine gemeinsame Schnittstelle zur Berechnung der Oberfläche und des Umfangs:

Diese drei Figuren, die die Eltern erben Figure Interfacekönnen Sie eine Liste von gemischten erstellen triangles, circlesund rectangles. Und behandeln Sie sie wie den gleichen Objekttyp.

Wenn diese Liste dann versucht, die Oberfläche für ein Element zu berechnen, wird die richtige Methode gefunden und ausgeführt. Wenn das Element ein Dreieck ist, ist das DreieckCalculateSurface()wird genannt. Wenn es ein Kreis ist - dann CirlceCalculateSurface()wird genannt. Und so weiter.

Wenn Sie eine Funktion haben, die mit einer Figur unter Verwendung ihres Parameters arbeitet, müssen Sie sie nicht dreimal definieren - einmal für ein Dreieck, einen Kreis und ein Rechteck.

Sie können es einmal definieren und a akzeptieren Figureals Argument. Ob Sie ein Dreieck, einen Kreis oder ein Rechteck übergeben - solange sie implementiert werden CalculateParamter(), spielt ihr Typ keine Rolle.

Ich hoffe das hat geholfen. Sie können genau dieselben Erklärungen direkt bei Vorstellungsgesprächen verwenden.

Wenn Sie etwas immer noch schwer zu verstehen finden, zögern Sie nicht, in den Kommentaren unten zu fragen.

Was kommt als nächstes?

Es ist großartig, bereit zu sein, einen der Klassiker der Interviewfragen zu beantworten - aber manchmal wird man nie zu einem Interview gerufen.

Als nächstes werde ich mich darauf konzentrieren, was Arbeitgeber von einem Nachwuchsentwickler erwarten und wie sie sich bei der Jobsuche von der Masse abheben können.

Bleib dran.