635 Stimmen

Können wir eine abstrakte Klasse instanziieren?

In einem meiner Interviews wurde ich gefragt: "Können wir eine abstrakte Klasse instanziieren?"

Meine Antwort war: "Nein, das können wir nicht". Aber der Interviewer sagte mir: "Falsch, wir können."

Ich habe ein wenig darüber gestritten. Dann sagte er mir, ich solle es zu Hause selbst versuchen.

abstract class my {
    public void mymethod() {
        System.out.print("Abstract");
    }
}

class poly {
    public static void main(String a[]) {
        my m = new my() {};
        m.mymethod();
    }
}

Hier erstelle ich eine Instanz meiner Klasse und rufe eine Methode der abstrakten Klasse auf. Kann mir das bitte jemand erklären? Habe ich mich bei meinem Vorstellungsgespräch wirklich geirrt?

787voto

Rohit Jain Punkte 207783

Hier erstelle ich eine Instanz meiner Klasse

Nein, Sie erstellen hier nicht die Instanz Ihrer abstrakten Klasse. Vielmehr erzeugen Sie eine Instanz einer anonyme Unterklasse Ihrer abstrakten Klasse. Und dann rufen Sie die Methode in Ihrer abstrakte Klasse Verweis auf Unterklassenobjekt .

Dieses Verhalten ist eindeutig aufgeführt in JLS - Abschnitt Nr. 15.9.1 : -

Wenn der Ausdruck zur Erzeugung der Klasseninstanz mit einer Klasse bo ist die zu instanzierende Klasse eine anonyme Klasse. Dann:

  • Wenn T eine Klasse bezeichnet, dann wird eine anonyme direkte Unterklasse der durch T bezeichneten Klasse deklariert. Es ist ein Kompilierzeitfehler, wenn die Klasse, die durch T bezeichnet wird, eine finale Klasse ist.
  • Wenn T eine Schnittstelle bezeichnet, dann wird eine anonyme direkte Unterklasse von Object deklariert, die die durch T bezeichnete Schnittstelle implementiert.
  • In beiden Fällen ist der Body der Unterklasse der ClassBody, der im Ausdruck zur Erzeugung der Klasseninstanz angegeben ist.
  • Die Klasse, die instanziiert wird, ist die anonyme Unterklasse.

Hervorhebung von mir.

Auch in JLS - Abschnitt # 12.5 können Sie sich über die Prozess der Objekterstellung . Ich möchte hier eine Aussage daraus zitieren: -

Jedes Mal, wenn eine neue Klasseninstanz erstellt wird, wird Speicherplatz zugewiesen Speicherplatz zugewiesen, der Platz für alle in der Klasse deklarierten Instanzvariablen deklarierten Instanzvariablen und alle Instanzvariablen, die in jeder Oberklasse der deklariert sind, einschließlich aller Instanzvariablen, die versteckt sein können.

Kurz bevor ein Verweis auf das neu erstellte Objekt zurückgegeben wird Ergebnis zurückgegeben wird, wird der angegebene Konstruktor verarbeitet, um das neue Objekts nach dem folgenden Verfahren zu initialisieren:

Das vollständige Verfahren können Sie unter dem von mir angegebenen Link nachlesen.


Um praktisch zu sehen, dass die Klasse, die instanziiert wird, eine Anonyme Unterklasse müssen Sie nur Ihre beiden Klassen kompilieren. Nehmen wir an, Sie haben diese Klassen in zwei verschiedenen Dateien abgelegt:

My.java:

abstract class My {
    public void myMethod() {
        System.out.print("Abstract");
    }
}

Poly.java:

class Poly extends My {
    public static void main(String a[]) {
        My m = new My() {};
        m.myMethod();
    }
}

Kompilieren Sie nun Ihre beiden Quelldateien:

javac My.java Poly.java

In dem Verzeichnis, in dem Sie den Quellcode kompiliert haben, finden Sie nun die folgenden Klassendateien:

My.class
Poly$1.class  // Class file corresponding to anonymous subclass
Poly.class

Sehen Sie diese Klasse - Poly$1.class . Es ist die vom Compiler erstellte Klassendatei, die der anonymen Unterklasse entspricht, die Sie mit dem unten stehenden Code instanziiert haben:

new My() {};

Es ist also klar, dass eine andere Klasse instanziiert wird. Es ist nur so, dass dieser Klasse erst nach der Kompilierung durch den Compiler ein Name gegeben wird.

Im Allgemeinen werden alle anonymen Unterklassen in Ihrer Klasse auf diese Weise benannt:

Poly$1.class, Poly$2.class, Poly$3.class, ... so on

Diese Nummern geben die Reihenfolge an, in der diese anonymen Klassen in der umgebenden Klasse erscheinen.

98voto

JB Nizet Punkte 654813

Das obige Beispiel instanziiert eine anonyme innere Klasse, die eine Unterklasse der my abstrakte Klasse. Das ist nicht unbedingt gleichbedeutend mit der Instanziierung der abstrakten Klasse selbst. Allerdings ist jede Instanz einer Unterklasse eine Instanz aller ihrer Oberklassen und Schnittstellen, so dass die meisten abstrakten Klassen tatsächlich durch die Instanziierung einer ihrer konkreten Unterklassen instanziiert werden.

Wenn der Interviewer einfach nur "falsch!" sagt, ohne dies zu erklären, und dieses Beispiel als einziges Gegenbeispiel anführt, denke ich, dass er nicht weiß, wovon er spricht.

92voto

Ioan Punkte 5142

= my() {}; bedeutet, dass es sich um eine anonyme Implementierung handelt, nicht um die einfache Instanziierung eines Objekts, die eigentlich : = my() . Sie können eine abstrakte Klasse niemals instanziieren.

31voto

ncenerar Punkte 1517

Das sind nur Beobachtungen, die Sie machen könnten:

  1. Pourquoi poly erweitert my ? Das ist nutzlos...
  2. Was ist das Ergebnis der Zusammenstellung? Drei Dateien: my.class , poly.class y poly$1.class
  3. Wenn wir eine abstrakte Klasse wie diese instanziieren können, können wir auch eine Schnittstelle instanziieren... komisch...

Können wir eine abstrakte Klasse instanziieren?

Nein, das können wir nicht. Was wir tun können, ist, eine anonyme Klasse zu erstellen (das ist die dritte Datei) und sie zu instanziieren.

Was ist mit der Instanziierung einer Superklasse?

Die abstrakte Superklasse wird nicht instanziiert durch us sondern durch Java.

EDIT: Bitten Sie ihn, dies zu testen

public static final void main(final String[] args) {
    final my m1 = new my() {
    };
    final my m2 = new my() {
    };
    System.out.println(m1 == m2);

    System.out.println(m1.getClass().toString());
    System.out.println(m2.getClass().toString());

}

Ausgabe ist:

false
class my$1
class my$2

20voto

Sie können in nur einer Zeile einfach antworten

Nein können Sie niemals eine abstrakte Klasse instanziieren.

Ist Ihr Gesprächspartner jedoch immer noch nicht einverstanden, können Sie ihm/ihr sagen

können Sie nur eine anonyme Klasse erstellen.

Und, laut Anonymous class, Klasse an der gleichen Stelle/Zeile deklariert und instanziiert

Es könnte also sein, dass Ihr Gesprächspartner daran interessiert ist, Ihr Selbstvertrauen und Ihr Wissen über die OOPs zu überprüfen.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X