Java-Interview: Fragen zu OOP
1. Was sind die Merkmale von Java?
Antworten:-
OOP-Konzepte:
- Objektorientierung
- Nachlass
- Verkapselung
- Polymorphismus
- Abstraktion
-
Plattformübergreifend: Ein Java-Programm kann ohne Änderungen auf jeder Plattform ausgeführt werden. Voraussetzung hierfür ist natürlich eine installierte JVM (Java Virtual Machine).
-
Hohe Leistung: Der Just-In-Time (JIT)-Compiler ermöglicht eine hohe Leistung. Der JIT-Compiler wandelt den Bytecode in Maschinencode um und dann beginnt die JVM mit der Ausführung.
- Multithreading: Die JVM erstellt einen Ausführungsthread namens
main thread
. Ein Programmierer kann mehrere Threads erstellen, indem er von der Thread-Klasse ableitet oder dieRunnable
Schnittstelle implementiert.
2. Was ist Vererbung?
Vererbung bedeutet, dass eine Klasse eine andere Klasse erben kann (mithilfe des Schlüsselworts „extends“ ). Das bedeutet, dass Sie Code aus der von Ihnen geerbten Klasse wiederverwenden können. Die vorhandene Klasse heißt „superclass
und die neu erstellte Klasse heißt „ subclass
. Man sagt auch, dass man die Begriffe „Elternteil“ und „verwendet“ child
.
public class Animal {
private int age;
}
public class Dog extends Animal {
}
wo Animal
ist das parent
und Dog
ist das child
.
3. Was ist Kapselung?
Diese Frage wird häufig in Vorstellungsgesprächen für Java-Entwicklerpositionen gestellt. Bei der Kapselung wird die Implementierung durch die Verwendung von Zugriffsmodifikatoren, Gettern und Settern ausgeblendet. Dies geschieht, um externe Zugriffe dort zu verhindern, wo Entwickler dies für notwendig halten. Ein einfaches Beispiel aus dem wirklichen Leben ist das Auto. Wir haben keinen direkten Zugriff auf den Betrieb des Motors. Alles, was wir tun müssen, ist, den Schlüssel ins Zündschloss zu stecken und den Motor anzustellen. Die Prozesse, die unter der Haube ablaufen, gehen uns nichts an. Darüber hinaus könnte ein Eingriff in die Motoraktivität zu einer unvorhersehbaren Situation führen, die möglicherweise zu Schäden am Fahrzeug und zu Körperverletzungen führen könnte. Genau das Gleiche passiert beim Programmieren. Dies ist auf Wikipedia gut beschrieben. Es gibt auch einen Artikel über Kapselung auf CodeGym .4. Was ist Polymorphismus?
Unter Polymorphismus versteht man die Fähigkeit eines Programms, Objekte mit derselben Schnittstelle auf die gleiche Weise zu behandeln, ohne Informationen über den spezifischen Typ des Objekts zu benötigen. Wie das Sprichwort sagt: „Eine Schnittstelle – viele Implementierungen“. Mit Polymorphismus können Sie verschiedene Objekttypen basierend auf gemeinsamen Verhaltensweisen kombinieren und verwenden. Zum Beispiel haben wir eine Animal-Klasse, die zwei Nachkommen hat: Dog und Cat. Die generische Animal-Klasse verfügt über ein Verhalten, das allen gemeinsam ist: die Fähigkeit, einen Ton zu erzeugen. Wir verwenden polymorphe Fähigkeiten, wenn wir alles sammeln müssen, was die Animal-Klasse erbt, und die Methode „make sound“ ausführen müssen. So sieht es aus:
List<Animal> animals = Arrays.asList(new Cat(), new Dog(), new Cat());
animals.forEach(animal -> animal.makeSound());
Mit anderen Worten: Polymorphismus ist hilfreich. Und das gilt auch für polymorphe (überladene) Methoden. Wie man Polymorphismus verwendet
Interviewfragen zur Java-Syntax
5. Was ist ein Konstruktor in Java?
Konstruktoren haben die folgenden Eigenschaften:- Wenn ein neues Objekt erstellt wird, verwendet das Programm den entsprechenden Konstruktor, um es zu erstellen.
- Ein Konstruktor ist wie eine Methode. Seine Besonderheiten liegen darin, dass es keinen Rückgabewert (einschließlich void) gibt und dass sein Name mit dem Namen der Klasse übereinstimmt.
- Wenn kein Konstruktor explizit erstellt wird, wird automatisch ein leerer Konstruktor erstellt.
- Ein Konstruktor kann überschrieben werden.
- Wenn Sie einen Konstruktor mit Parametern deklarieren, aber auch einen ohne Parameter benötigen, müssen Sie ihn separat erstellen, da er nicht automatisch erstellt wird.
6. Welche beiden Klassen erben Object nicht?
Lassen Sie sich nicht von Trickfragen täuschen – solche Kurse gibt es nicht. Alle Klassen erben die Object-Klasse entweder direkt oder über Vorfahren!7. Was ist eine lokale Variable?
Dies ist eine weitere beliebte Interviewfrage für Java-Entwickler. Eine lokale Variable ist eine Variable, die innerhalb einer Methode definiert ist und solange existiert, wie die Methode ausgeführt wird. Sobald die Ausführung beendet ist, hört die lokale Variable auf zu existieren. Hier ist ein Programm, das eine lokale Variable namens helloMessage in der main()-Methode verwendet:
public static void main(String[] args) {
String helloMessage;
helloMessage = "Hello, World!";
System.out.println(helloMessage);
}
8. Was ist eine Instanzvariable?
Eine Instanzvariable ist eine Variable, die innerhalb einer Klasse deklariert wird. Es existiert, solange ein Objekt existiert. Wir haben zum Beispiel eine Bee-Klasse, die zwei Instanzvariablen hat – nectarLoad und maxNectarLoad:
public class Bee {
/**
* Current nectar load
*/
private double nectarLoad;
/**
* Maximum nectar that can the bee can collect.
*/
private double maxNectarLoad = 20.0;
...
}
9. Was sind Zugriffsmodifikatoren?
Zugriffsmodifikatoren sind ein Mechanismus zum Anpassen des Zugriffs auf Klassen, Methoden und Variablen. Es gibt die folgenden Modifikatoren, aufgelistet in der Reihenfolge des zunehmenden Zugriffs:private
– Dieser Zugriffsmodifikator wird für Methoden, Felder und Konstruktoren verwendet. Der Zugriff ist auf die Klasse beschränkt, in der sie deklariert sind.package-private (default)
– Dies ist die Standardzugriffsebene für Klassen. Der Zugriff ist auf das spezifische Paket beschränkt, in dem eine Klasse, Methode, Variable oder ein Konstruktor deklariert ist.protected
– Dieser Zugriffsmodifikator bietet die gleiche Zugriffsebene wiepackage-private
mit dem zusätzlichen Zugriff für Klassen, die eine Klasse mit demprotected
Modifikator erben.public
— Diese Zugriffsebene wird auch für Klassen verwendet. Diese Zugriffsebene bedeutet, dass in der gesamten Anwendung vollständiger Zugriff besteht.
10. Was ist Methodenüberschreibung?
Wir überschreiben Methoden, wenn eine untergeordnete Klasse das Verhalten ihrer übergeordneten Klasse ändern möchte. Wenn wir auch das tun müssen, was in der übergeordneten Methode enthalten ist, können wir super.methodName() in der untergeordneten Methode verwenden, wodurch die übergeordnete Methode ausgeführt wird. Danach können wir unsere zusätzliche Logik hinzufügen. Zu beachtende Anforderungen:- Die Methodensignatur muss identisch sein
- Der Rückgabewert muss gleich sein
11. Was sind Methodensignaturen?
Eine Methodensignatur ist die Kombination aus dem Methodennamen und den Argumenten, die die Methode akzeptiert. Die Methodensignatur ist die eindeutige Kennung einer Methode beim Überladen von Methoden.12. Was ist Methodenüberladung?
Das Überladen von Methoden ist ein Merkmal des Polymorphismus, bei dem wir die Methodensignatur ändern, um mehrere Methoden zu erstellen, die dieselbe Aktion ausführen:- der selbe Name
- verschiedene Argumente
- Es kann verschiedene Rückgabetypen geben
ArrayList
der Klasse add()
überladen werden, sodass wir abhängig von den Eingabeargumenten auf unterschiedliche Weise etwas hinzufügen können:
add(Object o)
– Diese Methode fügt einfach ein Objekt hinzuadd(int index, Object o)
– Diese Methode fügt ein Objekt an einem bestimmten Index hinzuadd(Collection<Object> c)
– Diese Methode fügt eine Liste von Objekten hinzuadd(int index, Collection<Object> c)
– Diese Methode fügt eine Liste von Objekten hinzu, beginnend mit einem bestimmten Index.
13. Was ist eine Schnittstelle?
Java unterstützt keine Mehrfachvererbung. Um diese Einschränkung zu überwinden, wurden Schnittstellen in der Form hinzugefügt, die wir kennen und lieben ;) Lange Zeit verfügten Schnittstellen nur über Methoden ohne jegliche Implementierung. Lassen Sie uns im Kontext dieser Antwort darüber sprechen. Zum Beispiel:
public interface Animal {
void makeSound();
void eat();
void sleep();
}
Daraus ergeben sich einige Details:
- Alle Methoden in einer Schnittstelle sind öffentlich und abstrakt
- Alle Variablen sind öffentliche, statische Endvariablen
- Klassen erben keine Schnittstellen (dh wir verwenden nicht das Schlüsselwort „extens“). Stattdessen werden sie von Klassen implementiert (dh wir verwenden das Schlüsselwort „implements“). Darüber hinaus können Sie beliebig viele Schnittstellen implementieren.
- Klassen, die eine Schnittstelle implementieren, müssen eine Implementierung aller in der Schnittstelle enthaltenen Methoden bereitstellen.
public class Cat implements Animal {
public void makeSound() {
// Method implementation
}
public void eat() {
// Implementation
}
public void sleep() {
// Implementation
}
}
14. Was ist eine Standardmethode in einer Schnittstelle?
Lassen Sie uns nun über Standardmethoden sprechen. Wozu dienen sie? Für wen sind die? Diese Methoden wurden hinzugefügt, um „beide Hände“ zu bedienen. Wovon rede ich? Nun, einerseits bestand die Notwendigkeit, neue Funktionen hinzuzufügen: Lambdas und die Stream-API. Andererseits war es notwendig, das beizubehalten, wofür Java berühmt ist – die Abwärtskompatibilität. Dazu benötigte Interfaces einige neue vorgefertigte Lösungen. So kamen Standardmethoden zu uns. Eine Standardmethode ist eine implementierte Methode in einer Schnittstelle, die mit demdefault
Schlüsselwort gekennzeichnet ist. Zum Beispiel die bekannte stream()
Methode in der Collection
Schnittstelle. Glauben Sie mir, diese Schnittstelle ist nicht so einfach, wie es scheint. Oder auch die ebenso berühmte forEach()
Methode imIterable
Schnittstelle. Es existierte auch nicht, bis die Standardmethoden hinzugefügt wurden. Übrigens können Sie hier auch auf CodeGym darüber lesen .
15. Wie erben wir dann zwei identische Standardmethoden?
Die vorherige Antwort darauf, was eine Standardmethode ist, wirft eine andere Frage auf. Wenn Sie Methoden in Schnittstellen implementieren können, können Sie theoretisch zwei Schnittstellen mit derselben Methode implementieren. Wie machen wir das? Hier sind zwei verschiedene Schnittstellen mit derselben Methode:
interface A {
default void foo() {
System.out.println("Foo A");
}
}
interface B {
default void foo() {
System.out.println("Foo B");
}
}
Und wir haben eine Klasse, die diese beiden Schnittstellen implementiert. Aber wie wählen wir eine bestimmte Methode in Schnittstelle A oder B aus? Das folgende spezielle Konstrukt ermöglicht dies: A.super.foo()
:
public class C implements A, B {
public void fooA() {
A.super.foo();
}
public void fooB() {
B.super.foo();
}
}
Daher fooA()
verwendet die Methode die Standardmethode foo()
der A
Schnittstelle, während die Methode die Methode der Schnittstelle fooB()
verwendet . foo()
B
16. Was sind abstrakte Methoden und Klassen?
In Javaabstract
ist es ein reserviertes Wort. Es wird zur Bezeichnung abstrakter Klassen und Methoden verwendet. Zuerst brauchen wir Definitionen. abstract
Eine abstrakte Methode ist eine Methode, die mit dem Schlüsselwort ohne Implementierung in einer abstrakten Klasse deklariert wird . Das heißt, es handelt sich um eine Methode wie in einer Schnittstelle, jedoch mit dem Zusatz eines Schlüsselworts, zum Beispiel:
public abstract void foo();
Eine abstrakte Klasse ist eine Klasse, die auch mit dem abstract
Schlüsselwort gekennzeichnet ist:
public abstract class A {
}
Eine abstrakte Klasse verfügt über mehrere Funktionen:
- Sie können kein Objekt einer abstrakten Klasse erstellen
- es kann abstrakte Methoden haben
- Möglicherweise gibt es auch keine abstrakten Methoden
17. Was ist der Unterschied zwischen String, StringBuilder und StringBuffer?
String
Werte werden in einem konstanten String-Pool gespeichert. Sobald ein String erstellt wird, erscheint er in diesem Pool. Und Sie können es nicht löschen. Zum Beispiel:
String name = "book";
Die Variable zeigt auf den konstanten String-Pool. Wenn wir die Namensvariable auf einen anderen Wert setzen, haben wir:
name = "pen";
Der Konstanten-String-Pool sieht so aus: Mit anderen Worten, beide Werte bleiben dort. String-Puffer:
String
Werte werden in einem Stapel gespeichert. Wenn ein Wert geändert wird, ersetzt der neue Wert den alten.String Buffer
ist synchronisiert und daher threadsicher.- Aufgrund der Thread-Sicherheit ist die Leistung schlecht.
StringBuffer name = “book”;
Sobald sich der Wert der Namensvariablen ändert, ändert sich auch der Wert im Stapel: StringBuilder ist genau das Gleiche wie StringBuffer
, nur dass es nicht Thread-sicher ist. Dadurch ist es deutlich schneller als StringBuffer
.
18. Was ist der Unterschied zwischen einer abstrakten Klasse und einer Schnittstelle?
Abstrakte Klasse:- Abstrakte Klassen haben einen Standardkonstruktor. Es wird jedes Mal aufgerufen, wenn ein Nachkomme der abstrakten Klasse erstellt wird.
- Sie können sowohl abstrakte als auch nicht abstrakte Methoden umfassen. Im Allgemeinen muss eine abstrakte Klasse keine abstrakten Methoden haben.
- Eine Klasse, die eine abstrakte Klasse erbt, darf nur abstrakte Methoden implementieren.
- Eine abstrakte Klasse kann Instanzvariablen haben (siehe Frage Nr. 5).
- Eine Schnittstelle hat keinen Konstruktor und kann nicht initialisiert werden.
- Es können nur abstrakte Methoden hinzugefügt werden (außer Standardmethoden).
- Klassen, die die Schnittstelle implementieren, müssen alle Methoden implementieren (außer Standardmethoden).
- Schnittstellen können nur Konstanten haben.
19. Warum ist der Zugriff auf ein Element in einem Array O(1)?
Diese Frage wurde mir in meinem letzten Interview wörtlich gestellt. Wie ich später erfuhr, besteht der Zweck dieser Frage darin, herauszufinden, wie eine Person denkt. Offensichtlich hat dieses Wissen wenig praktischen Nutzen. Es genügt, es zu wissen. Zunächst müssen wir klarstellen, dass O(1) eine Notation für die Zeitkomplexität eines Algorithmus mit „konstanter Zeit“ ist. Mit anderen Worten: Diese Bezeichnung gibt die schnellste Ausführungszeit an. Um diese Frage zu beantworten, müssen wir berücksichtigen, was wir über Arrays wissen. Um einint
Array zu erstellen, müssen wir Folgendes schreiben:
int[] intArray = new int[100];
Aus dieser Syntax lassen sich mehrere Schlussfolgerungen ziehen:
- Wenn ein Array deklariert wird, ist sein Typ bekannt. Wenn der Typ bekannt ist, ist auch die Größe jeder Zelle im Array bekannt.
- Die Größe des gesamten Arrays ist bekannt.
Wie kommen wir also zu O(1), wenn wir auf Objekte in einer ArrayList zugreifen?
Diese Frage folgt unmittelbar auf die vorherige. Die Wahrheit ist, dass wir bei der Arbeit mit einem Array, das Grundelemente enthält, im Voraus (zum Zeitpunkt der Erstellung) die Größe des Elementtyps kennen. Aber was machen wir, wenn wir eine solche Vererbungshierarchie haben und eine Sammlung für Elemente vom Typ A erstellen und verschiedene Implementierungen (B, C und D) hinzufügen möchten:
List<A> list = new ArrayList();
list.add(new B());
list.add(new C());
list.add(new D());
list.add(new B());
Wie berechnen wir in dieser Situation die Größe jeder Zelle? Schließlich wird jedes Objekt anders sein, möglicherweise mit unterschiedlichen Zusatzfeldern. Was zu tun ist? Hier ist die Frage auf eine Weise gestellt, die Sie verwirren soll. Wir wissen, dass die Sammlung Objekte nicht direkt speichert. Es speichert nur Verweise auf Objekte. Und alle Referenzen haben die gleiche Größe und es ist bekannt. Daher berechnen wir hier Adressen auf die gleiche Weise wie in der vorherigen Frage.
21. Autoboxing und Unboxing
Historischer Hintergrund: Autoboxing und Unboxing sind einige der wichtigsten Neuerungen in JDK 5. Autoboxing ist der Prozess der automatischen Konvertierung von einem primitiven Typ in eine entsprechende Wrapper-Klasse. Unboxing ist das genaue Gegenteil von Autoboxing. Dabei handelt es sich um den Prozess der Konvertierung einer Wrapper-Klasse in ein Grundelement. Wenn der Wert eines Wrappers jedoch istnull
, NullPointerException
wird beim Unboxing ein geworfen.
Primitive und ihre entsprechenden Wrapper
Primitive | Wrapper-Klasse |
---|---|
Boolescher Wert | Boolescher Wert |
int | Ganze Zahl |
Byte | Byte |
verkohlen | Charakter |
schweben | Schweben |
lang | Lang |
kurz | Kurz |
doppelt | Doppelt |
// Autoboxing passiert:
-
beim Zuweisen eines Grundelements zu einer Referenz auf eine Wrapper-Klasse:
VOR Java 5:
// Manual boxing (the way it was BEFORE Java 5). public void boxingBeforeJava5() { Boolean booleanBox = new Boolean(true); Integer intBox = new Integer(3); // And so on for other types } After Java 5: // Automatic boxing (the way it became in Java 5). public void boxingJava5() { Boolean booleanBox = true; Integer intBox = 3; // And so on for other types }
-
wenn ein Grundelement als Argument an eine Methode übergeben wird, die einen Wrapper erwartet:
public void exampleOfAutoboxing() { long age = 3; setAge(age); } public void setAge(Long age) { this.age = age; }
// Das Auspacken erfolgt:
-
wenn wir einer primitiven Variablen eine Instanz einer Wrapper-Klasse zuweisen:
// BEFORE Java 5: int intValue = new Integer(4).intValue(); double doubleValue = new Double(2.3).doubleValue(); char c = new Character((char) 3).charValue(); boolean b = Boolean.TRUE.booleanValue(); // And after JDK 5: int intValue = new Integer(4); double doubleValue = new Double(2.3); char c = new Character((char) 3); boolean b = Boolean.TRUE;
-
Bei arithmetischen Operationen. Die Operationen gelten nur für Grundtypen, daher ist ein Auspacken für Grundtypen erforderlich.
// BEFORE Java 5: Integer integerBox1 = new Integer(1); Integer integerBox2 = new Integer(2); // A comparison used to require this: integerBox1.intValue() > integerBox2.intValue() // In Java 5 integerBox1 > integerBox2
-
wenn eine Instanz einer Wrapper-Klasse an eine Methode übergeben wird, die das entsprechende Grundelement annimmt:
public void exampleOfAutoboxing() { Long age = new Long(3); setAge(age); } public void setAge(long age) { this.age = age; }
22. Was ist das letzte Schlüsselwort und wo wird es verwendet?
Dasfinal
Schlüsselwort kann für Variablen, Methoden und Klassen verwendet werden.
- Der Wert einer endgültigen Variablen kann nach der Initialisierung nicht mehr geändert werden.
- Eine Abschlussklasse ist steril :) Sie kann keine Kinder haben.
- Eine finale Methode kann nicht von einem Nachkommen überschrieben werden.
Endgültige Variablen
Java bietet uns zwei Möglichkeiten, eine Variable zu deklarieren und ihr einen Wert zuzuweisen:- Sie können eine Variable deklarieren und später initialisieren.
- Sie können eine Variable deklarieren und sofort einen Wert zuweisen.
public class FinalExample {
// A static final variable that is immediately initialized:
final static String FINAL_EXAMPLE_NAME = "I'm likely the final one";
// A final variable that is not initialized, but will only work if you
// initialize it in the constructor:
final long creationTime;
public FinalExample() {
this.creationTime = System.currentTimeMillis();
}
public static void main(String[] args) {
FinalExample finalExample = new FinalExample();
System.out.println(finalExample.creationTime);
// The final FinalExample.FINAL_EXAMPLE_NAME field cannot be accessed
// FinalExample.FINAL_EXAMPLE_NAME = "Not you're not!";
// The final Config.creationTime field cannot be accessed
// finalExample.creationTime = 1L;
}
}
Kann eine Endvariable als Konstante betrachtet werden?
Da wir endgültigen Variablen keine neuen Werte zuweisen können, scheint es sich hierbei um konstante Variablen zu handeln. Aber nur auf den ersten Blick: Wenn der Datentyp der Variablen istimmutable
, dann ist sie ja eine Konstante. Wenn der Datentyp jedoch mutable
veränderbar ist, können Methoden und Variablen verwendet werden, um den Wert des Objekts zu ändern, auf das eine final
Variable verweist. Aus diesem Grund kann es nicht als Konstante bezeichnet werden. Das folgende Beispiel zeigt, dass einige Endvariablen tatsächlich Konstanten sind, andere hingegen nicht, da sie geändert werden können.
public class FinalExample {
// Immutable final variables
final static String FINAL_EXAMPLE_NAME = "I'm likely the final one";
final static Integer FINAL_EXAMPLE_COUNT = 10;
// Mutable final variables
final List<String> addresses = new ArrayList();
final StringBuilder finalStringBuilder = new StringBuilder("Constant?");
}
Lokale Endvariablen
Wenn einefinal
Variable innerhalb einer Methode erstellt wird, wird sie als local final
Variable bezeichnet:
public class FinalExample {
public static void main(String[] args) {
// You can do this
final int minAgeForDriveCar = 18;
// Or you can do this, in a for-each loop:
for (final String arg : args) {
System.out.println(arg);
}
}
}
Wir können das Schlüsselwort final in einer erweiterten for-Schleife verwenden, da nach jeder Iteration der Schleife eine neue Variable erstellt wird. Beachten Sie, dass dies nicht für eine normale for-Schleife gilt, sodass bei der Kompilierung ein Fehler auftritt.
// The final local j variable cannot be assigned
for (final int i = 0; i < args.length; i ++) {
System.out.println(args[i]);
}
Abschlussklasse
Eine als deklarierte Klassefinal
kann nicht erweitert werden. Einfacher ausgedrückt: Keine andere Klasse kann es erben. Ein hervorragendes Beispiel für eine final
Klasse im JDK ist String. Der erste Schritt zum Erstellen einer unveränderlichen Klasse besteht darin, sie als zu markieren und final
so zu verhindern, dass sie erweitert wird:
public final class FinalExample {
}
// Compilation error!
class WantsToInheritFinalClass extends FinalExample {
}
Endgültige Methoden
Wenn eine Methode als final markiert ist, wird sie als finale Methode bezeichnet (macht doch Sinn, oder?). Eine letzte Methode kann in einer untergeordneten Klasse nicht überschrieben werden. Übrigens sind die Methoden „wait()“ und „notify()“ der Object-Klasse endgültig, sodass wir sie nicht überschreiben können.
public class FinalExample {
public final String generateAddress() {
return "Some address";
}
}
class ChildOfFinalExample extends FinalExample {
// Compilation error!
@Override
public String generateAddress() {
return "My OWN Address";
}
}
Wie und wo man final in Java verwendet
- Verwenden Sie das Schlüsselwort final, um einige Konstanten auf Klassenebene zu definieren.
- Erstellen Sie endgültige Variablen für Objekte, die nicht geändert werden sollen. Zum Beispiel objektspezifische Eigenschaften, die wir für Protokollierungszwecke verwenden können.
- Wenn Sie nicht möchten, dass ein Kurs verlängert wird, markieren Sie ihn als endgültig.
- Wenn Sie eine unveränderliche Klasse erstellen müssen, müssen Sie sie endgültig machen.
- Wenn Sie möchten, dass sich die Implementierung einer Methode in ihren Nachkommen nicht ändert, markieren Sie die Methode als
final
. Dies ist sehr wichtig, um sicherzustellen, dass sich die Implementierung nicht ändert.
23. Was sind veränderliche und unveränderliche Typen?
Veränderlich
Veränderbare Objekte sind Objekte, deren Zustand und Variablen nach der Erstellung geändert werden können. Beispiele für veränderliche Klassen sind StringBuilder und StringBuffer. Beispiel:
public class MutableExample {
private String address;
public MutableExample(String address) {
this.address = address;
}
public String getAddress() {
return address;
}
// This setter can change the name field
public void setAddress(String address) {
this.address = address;
}
public static void main(String[] args) {
MutableExample obj = new MutableExample("First address");
System.out.println(obj.getAddress());
// We are updating the name field, so this is a mutable object
obj.setAddress("Updated address");
System.out.println(obj.getAddress());
}
}
Unveränderlich
Unveränderliche Objekte sind Objekte, deren Status und Variablen nach der Erstellung des Objekts nicht geändert werden können. Ein toller Schlüssel für eine HashMap, finden Sie nicht? :) Zum Beispiel String, Integer, Double und so weiter. Beispiel:
// We'll make this class final so no one can change it
public final class ImmutableExample {
private String address;
ImmutableExample(String address) {
this.address = address;
}
public String getAddress() {
return address;
}
// We remove the setter
public static void main(String[] args) {
ImmutableExample obj = new ImmutableExample("Old address");
System.out.println(obj.getAddress());
// There is no way to change this field, so it is an immutable object
// obj.setName("new address");
// System.out.println(obj.getName());
}
}
Im nächsten Teil betrachten wir Fragen und Antworten zu Sammlungen. Mein Profil auf GitHub Top 50 Fragen und Antworten zu Vorstellungsgesprächen für Java Core. Teil 2
GO TO FULL VERSION