Die Komplexität der Probleme, die Menschen lösen können, hängt von der Fähigkeit ab, Dinge zu abstrahieren Inwieweit.
Fortgeschrittene Mathematik und Physik sind höchst abstrakte Dinge. Sie werden auf dieser extrem abstrakten Ebene untersucht, und sobald sie große Fortschritte machen, werden sie einen großen Einfluss auf unser tägliches Leben haben. Zum Beispiel Einsteins Relativitätstheorie, deren Entdeckung einen großen Einfluss auf die Welt hatte. Das Gleiche gilt für die Programmierung. Je höher die Abstraktionsebene, desto präziser können wir sie beschreiben.
Alan Kay hat einmal die fünf Grundmerkmale von Smalltalk zusammengefasst, der ersten erfolgreichen objektorientierten Sprache und einer der Sprachen, auf denen Java basiert. Diese Merkmale stellen einen rein objektorientierten Designansatz dar. :
Alles ist ein Objekt
Ein Programm ist eine Sammlung von Objekten, die sich gegenseitig durch Senden mitteilen, was zu tun ist Nachrichten
Jedes Objekt hat seinen eigenen Speicher, der aus anderen Objekten besteht
Jedes Objekt hat seinen Typ
Alle Objekte eines bestimmten Typs können dieselbe Nachricht empfangen
Oder wir können Objekte prägnanter beschreiben: Objekte haben Status, Verhalten und Logos . Jedes Objekt verfügt über interne Daten, Methoden und eine eindeutige Adresse.
Alle Objekte sind einzigartig, weisen aber die gleichen Eigenschaften und Verhaltensweisen auf. Es gibt zum Beispiel viele Spatzen am Himmel, und jeder Spatz ist ein eigenständiges Individuum, aber diese Individuen sind alle Spatzen und sie haben alle die Eigenschaften von Spatzen.
Jedes Objekt ist ein Dienstanbieter, indem wir Methoden in diesem Objekt aufrufen und Variablen im Objekt verwenden. Objekte als Dienstleister zu betrachten, hat einen Nebeneffekt: Es trägt dazu bei, Objekte zusammenhängender zu machen. Hohe Kohäsion ist eine der grundlegenden Qualitätsanforderungen des Softwaredesigns, was bedeutet, dass eine Softwarestruktur gut organisiert ist. In dieser Klasse werden alle Methoden und Attribute für eine Funktion erstellt und sind sehr praktisch in der Anwendung. Aber eines der Probleme, mit denen wir täglich beim Entwerfen von Objekten konfrontiert sind, besteht darin, dass wir oft zu viele Funktionen in ein Objekt packen.
Bei einem guten objektorientierten Design erfüllt jedes Objekt eine Aufgabe gut und versucht nicht, mehr zu tun. Ein solches Design hat einen weiteren Vorteil: geringe Kopplung. Da jedes Objekt über seine eigenen hochkohäsiven Attributmethoden verfügt, sind sie alle dazu bestimmt, ihre eigenen „Dinge“ zu erledigen. Diese geringe Kopplung wird durch die Kombination ihrer jeweiligen Funktionen erreicht.
Im siebenschichtigen Modell der Computernetzwerkstruktur ist jede Schicht miteinander verbunden und schließlich abgeschlossen gesamte Netzwerkstruktur von den meisten virtuellen Computeroperationen bis zu den zugrunde liegenden elektronischen Schaltkreisoperationen. Zwischen ihren Schichten kann die obere Schicht nur die Schnittstelle der Methode der nächsten Schicht sehen. Sie kann nur wissen, wie die Methode der nächsten Schicht aufgerufen wird, ist jedoch nicht an der spezifischen Code-Implementierung der nächsten Schicht interessiert.
Im Java-Code werden drei Schlüsselwörter verwendet, um Grenzen in der Klasse festzulegen. Diese drei Zugriffsbezeichnungswörter bestimmen, wer den folgenden Inhalt verwenden kann:
public: Aktuelle Klasse Aktuelles Paket Nachkommen andere Pakete
geschützt: Aktuelle Klasse Aktuelles Paket Nachkommen
Standard (unverändert): Aktuelle Klasse Aktuelles Paket
privat: Aktueller Kurs
Die Wiederverwendung und Kombination von Code ist einer der erstaunlichsten Vorteile, die objektorientierte Programmiersprachen bieten.
Der einfachste Weg zur Wiederverwendung besteht darin, ein Objekt dieser Klasse direkt zu verwenden. Darüber hinaus können Sie ein Objekt dieser Klasse auch in eine neue Klasse einfügen. Wir nennen diese Wiederverwendungsmethode „Erstellen eines Mitgliedsobjekts“. Die neue Klasse kann aus einer beliebigen Anzahl anderer Objekte beliebiger Art auf jede Art und Weise zusammengesetzt werden, die die gewünschte Funktionalität in der neuen Klasse erreicht. Da Sie vorhandene Klassen verwenden, um neue Klassen zu synthetisieren, wird dieses Konzept Komposition genannt.
Wir stellen uns Kombination normalerweise als eine Beziehung vor – „hat-ein“.
Im Vergleich zu vielen Anfängern, die gerne Vererbungsbeziehungen in ihren eigenen Klassen verwenden, sollte beim Einrichten einer neuen Klasse tatsächlich zuerst die Komposition berücksichtigt werden, da sie flexibler ist. Wenn Sie diese Kombination verwenden, wird das Design klarer.
Wir werden nicht vorstellen, was Vererbung bedeutet. Es ist erwähnenswert, dass wir darüber nachdenken können, wie wir die übergeordnete Klasse im Projekt abstrahieren können Mehrere Unterklassen: Verwenden Sie mehrere Unterklassen, um herauszufinden, was sie gemeinsam haben. Dies ist für uns sehr hilfreich, um die übergeordnete Klasse zu abstrahieren.
Aufgrund der Vererbungsbeziehung können alle Nachrichten, die an Basisklassenobjekte gesendet werden können, auch an Unterklassenobjekte gesendet werden. Dies bedeutet, dass die -Unterklasse tatsächlich denselben Typ hat wie die übergeordnete Klasse . Wenn wir nur die übergeordnete Klasse erben und nur Methoden in der übergeordneten Klasse überschreiben, ohne neue Methoden zu erstellen, können wir dies als Reine Substitution bezeichnen. Für eine reine Substitution verwenden wir - „is-a“, um diese Beziehung auszudrücken. Für diejenigen, die nicht nur die übergeordnete Klasse erben, sondern auch neue Methoden basierend auf der übergeordneten Klasse hinzufügen, verwenden wir - „is-like-a“, um diese Beziehung auszudrücken.
Beim Umgang mit hierarchischen Strukturen behandeln wir ein Objekt oft nicht als spezifisches Objekt, sondern als ihre Elternklasse. Beispielsweise müssen wir in den Parametern der Methode zu diesem Zeitpunkt nicht unterscheiden, ob es sich um eine ArrayList oder eine LinkedList handelt. Dieser Polymorphismus bereichert das Programm erheblich.
Aber hier gibt es ein einfaches, aber schwer zu erklärendes Problem: Beispielsweise ruft die obige Methode die Add-Funktion auf, nachdem sie eine Liste übergeben hat. Woher weiß diese Methode, welche Add-Funktion für die übergebene Liste aufgerufen werden soll? ?
Die Antwort auf diese Frage ist gleichzeitig der wichtigste Tipp in der objektorientierten Programmierung: Der Compiler generiert keine Early-Bound-Funktionsaufrufe im herkömmlichen Sinne, sondern nutzt die Late-Binding-Methode. Ein von einem nicht objektorientierten Compiler generierter Funktionsaufruf führt zu einer sogenannten frühen Bindung. Diese Bindungsmethode bedeutet, dass der Compiler einen Aufruf mit einem bestimmten Funktionsnamen generiert und die Laufzeit ihn auflöst absolute Adresse des auszuführenden Codes. Um dieses Problem zu lösen, verwendet OOP das Konzept der späten Bindung. Beim Senden einer Nachricht an ein Objekt kann der aufgerufene Code erst zur Laufzeit ermittelt werden. Der Compiler stellt sicher, dass die aufgerufene Methode existiert und prüft die Rückgabewerte der Parameter, kennt jedoch nicht den genauen Code, der ausgeführt wird.
In C++ müssen Sie explizit über das Schlüsselwort virtual deklarieren, dass eine Methode die Flexibilität haben soll, die Late-Binding-Attribute mit sich bringen, was bedeutet, dass es sich standardmäßig nicht um Late-Binding handelt. In Java ist die dynamische Bindung das Standardverhalten.
In Java erben alle Klassen letztendlich von einer einzelnen Basisklasse, und diese Basisklasse ist Object. Es stellt sich heraus, dass die Single-Root-Vererbungsstruktur viele Vorteile mit sich bringt. Die Single-Root-Vererbung erleichtert die Implementierung eines Garbage Collectors erheblich. Da garantiert ist, dass alle Objekte ihre Typinformationen haben, gibt es keinen Deadlock aufgrund der Unfähigkeit, den Typ eines Objekts zu bestimmen.
Wenn man über die Erstellung und den Lebenszyklus von Objekten spricht, kommen einem viele Sprachen in den Sinn. Die Handhabung variiert. C++ glaubt, dass die Effizienzkontrolle das wichtigste Thema ist, daher gibt C++ Programmierern das Recht zu wählen. Sie können selbst neue erstellen, müssen jedoch den durch neue erstellten Speicherplatz löschen, da sonst das berühmte Problem des Speicherverlusts auftritt.
In Java werden alle Objekte dynamisch im Heap-Speicherpool erstellt. Bei diesem Ansatz wissen Sie erst zur Laufzeit, wie viele Objekte benötigt werden, welchen Lebenszyklus sie haben und welche spezifischen Typen sie haben. Solche Probleme können erst in dem Moment festgestellt werden, in dem der entsprechende Code ausgeführt wird, während das Programm läuft. Daher nimmt die Zuweisung von Speicherplatz im Heap viel Zeit in Anspruch, was möglicherweise viel länger dauert als die Zeit, die für die Erstellung von Speicherplatz im Stapel benötigt wird. Das Erstellen und Freigeben von Speicherplatz auf dem Stapel erfordert normalerweise nur eine einzige Anweisung. Die Zeit, die zum Erstellen eines Heap-Speichers benötigt wird, hängt vom Design des Speichermechanismus ab.
Ausnahme ist ein Objekt. Er wurde vom Punkt des Fehlers „geworfen“. und werden von entsprechenden Ausnahmehandlern „abgefangen“, die speziell für die Behandlung bestimmter Fehlertypen entwickelt wurden. Die Ausnahmebehandlung ist wie ein weiterer Pfad, der beim Auftreten eines Fehlers parallel zum normalen Ausführungspfad des Programms ausgeführt wird. Da es sich um einen völlig separaten Ausführungspfad handelt, beeinträchtigt er die normale Ausführung des Codes nicht.
Es ist erwähnenswert: Die Ausnahmebehandlung ist keine objektorientierte Funktion – obwohl die Ausnahmebehandlung in objektorientierten Sprachen häufig als Objekt dargestellt wird. Die Ausnahmebehandlung existierte bereits, bevor es objektorientierte Sprachen gab.
Das Obige ist die detaillierte Einführung in Java-Objekte. Weitere verwandte Inhalte finden Sie auf der chinesischen PHP-Website (www.php.cn)!