Zugangsmodifikatoren und Vererbung

JavaJavaBeginner
Jetzt üben

💡 Dieser Artikel wurde von AI-Assistenten übersetzt. Um die englische Version anzuzeigen, können Sie hier klicken

Einführung

In diesem Lab werden Sie Zugangsmodifikatoren und Vererbung lernen. Mit unterschiedlichen Modifikatoren sind die Zugangsebenen unterschiedlich. Die Vererbung in Java ähnelt der biologischen Vererbung darin, dass Kinder die Eigenschaften der Eltern beibehalten und sich auf bestimmte Weise anders verhalten können.

Dies ist ein Guided Lab, das schrittweise Anweisungen bietet, um Ihnen beim Lernen und Üben zu helfen. Befolgen Sie die Anweisungen sorgfältig, um jeden Schritt abzuschließen und praktische Erfahrungen zu sammeln. Historische Daten zeigen, dass dies ein Labor der Stufe Anfänger mit einer Abschlussquote von 93% ist. Es hat eine positive Bewertungsrate von 100% von den Lernenden erhalten.

Zugangsmodifikatoren

Bisher haben wir bereits Code geschrieben. Im vorherigen Lab haben wir eine Klasse geschrieben. Es gibt Modifikatoren wie public und private. Was bedeuten diese Wörter also?

Java bietet eine Reihe von Zugangsmodifikatoren an, um die Zugangsebenen für Klassen, Variablen, Methoden und Konstruktoren festzulegen. Die vier Zugangsebenen sind:

  • default: Sichtbar innerhalb des Pakets, der Standard. Keine Modifikatoren erforderlich.
  • private: Nur der definierenden Klasse sichtbar.
  • public: Sichtbar für die Java-Welt (alle Typen). Sie können sie überall zugreifen.
  • protected: Sichtbar für das Paket und alle Unterklassen (auch für die in anderen Paketen).
Java-Zugangsmodifikatoren-Diagramm

Java bietet eine Reihe von nicht-zugangsbezogenen Modifikatoren an, um viele andere Arten der Feinabstimmung des Verhaltens zu erreichen:

  • static: Dieser Modifikator wird verwendet, um Variablen oder Methoden zu erstellen, die unabhängig von allen Instanzen der Klasse existieren. Es gibt nur eine Kopie der static-Variablen für die Klasse, unabhängig von der Anzahl der erstellten Instanzen.
  • final: Eine final-Variable kann nur einmal explizit initialisiert werden. Eine final-Methode kann von keiner Unterklasse überschrieben werden. Eine Klasse wird als final deklariert, um zu verhindern, dass die Klasse weitervererbt wird.
  • abstract: Eine abstract-Klasse kann niemals instanziiert werden. Eine abstract-Methode ist eine Methode, die ohne jede Implementierung deklariert wird.
  • synchronized/volatile: Die Modifikatoren synchronized und volatile werden im Zusammenhang mit Threads verwendet.

Beispiel:

Schreiben Sie folgenden Code in die Datei /home/labex/project/modifierTest.java:

public class modifierTest {
    // static variables are initialized when class is loaded.
    public static int i = 10;
    public static final int NUM = 5;
    // non-static variables are initialized when object is created.
    public int j = 1;

    /*
     * static code block here, this will execute when the class is loaded
     * creating new object will not execute the block again, run only once.
    */
    static{
        System.out.println("this is a class static block.");
    }
    public static void main(String[] args)
    {
        System.out.println("this is in main method");

        // you can access i and change it
        modifierTest.i = 20;  //the same with obj.i = 20
        System.out.println("Class variable i = " + modifierTest.i);
        // you can access NUM, but can't change it
        // HelloWorld.NUM = 10;     this will cause an error, NUM is final, it's immutable
        System.out.println("Class variable NUM = " + modifierTest.NUM);

        // create new object
        modifierTest obj = new modifierTest();
        // we can use both class and object to access static methods and static properties
        obj.staticMethod();  // the same with modifierTest.staticMethod()
        // you can't access j like this: modifierTest.j
        System.out.println("Object variable j = " + obj.j);
    }
    // the constructor, only new object being created will call this.
    public modifierTest(){
        System.out.println("this is in object's constructor.");
    }
    public static void staticMethod(){
        System.out.println("this is a static method");
    }
}

Ausgabe:

Führen Sie die Datei modifierTest.java mit folgenden Befehlen aus:

javac /home/labex/project/modifierTest.java
java modifierTest

Sehen Sie sich die Ausgabe an:

this is a class static block.
this is in main method
Class variable i = 20
Class variable NUM = 5
this is in object's constructor.
this is a static method
Object variable j = 1

Vererbung

In vielen Fällen haben wir eine Klasse geschrieben. Und dann müssen wir eine neue Klasse schreiben, um nur ein wenig den Code der vorherigen Klasse zu ändern, und sie haben eine gewisse logische Beziehung zueinander. Hier können wir Vererbung verwenden. Wir verwenden das Schlüsselwort extends, um die Vererbung zu implementieren. Unterklassen erben alle zugänglichen Eigenschaften und Methoden der Superklasse und können auch eigene spezielle Eigenschaften und Methoden haben. In Unterklassen können wir auf die Eigenschaften und Methoden zugreifen, die in der Superklasse als public oder protected deklariert sind, aber die private Eigenschaften können wir nicht direkt zugreifen. Ein Beispiel: Die Vererbungsstruktur wird in einem Diagramm gezeigt. Sie können Mehrstufenvererbung (horizontal) oder hierarchische Vererbung (vertikal) implementieren:

Vererbungsstruktur-Diagramm

Beispiel:

Schreiben Sie folgenden Code in die Datei /home/labex/project/inheritanceTest.java:

class Animal{
    // what kind of animal i am.
    private String species;
    private int age = 8;

    public Animal(){
        System.out.println("Animal's constructor");
    }
    public void grow(){
        // In this class, we can access the private properties directly.
        System.out.println("I'm "+ this.age + " years old, " +"I grow up.");
    }
}
class Dog extends Animal{
    private String color;
    // In this class, we can't access superclass private attributes, but grow() is ok.
    public Dog(){
        System.out.println("Dog's constructor");
    }
    public void run(){
        this.grow();
        System.out.println("I'm dog, I can run.");
    }
}
class Bird extends Animal{
    private double weight;

    public Bird(){
        // if explicitly invoke superclass constructor, it must be at the first line here.
        // super();
        System.out.println("Bird's constructor");
    }
    public void fly(){
        this.grow();
        System.out.println("I'm bird, I can fly.");
    }
}
public class inheritanceTest{
    public static void main(String[] args){
        Dog dog = new Dog();
        dog.run();

        Bird bird = new Bird();
        bird.fly();
    }
}

Ausgabe:

Führen Sie die Datei inheritanceTest.java mit folgenden Befehlen aus:

javac /home/labex/project/inheritanceTest.java
java inheritanceTest

Sehen Sie sich die Ausgabe an:

Animal's constructor
Dog's constructor
I'm 8 years old, I grow up.
I'm dog, I can run.
Animal's constructor
Bird's constructor
I'm 8 years old, I grow up.
I'm bird, I can fly.

Wenn Sie diese Ausgabe sehen, können Sie verwirrt sein. Keine Sorge; wir werden erklären, warum. Wenn wir ein Objekt einer Unterklasse mit new erstellen, ruft es standardmäßig zuerst den Standardkonstruktor der Superklasse in der Vererbungsbaumstruktur "von oben nach unten" auf und führt zuletzt seinen eigenen Konstruktor aus. Der Superklassekonstruktor kann explizit mit dem Schlüsselwort super aufgerufen werden, aber es muss der erste Ausdruck in einem Konstruktor sein, wenn er vorhanden ist. Das Schlüsselwort super bezieht sich auf die Superklasse, direkt über der aufrufenden Klasse in der Hierarchie.

Zusammenfassung

Mit Zugangsmodifikatoren können wir sicheren Code schreiben, Details verstecken und Zugangskontrolle erreichen. Andere Benutzer müssen nicht wissen, wie wir die Details von Methoden implementieren. Wir bieten eine Schnittstelle an andere Aufrufer. Für Zugangsmodifikatoren können Sie Java-Quellcodebibliotheken lesen, um zu verstehen, was der Unterschied ist. Die Vererbung, denken Sie daran, die hierarchische Struktur, ist die Beziehung zwischen Klassen.