Heim >Java >javaLernprogramm >JAVA-Polymorphismus von flach nach tief eingeführt

JAVA-Polymorphismus von flach nach tief eingeführt

高洛峰
高洛峰Original
2017-01-21 16:59:421179Durchsuche

Was ist Polymorphismus?

Polymorphismus wird in zwei Typen unterteilt:

(1) Polymorphismus zur Kompilierungszeit (Entwurfszeitpolymorphismus): Methodenüberladung.

(2) Laufzeitpolymorphismus: Das JAVA-Laufzeitsystem entscheidet, welche Methode aufgerufen werden soll, basierend auf dem Typ der Instanz, die die Methode aufruft, was als Laufzeitpolymorphismus bezeichnet wird. (Wir sprechen normalerweise viel über Laufzeitpolymorphismus, daher bezieht sich Polymorphismus hauptsächlich auf Laufzeitpolymorphismus)

Es gibt drei notwendige Bedingungen für die Existenz von Laufzeitpolymorphismus:
1 Es muss Vererbung vorliegen (Einschließlich der Implementierung von die Schnittstelle);
2. Umschreiben ist erforderlich
3. Die Referenz der übergeordneten Klasse verweist auf das untergeordnete Klassenobjekt.

---------------- ------ ------------------------------------

Ausführliche Erklärung :

Erläuterung des Laufzeitpolymorphismus: a. Der Laufzeitpolymorphismus bezieht sich auf den spezifischen Typ, auf den die im Programm definierte Referenzvariable zeigt, und b. Der über die Referenzvariable ausgegebene Methodenaufruf wird nicht beim Programmieren bestimmt, sondern wann Während dieser Zeit wird festgestellt, dass eine Referenzvariable auf ein Instanzobjekt zeigt, in welcher Klasse der von der Referenzvariable ausgegebene Methodenaufruf eine implementierte Methode ist. Dies muss während der Ausführung des Programms ermittelt werden .

1 .Der spezifische Typ, auf den die im Programm definierte Referenzvariable zeigt, ist ungewiss (d. h. auf welches Klasseninstanzobjekt eine Referenzvariable zeigt).

Beispiel:

Fahrmethode in der Fahrerklasse (Fahrzeugklasse Fahrzeug) {}

•oneDriver.drive( new car() )
•oneDriver.drive( new bus() )
Die Fahrzeugvariable kann nicht bestimmen, welche Unterklasseninstanz verwendet wird.

1. Der über die Referenzvariable ausgegebene Methodenaufruf wird während der Programmierung nicht bestimmt (der von der Referenzvariable ausgegebene Methodenaufruf ist eine Methode, die in welcher Klasse implementiert ist).

Beispiel: Die Cut-Methode des Kochs, Gärtners und Friseurs ruft .persion.cut() auf.

----------------- - ------------------------------------------------- - ----------

Vorteile des Polymorphismus:

1. Polymorphismus ermöglicht das Ersetzen von vorhandenem Code. Polymorphismus funktioniert beispielsweise für die Circle-Klasse, aber auch für jede andere kreisförmige Geometrie, beispielsweise einen Torus.

2. Erweiterbarkeit. Polymorphismus macht Code erweiterbar. Das Hinzufügen neuer Unterklassen hat keinen Einfluss auf den Polymorphismus, die Vererbung sowie den Betrieb und Betrieb anderer Funktionen vorhandener Klassen. Tatsächlich ist es einfacher, neue Unterklassen hinzuzufügen, um polymorphe Funktionen zu erhalten. Nachdem beispielsweise der Polymorphismus von Kegeln, Halbkegeln und Halbkugeln erkannt wurde, ist es einfach, den Polymorphismus der Kugelklasse hinzuzufügen.

3. Schnittstellenfähigkeit. Polymorphismus wird dadurch erreicht, dass die Oberklasse den Unterklassen durch Methodensignaturen eine gemeinsame Schnittstelle bereitstellt und die Unterklassen diese vervollständigen oder überschreiben. Wie in Abbildung 8.3 dargestellt. Die Superklasse Shape in der Abbildung gibt zwei Schnittstellenmethoden an, die Polymorphismus implementieren: ComputeArea() und ComputeVolume(). Unterklassen wie Circle und Sphere verbessern oder überschreiben diese beiden Schnittstellenmethoden, um Polymorphismus zu erreichen.

4. Flexibilität. Es verkörpert flexible und vielfältige Abläufe in Anwendungen und verbessert die Nutzungseffizienz.

5. Einfachheit. Polymorphismus vereinfacht den Code-Schreib- und Änderungsprozess von Anwendungssoftware. Diese Funktion ist besonders wichtig und wichtig, wenn es um Berechnungen und Operationen an einer großen Anzahl von Objekten geht.

Praktische Anwendung:

In Kombination mit der Verwendung von Konfigurationsdateien wenden Sie sich an das Spring-Framework, verwenden Sie Reflektion, rufen Sie Klassen dynamisch auf, ohne den Quellcode zu ändern, fügen Sie direkt neue Klassen hinzu und ändern Sie Konfigurationsdateien. keine Notwendigkeit. Das Programm kann durch einen Neustart des Servers erweitert werden.

---------------- ------ ------------------------------------

Zusammenfassung:

Verwenden Sie eine Referenz des übergeordneten Klassentyps, um auf das Objekt der Unterklasse zu verweisen. Die Variablen können nicht überschrieben (überschrieben) werden Die übergeordnete Klasse wird in der Unterklasse überschrieben. Wenn diese Methode aufgerufen wird, wird die Methode in der Unterklasse aufgerufen.

Beachten Sie die besonderen Umstände, wenn die Parameterliste der Methode von der übergeordneten Klasse aufgerufen wird Wenn sie nicht definiert ist, wird die übergeordnete Klasse aufgerufen, um sie zu finden. Wenn sie noch nicht gefunden wurde, wird die Konvertierung der Parametertypen in der Parameterliste erzwungen. Die spezifische Priorität ist wie folgt :

this.show(O), super.show(O), this.show( (super)O), super.show((super)O).

---------------- ------ ------------------------------------

Klassisch geschrieben Testfragen (gemischte Überladung und Umgeschrieben):

(1) Verwandte Klassen

class A {
         public String show(D obj)...{
                return ("A and D");
         } 
         public String show(A obj)...{
                return ("A and A");
         } 
} 
class B extends A{
         public String show(B obj)...{
                return ("B and B");
         }
         public String show(A obj)...{
                return ("B and A");
         } 
}
class C extends B...{} 
class D extends B...{}

(2) Frage: Was ist das folgende Ausgabeergebnis?

        A a1 = neues A();
        A a2 = neues B();
        B b = neues B();
        C c = neues C(); 
        D d = new D(); 
        System.out.println(a1.show(b));   ①
        System.out.println(a1.show(c));   ②
        System.out.println(a1.show(d));   ③
        System.out.println(a2.show(b));   ④
        System.out.println(a2.show(c));   ⑤
        System.out.println(a2.show(d));   ⑥
        System.out.println(b.show(b));     ⑦
        System.out.println(b.show(c));     ⑧
        System.out.println(b.show(d));     ⑨   

(三)答案

              ①   A und A
              ②   A und A
              ③   A und
              ④   B und A
              ⑤   B und A
              ⑥   A und D
              ⑦   B und B
             ⑧   B und B
              ⑨   A und. D

(四)分析

        ①②③比较好理解,一般不会出错。④⑤就有点糊涂了,为什么输出的不是„B and  运行时多态性是面向对象程序设计代码重用的一个最强大机制, 动态性的概念也可以被说成„一个接口,多个方法“.Java实现运行时多态性的基础是动态方法调度, 它是一种在运行时而不是在编译期调用重

        方法的重写Overriding和重载Overloading是Java多态性的不同表现.重写Overriding是父类与子类之间多态性的一种表现,重载Überlastung们说该方法被重写(Overriding)。子类的对象使用这个方法时将调用子类中的定义, 对它而言, 父类中的定义如同被“屏蔽”了.如果在一个类中定义了多个同名的方法, 它们或有不同的参数个数或有不同的参数类型,则称为方法的重载(Overloading)不同.

        当超类对象引用变量引用子类对象时但是这个被调用的方法必须是在超类中定义过的,也就是说被子类覆盖的方法. (但是如果强制把超类转换成子类的话,就可以调用子类中新添加而超类没有的方法了.)

       . 好了,先温习到这里,言归正传!实际上这里涉及方法调用的优先问题Sie haben die folgenden Optionen verwendet: this.show(O), super.show(O), this.show((super)O), super.show((super)O).是怎么工作的.

       于是它到类A里面找show(B. obj)方法,没有找到,于是到A的super(超类)找,而A没有超类,因此转到第三优先级this.show((super)O),this仍然是a2,这里O为B, (super)O即(super)B即A, 因此它到类A里面找show(A. obj)的方法, 类A有这个方法, 但是由于a2引用的是类B的个对象, B覆盖了A的show(A obj)方法,因此此最终锁定到类B的show(A obj),输出为„B and A“。

Ein weiteres Beispiel ist ⑧, b.show(c), b ist eine Referenzvariable vom Typ B, dann ist dies b und c ist eine Instanz von C, also geht es zu Klasse B, um das show(C obj) zu finden ) Methode, aber es gibt keine Found, dann gehen Sie zur Superklasse A von B, um danach zu suchen. In A gibt es so etwas nicht, also gehen wir auch zur dritten Prioritätsebene this.show((super)O), das ist b, O ist C, (super)O ist (super)C ist B, also sucht es in B nach der Methode show(B obj) und findet sie. Da b auf ein Objekt der Klasse B verweist, ist es direkt darauf gesperrt die show(B obj) der Klasse B, und die Ausgabe ist „B und B“.

Wenn Sie die oben beschriebene Methode befolgen, können Sie andere Ergebnisse korrekt erhalten.

Die Frage geht nun weiter. Schauen wir uns nun an, wie der obige Analyseprozess die Konnotation des Satzes in blauer Schrift widerspiegelt. Es heißt: Wenn eine Referenzvariable eines Oberklassenobjekts auf ein Unterklassenobjekt verweist, bestimmt der Typ des referenzierten Objekts und nicht der Typ der Referenzvariablen, welche Mitgliedsmethode aufgerufen wird, aber die aufgerufene Methode muss in der Oberklasse definiert sein , Methoden, die von Unterklassen überschrieben werden. Nehmen wir als Beispiel a2.show(b).

a2 ist eine Referenzvariable vom Typ A, die auf ein Objekt von B verweist. Dieser Satz bedeutet also, dass B entscheidet, welche Methode aufgerufen werden soll. Daher sollte show(B obj) von B aufgerufen werden, um „B und B“ auszugeben. Aber warum stimmt es nicht mit den Ergebnissen der vorherigen Analyse überein? ! Das Problem besteht darin, dass wir die zweite Hälfte der blauen Schriftart nicht ignorieren sollten, in der es ausdrücklich heißt: Die aufgerufene Methode muss in der Superklasse definiert sein, also eine Methode, die von der Unterklasse überschrieben wird. Ist show(B obj) in B in der Superklasse A definiert? NEIN! Ganz zu schweigen davon, dass man versichert ist. Tatsächlich verbirgt dieser Satz eine Botschaft: Er wird immer noch anhand der Priorität des Methodenaufrufs bestimmt. Es findet show(A obj) in Klasse A. Wenn die Unterklasse B die Methode show(A obj) nicht überschreibt, ruft sie show(A obj) von A auf (da B A erbt, obwohl diese Methode nicht überschrieben wird, ist diese Methode geerbt von Superklasse A. In gewisser Weise bestimmt B immer noch die aufzurufende Methode, aber die Methode ist in A implementiert. Jetzt überschreibt Unterklasse B show(A obj), sodass sie schließlich auf show(A obj) von B gesperrt wird. Das ist es, was diese Aussage bedeutet.

Weitere Artikel zum Thema JAVA-Polymorphismus, die von flach bis tief eingeführt werden, finden Sie auf der chinesischen PHP-Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn