JavaRush /Java-Blog /Random-DE /Abstrakte Klassen in Java mit konkreten Beispielen

Abstrakte Klassen in Java mit konkreten Beispielen

Veröffentlicht in der Gruppe Random-DE
Hallo! In früheren Vorlesungen haben wir uns mit Schnittstellen vertraut gemacht und herausgefunden, wofür sie benötigt werden. Das heutige Thema wird etwas mit dem vorherigen gemeinsam haben. Lassen Sie uns über abstrakte Klassen in Java sprechen. Abstrakte Klassen in Java mit konkreten Beispielen - 1

Warum heißen Klassen „abstrakt“?

Sie erinnern sich wahrscheinlich daran, was „Abstraktion“ ist – wir haben es bereits behandelt :) Wenn Sie es plötzlich vergessen haben, ist es in Ordnung, denken wir daran: Dies ist das Prinzip von OOP , nach dem beim Entwerfen von Klassen und Erstellen von Objekten Hervorhebung erforderlich ist nur die Haupteigenschaften einer Entität und verwerfen die sekundären. Wenn wir beispielsweise eine Klasse entwerfen SchoolTeacher– einen Schullehrer –, ist es unwahrscheinlich, dass wir das Merkmal „ Größe “ benötigen. Tatsächlich: Für einen Lehrer ist diese Eigenschaft nicht wichtig. Wenn wir jedoch eine Klasse im Programm erstellen BasketballPlayer– einen Basketballspieler –, wird die Körpergröße zu einem der Hauptmerkmale. Eine abstrakte Klasse ist also das abstrakteste, ach so annähernd „leer“ für eine Gruppe zukünftiger Klassen. Dieses Präparat kann nicht in fertiger Form verwendet werden, es ist zu „roh“. Es beschreibt jedoch einen bestimmten allgemeinen Zustand und ein bestimmtes Verhalten, das zukünftige Klassen – Erben der abstrakten Klasse – haben werden.

Beispiele für abstrakte Java-Klassen

Schauen wir uns ein einfaches Beispiel mit Autos an:
public abstract class Car {

   private String model;
   private String color;
   private int maxSpeed;

   public abstract void gas();

   public abstract void brake();

   public String getModel() {
       return model;
   }

   public void setModel(String model) {
       this.model = model;
   }

   public String getColor() {
       return color;
   }

   public void setColor(String color) {
       this.color = color;
   }

   public int getMaxSpeed() {
       return maxSpeed;
   }

   public void setMaxSpeed(int maxSpeed) {
       this.maxSpeed = maxSpeed;
   }
}
So sieht die einfachste abstrakte Klasse aus. Wie Sie sehen, nichts Besonderes :) Wofür könnten wir es brauchen? Zunächst beschreibt er auf möglichst abstrakte Weise die Entität, die wir brauchen – ein Auto. Das Wort „abstrakt“ gibt es hier aus einem bestimmten Grund. Es gibt keine „gerechten Maschinen“ auf der Welt. Es gibt Lastwagen, Rennwagen, Limousinen, Coupés und SUVs. Unsere abstrakte Klasse ist lediglich eine „Blaupause“, aus der wir später Autoklassen erstellen werden.
public class Sedan extends Car {

   @Override
   public void gas() {
       System.out.println(„Die Limousine beschleunigt!“);
   }

   @Override
   public void brake() {
       System.out.println(„Die Limousine wird langsamer!“);
   }

}
Das ähnelt stark dem, worüber wir in den Vorlesungen über Vererbung gesprochen haben. Nur dort hatten wir eine Klasse Carund ihre Methoden, die nicht abstrakt waren. Diese Lösung weist jedoch eine Reihe von Nachteilen auf, die in abstrakten Klassen behoben werden. Erstens kann keine Instanz einer abstrakten Klasse erstellt werden:
public class Main {

   public static void main(String[] args) {

       Car car = new Car(); // Fehler! Die Car-Klasse ist abstrakt!
   }
}
Dieser „Trick“ wurde speziell von den Java-Entwicklern implementiert. Noch einmal zur Erinnerung: Eine abstrakte Klasse ist nur eine Blaupause für zukünftige „normale“ Klassen . Du brauchst doch keine Kopien der Zeichnung, oder? Es besteht also keine Notwendigkeit, Instanzen einer abstrakten Klasse zu erstellen :) Und wenn die Klasse Carnicht abstrakt wäre, könnten wir ihre Objekte einfach erstellen:
public class Car {

   private String model;
   private String color;
   private int maxSpeed;

   public void gas() {
       // etwas Logik
   }

   public  void brake() {
       // etwas Logik
   }
}


public class Main {

   public static void main(String[] args) {

       Car car = new Car(); // Alles ist in Ordnung, die Maschine wurde erstellt
   }
}
Jetzt haben wir irgendein unverständliches Auto in unserem Programm – keinen Lastwagen, keinen Rennwagen, keine Limousine, sondern irgendetwas im Allgemeinen. Dasselbe „nur eine Maschine“, die es in der Natur nicht gibt. Das gleiche Beispiel lässt sich auch bei Tieren anführen. Stellen Sie sich vor, in Ihrem Programm würden Objekte auftauchen Animal– „ nur ein Tier “. Um welche Art es sich handelt, zu welcher Familie es gehört und welche Eigenschaften es aufweist, ist unklar. Es wäre seltsam, ihn im Programm zu sehen. In der Natur gibt es keine „gerechten Tiere“. Nur Hunde, Katzen, Füchse, Maulwürfe und andere. Abstrakte Klassen befreien uns von „ nur Objekten “. Sie geben uns einen Grundzustand und ein Verhalten. Beispielsweise müssen alle Autos ein Modell , eine Farbe und eine Höchstgeschwindigkeit haben , außerdem müssen sie Gas und Bremsen können . Das ist alles. Dies ist ein allgemeines abstraktes Schema. Anschließend entwerfen Sie selbst die Klassen, die Sie benötigen. Bitte beachten Sie: Zwei Methoden in einer abstrakten Klasse werden ebenfalls als abstract bezeichnet und sind überhaupt nicht implementiert. Der Grund ist derselbe: Abstrakte Klassen erzeugen kein „Standardverhalten“ für „bloße Maschinen“. Sie sagen nur, dass sie in der Lage sein sollten, alle Autos herzustellen. Wenn Sie jedoch weiterhin das Standardverhalten benötigen, können Sie Methoden in einer abstrakten Klasse implementieren. Java verbietet dies nicht:
public abstract class Car {

   private String model;
   private String color;
   private int maxSpeed;

   public void gas() {
       System.out.println("Lass uns gehen!");
   }

   public abstract void brake();

   //Getter und Setter
}


public class Sedan extends Car {

   @Override
   public void brake() {
       System.out.println(„Die Limousine wird langsamer!“);
   }

}

public class Main {

   public static void main(String[] args) {

       Sedan sedan = new Sedan();
       sedan.gas();
   }
}
Konsolenausgabe: „Beschleunigen!“ Wie Sie sehen, haben wir eine Methode in der abstrakten Klasse implementiert, die zweite jedoch nicht. Infolgedessen Sedanwurde das Verhalten unserer Klasse in zwei Teile geteilt: Wenn Sie eine Methode darauf aufrufen gas(), wird sie von der übergeordneten abstrakten Klasse „abgerufen“ Carund brake()wir haben die Methode in der Klasse neu definiert Sedan. Es erwies sich als sehr praktisch und flexibel. Aber jetzt ist unsere Klasse nicht mehr so ​​abstrakt ? Immerhin wird tatsächlich die Hälfte seiner Methoden umgesetzt. Tatsächlich – und das ist ein sehr wichtiges Merkmal – ist eine Klasse dann abstrakt, wenn mindestens eine ihrer Methoden abstrakt ist . Mindestens eine von zwei, mindestens eine von tausend Methoden – das spielt keine Rolle. Wir können sogar alle Methoden implementieren und keine abstrakten übrig lassen. Es wird eine abstrakte Klasse ohne abstrakte Methoden geben. Im Prinzip ist dies möglich und der Compiler wird keine Fehler erzeugen, aber es ist besser, dies nicht zu tun: Das Wort „abstrakt“ verliert seine Bedeutung und Ihre Programmierkollegen werden sehr überrascht sein, dies zu sehen :/ Außerdem, wenn eine Methode mit dem Wort „abstrakt“ gekennzeichnet ist, muss jede abgeleitete Klasse „abstrakt“ implementieren oder als abstrakt deklariert werden. Andernfalls gibt der Compiler einen Fehler aus . Natürlich kann jede Klasse nur von einer abstrakten Klasse erben, sodass es hinsichtlich der Vererbung keinen Unterschied zwischen abstrakten und regulären Klassen gibt. Es spielt keine Rolle, ob wir von einer abstrakten oder einer regulären Klasse erben, es kann nur eine übergeordnete Klasse geben.

Warum gibt es in Java keine Mehrfachklassenvererbung?

Wir haben bereits gesagt, dass es in Java keine Mehrfachvererbung gibt, aber wir haben noch nicht wirklich herausgefunden, warum. Versuchen wir es jetzt. Der Punkt ist, dass untergeordnete Klassen nicht entscheiden könnten, welches Verhalten sie wählen würden, wenn Java über Mehrfachvererbung verfügen würde. Nehmen wir an, wir haben zwei Klassen – Tosterund NuclearBomb:
public class Toster {


 public void on() {

       System.out.println(„Der Toaster ist an, der Toast wird fertig!“);
   }

   public void off() {

       System.out.println(„Der Toaster ist aus!“);
   }
}


public class NuclearBomb {

   public void on() {

       System.out.println("Взрыв!");
   }
}
Wie Sie sehen, haben beide eine Methode on(). Im Falle eines Toasters beginnt er, Toast zu backen, und im Falle einer Atombombe löst er eine Explosion aus. Oh :/ Stellen Sie sich nun vor, Sie hätten (ich weiß nicht warum plötzlich!) beschlossen, etwas dazwischen zu schaffen. Und hier ist es deine Klasse - MysteriousDevice! Dieser Code funktioniert natürlich nicht und wir präsentieren ihn lediglich als Beispiel dafür, „wie es sein könnte“:
public class MysteriousDevice extends Toster, NuclearBomb {

   public static void main(String[] args) {

       MysteriousDevice mysteriousDevice = new MysteriousDevice();
       mysteriousDevice.on(); // Und was soll hier passieren? Bekommen wir einen Toast oder eine nukleare Apokalypse?
   }
}
Mal sehen, was wir haben. Das mysteriöse Gerät stammt sowohl vom Toaster als auch von der Atombombe. Beide haben eine Methode on(), und daher ist nicht klar, welche Methode on()auf das Objekt ausgelöst werden soll, MysteriousDevicewenn wir es aufrufen. Das Objekt wird dies nicht verstehen können. Nun, als Kirsche auf dem Kuchen: Die Atombombe hat keine Methode off(). Wenn wir also falsch geraten haben, gibt es keine Möglichkeit, das Gerät auszuschalten. Abstrakte Klassen in Java mit konkreten Beispielen - 2 Gerade wegen dieser Verwirrung haben die Entwickler von Java die Mehrfachvererbung aufgegeben, wenn einem Objekt nicht klar ist, welches Verhalten es wählen soll. Sie erinnern sich jedoch daran, dass Java-Klassen viele Schnittstellen implementieren. Übrigens haben Sie in Ihrem Studium schon mindestens eine Abstract-Klasse kennengelernt! Obwohl, vielleicht habe ich es nicht bemerkt :)
public abstract class Calendar implements Serializable, Cloneable, Comparable<Calendar>
Das ist die Klasse deiner alten Freunde Calendar. Es ist abstrakt und hat mehrere Erben. Einer von ihnen ist GregorianCalendar. Sie haben es bereits im Unterricht über Datumsangaben verwendet :) Alles scheint klar zu sein, es bleibt nur noch ein Punkt: Was ist der grundlegende Unterschied zwischen abstrakten Klassen und Schnittstellen ? Warum haben sie beide zu Java hinzugefügt und sich nicht auf nur eines beschränkt? Das könnte durchaus ausreichen. Darüber sprechen wir im nächsten Vortrag! Auf Wiedersehen:)
Kommentare
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION