INFO

Zur Haupt-Section (AB) geht es hier: Arbeitsblatt.

Basics

In diesem Absatz gehe ich so verständlich wie möglich auf einige Basis-Konzepte von Java ein und versuche sie anhand von einfachen Beispiel zu erläutern.

Basics - Das Konzept von objektorientierter Programmierung

In objektorientierter Programmierung (Absofort mit OOP abgekürzt) dreht sich alles um Objekte.

Die erste Frage, die sich einem dann hierbei stellt, ist womöglich: Schön, was aber ist jetzt ein Objekt? Also was kann es und wie macht man eins?

Diese Frage lässt sich am besten mit einem praktischen Beispiel erläutern. Gehen wir nun einmal davon aus, dass wir irgendwie in der Welt des Programmierens in Java ein Auto darstellen wollen.

Nun, genau für solche Fälle sind Objekte gedacht. Wir betrachten ein Auto nun also nicht einfach nur als Ding, sondern als Objekt. Ein Auto hat bestimmte Eigenschaften und kann bestimmte Dinge tun. Genau so soll also auch ein Objekt funktionieren.

Die Eigenschaften eines Objektes nennt man hierbei Attribute, während die Fähigkeiten eines Objektes, also die Dinge, die es "tun kann", Methoden genannt werden.

Wie erstellen wir nun aber ein Auto?

Genau hier kommen dann Klassen ins Spiel. Eine Klasse kann als Blueprint, als Bauplan für ein Objekt angesehen werden, der genau festlegt, wie ein Objekt einmal auszusehen hat, d.h. was es alles für Eigenschaften und Fähigkeiten haben soll.

In einer Klasse definieren wir Attribute und Methoden, über die dann ein Objekt dieser Klasse (Auch genannt Instanz) verfügen soll.

Um das alles einmal praktisch zu veranschaulichen, versuchen wir nun einfach einmal ein sehr einfaches Auto Objekt in Java zu erstellen.

Hierfür müssen wir uns zu allererst einmal überlegen, welche Eigenschaften und Fähigkeiten ein Auto überhaupt besitzen soll.

Nun, für unser vereinfachtes Beispiel hat ein Auto auf jeden Fall eine Farbe, einen Modelname und kann hupen und fahren.

Damit hätten wir zwei Attribute und zwei Fähigkeiten, die ein Auto Objekt also besitzen muss.

Um nun ein Auto Objekt erstellen zu können, müssen wir erstmal den Bauplan für das Auto, also die Klasse für das Auto entwerfen.

Diese nennen wir passend Auto.

Sie soll zwei Attribute, eine Farbe color und einen Modelname modelName und zwei Methoden hupen() und fahren() haben.

Basics - Encapsulation

Wir bleiben weiter bei den Beispiel des Autos.

Um uns nun weiter der Erstellung der Auto-Klasse anzunähern, wenden wir auch gleich ein sehr wichtiges Konzept der OOP an: Encapsulation (DE: Verkapselung).

In dieser geht es darum die Eigenschaften verschiedener Klassen, also später Objekten, voneinander abzugrenzen. Dies können wir durch die Verwendung von Sichtbarkeits-Modifizierern erreichen. Durch diese legen wir nämlich fest, auf welche Eigenschaften welches Objekt zugreifen kann.

In Java stehen uns die folgenden zur Verfügung: public, private und protected.

Der Sichtbarkeits-Modifizierer public bedeutet, dass auf dieses Attribut oder diese Methode direkt von außen zugegriffen werden kann. Das heißt, dass auch von außerhalb des Objektes direkt Änderungen an einem Attribut (das also als public definiert wurde) eines anderen Objektes vorgenommen werden können.

Das komplette Gegenteil von public ist, wie es der Name schon vermuten lässt, private. Auf ein Attribut, was als private definiert wurde, kann niemals direkt von außerhalb des Objektes darauf zugegriffen werden. Um jedoch immernoch Änderungen an diesem Attribut vornehmen zu können, werden sogenannte Getter und Setter Methoden verwendet.

Das Praktische an diesen Bezeichnungen ist, dass sie bereits im Vorhinein quasi alles über ihre Funktion verraten.

Über einen Getter können wir den Wert eines Attributes lesen, ohne dabei direkt von außen auf dieses Attribut zuzugreifen. Wie der Name vermuten lässt, "getten" wir etwas durch ihn - Er gibt etwas zurück, nämlich den Wert des privaten Attributes.

Ein Setter erlaubt es uns, ihm einen Wert zu übergeben und dann den Wert des entsprechenden Attributes auf diesen übergebenen Wert zu setzen.

Über diese beiden Umwege können wir also, obwohl wir ein Attribut als private definiert haben, dessen Wert noch ändern. Der wichtige Unterschied hierbei ist, dass wir es in diesem Fall allerdings nicht direkt tun.

Das gleiche, was ich nun bereits für Attribute erläutert habe, gilt auch für Methoden (nahezu). Bei Methoden weisen wir nun jedoch keinen Wert mehr zu, sondern wollen etwas ausführen, etwas tun.

Damit regeln die Sichtbarkeits-Modifizierer von Methoden "nur noch", ob auf die jeweiligen Methoden von außerhalb oder nur von innerhalb eines Objektes aus zugegriffen werden kann.

Ist eine Methode als public definiert, kann auch von außerhalb des Objektes auf die Methode zugegriffen werden. Bei private ist das genaue Gegenteil der Fall.

Was genau das alles nun im Klartext bedeutet, wird hoffentlich bei der weiteren Ausführung der Erstellung unserer Auto Klasse klar.

Abschließend sei zu diesem Absatz noch gesagt, dass der Sichtbarkeits-Modifizierer protected eine besondere Funktion hat, auf die ich erst im weiteren Verlauf dieses ABs eingehen werde. Bisher nur soviel: Seine Funktion hat etwas mit einem weiteren extrem wichtigen Konzept der OOP zu tun, der Vererbung. Hierzu jedoch später mehr.

Basics - Methoden

Zuvor bin ich bereits auf Methoden im Allgemeinen ein wenig über die Beschreibung der Getter und Setter eingegangen.

Hierzu sind bestimmt einige Fragen entstanden, die ich nun versuchen werde in diesem Abschnitt zu erläutern.

Was genau bedeutet es denn, wenn einer Methode ein oder mehrere Werte übergeben werden?

Um sich das auf eine sehr simple Art zu veranschaulichen, betrachten wir im folgenden eine Methode als eine Art mathematische Funktion.

In diesem Beispiel sollte dann auch gleich das Konzept einer Methodenrückgabe klarer werden.

Wir versuchen nun einfach mal (unabhängig zu dem Auto Beispiel aus den zuvorigen Abschnitten!) eine Methode für das Summieren zweier Ganzzahlen zu schreiben.

Dafür müssen wir, wie bei einer mathematischen Funktion, erst einmal einen oder mehrere Werte in sie "hineinstecken", um einen weiteren "heraus", also zurückzubekommen.

In Java müssen wir beachten, dass Java es vorschreibt (abgesehen von lambda-Funktionen - doch diese lassen wir in diesem AB außer Acht, bei mehr Interesse gerne direkt bei mir nachfragen), dass jede Funktion in einer Klasse steht und damit im Endeffekt nur über ein Objekt dieser Klasse oder in einem Objekt dieser Klasse aufgerufen werden kann.

Ferner startet jedes Java-Programm immer in der main Methode, die sich in jedem Java-Programm in der folgenden Form auffinden lässt:

                    
    public static void main(String[] args) {
        // Anweisungen
    }
                    
                

Hier finden wir auch gleich einen nun bereits bekannten Sichtbarkeits-Modifizierer, public, der von einem weiteren bisher unbekanntnen Schlüsselwort static und schließlich void gefolgt wird, bis wir schließlich beim Methodennamen main angekommen sind.

In den Klammern folgt dann ein sogenannter Parameter, args vom Typ String[] (Was genau das nun bedeutet, ist zum jetzigen Stand erst einmal unwichtig). Auf dieses Konzept gehe ich nun im Bezug auf unsere Summen-Methode ein.

Parameter erlauben es uns, einer Methode Werte von außen zu übergeben, mit denen wir dann etwas in der Methode anstellen können.

So müssen wir, um das Ergebnis einer Addition von zwei Ganzzahlen zu erhalten, unserer Methode zwei Parameter übergeben: Den ersten und den zweiten Summanden.

Da wir nur mit ganzen Zahlen rechnen, sollen beide Parameter von Typ int sein und die Namen sum1 und sum2 haben.

Diese zwei übergebenen Werte rechnen wir in unserer Methode zusammen und geben das Ergebnis wieder zurück.

So könnte eine relativ lange Version für unsere Additions-Methode wie folgt aussehen:

                    
    public int sum(int sum1, int sum2){
        int result = sum1 + sum2;
        return result;
    }
                    
                

Wenn wir nun diese Methode einmal mit der main Methode vergleichen, fällt direkt etwas auf: Wo ist das void der main Methode hin?

Nun, über dieses void sagen wir dem Java-Compiler, dass eine Methode keinen Wert zurückgibt, also genau das, was wir nicht wollen.

Gerade unsere Additions-Methode soll ja aber das Ergebnis dieser Addition zurückgeben.

Also müssen wir den Rückgabetypen dieser Methode ändern. Geben wir etwas in einer Methode zurück, müssen wir festlegen, von welchem Typ der zurückgegebene Wert sein wird.

In unserem Fall wissen wir ja, dass wir nur mit Ganzzahlen, also keinen Kommazahlen rechnen und können demnach den Datentyp int als Rückgabetyp festlegen.

Und wie geben wir nun einen Wert zurück?

Dies erledigen wir über die return Anweisung. Der Wert, der ihr folgt, wird zurückgegeben.

In unserer Additions-Methode geben wir den Wert von der Variablen result des Typs int zurück. In dieser Variablen ist das eigentliche Ergebnis der Addition der beiden Summanden gespeichert.

Um die Methode ein wenig kürzer zu halten, wäre folgendes auch vollkommen legitim:

                    
    public int sum(int sum1, int sum2){
        return sum1 + sum2;
    }
                    
                

Dann testen wir doch einfach mal unsere Methode!

Da in Java alles in Klassen stehen muss, müssen wir also erst eine neue Datei erstellen und in dieser eine Klasse definieren, die allerdings keinerlei Eigenschaften besitzen muss. In ihr muss sich nur die main Methode befinden. Denn in dieser startet ja die Ausführung unseres Java-Programms.

Weiter ist es in Java notwendig die eigentliche Datei so zu nennen, wie die in ihr definierte Klasse heißt.

Wir nennen unsere "Anfangsklasse" einfach Main und fügen in diese das Code-Snippet der main Methode von weiter oben ein.

Um im Java-Editor eine leere Java-Datei zu erstellen, klicke auf Datei > Neu > Java oder drücke Strg + N

Um diese Datei dann zu speichern und ihr einen Namen zu geben, klicke auf Datei > Speichern oder drücke Strg + S.

In dem neu geöffneten Fenster kannst du nun den Speicherort und den Dateinamen festlegen.

Abschließend einfach auf Speichern klicken.

Damit sollte in der Datei Main.java nun folgendes stehen:

                    
    public class Main {
        public static void main(String[] args) {
            // Anweisungen
        }
    }
                    
                

Um nun unsere eigene Methode auszuprobieren, müssen wir diese einfach in die Main Klasse einfügen und (!) das Schlüsselwort static hinzufügen.

Warum genau dies nun nötig ist würde nun etwas den Rahmen sprengen, deshalb sei lediglich gesagt, dass es notwendig ist und sonst einen Fehler geben würde, weil wir unsere Methode später aus der main Methode und damit aus einem statischen Kontext ausrufen werden, wodurch die aufgerufene Methode automatisch auch als static definiert sein muss.

Damit sieht die fertige Main Klasse nun so aus:

                    
    public class Main {
        public static void main(String[] args) {
            // Anweisungen
        }

        public static int sum(int sum1, int sum2){
            return sum1 + sum2;
        }
    }
                    
                

Jedoch können wir bisher immer noch nicht sehen, was unsere eigene sum() Methode denn zurückgibt.

Dafür müssen wir sie ja erstmal irgendwo aufrufen und ihr dabei zwei Werte von Typ int übergeben, denn so haben wir es ja in unserer Methoden-Definition festgelegt.

Hierfür deklarieren wir in der main() Methode eine Variable addition vom Typ int.

Anschließend weisen wir ihr einen Wert zu. Jedoch nicht wie bisher direkt eine Zahl, sondern den Wert, den sum() zurückgibt, wenn wir ihr zwei Ganzzahlen übergeben.

Über den Befehl System.out.println() (Was im übrigen auch einfach nur ein Methoden-Aufruf ist), können wir uns Werte auf der Konsole ausgeben lassen. Nämlich genau den Wert, den wir ihr als Parameter (oder auch Argument genannt) übergeben.

Damit sieht unser fertiges Additions-Programm wie folgt aus:

                    
    public class Main {
        public static void main(String[] args) {
            int addition;
            addition = sum(2, 3);
            System.out.println(addition);
        }

        public static int sum(int sum1, int sum2){
            return sum1 + sum2;
        }
    }

    // Nach Complilieren und Ausführen wird auf der Konsole ausgegeben:
    // 5
                    
                

Versuche doch einfach mal eine Methode mul() für die Multiplikation zweier Ganzzahlen zu schreiben. Oder wie sieht es denn aus, wenn wir drei statt nur zwei Zahlen addieren wollen?

Probiere einfach ein bisschen herum, das fördert nur dein Verständnis!

Basics - Zurück zur Konstruktion des Autos

Nun mit unserem neuen Wissen wollen wir das Beispiel von einem Auto Objekt einmal zuende führen.

Um einmal zu rekapitulieren:

  • Unser Auto Objekt soll folgende Attribute und Methoden besitzen: color, model, fahren() und hupen()
  • Nach dem Konzept der Encapsulation müssen wir uns nun überlegen, welche Attribute und Methoden nach außen sichtbar sein sollen und welche nicht. In anderen Worten: Auf welche Eigenschaften von außen zugegriffen werden kann.
  • Zusätzlich müssen wir auch erst einmal überlegen, was genau wir in den Attributen speichern wollen. Daraus legen wir dann die entsprechenden Datentypen fest.

Was muss denn nun alles von außen direkt aufrufbar sein?

Nun, color, model müssen ja eigentlich nicht wirklich direkt von außen abrufbar sein. Eventuell wollen wir sie im Laufe des Programmes einmal auslesen oder sogar ändern, ein Auto kann ja auch neu lackiert werden und das können wir dann ja über den indirekten Zugriff über die Getter und Setter regeln.

Das heißt, dass wir color und model auf jeden Fall als private definieren werden.

Bleibt noch die Frage des Datentyps.

Der einfachere Fall zuerst: In model wollen wir ja einen Modelnamen speichern. Und aus was besteht ein Name? Genau, aus vielen aneinandergehängten Zeichen. Damit fällt unsere Wahl des Datentyps von model eindeutig auf String, da sich in einem String Zeichenketten speichern lassen.

In color soll ja eine Farbe gespeichert werden. Dies könnten wir zwar ganz einfach durch eine Zeichenkette, also einen String realisieren, indem wir z.B. einfach den hex-code einer Farbe als String in color speichern, jedoch ist das relativ unpraktisch.

Da kommt es uns nur gelegen, dass Java bereits eine eigene Klasse Color definiert hat, die es uns erlaubt simpel Color Objekte zu erstellen, in denen wir dann die Werte für R (Rot), G (Grün) und B (Blau) speichern können und uns zusätzlich noch einige andere sehr praktische Methoden zur Verfügung stehen.

Wichtig hierbei ist noch, dass wir, um diese Klasse in unserem Quellcode verwenden zu können, sie erst über den folgenden Befehl, den wir später ganz oben in die erste Zeile unseres Programms schreiben, importieren müssen.

                    
    import java.awt.Color;
                    
                

Um ein Objekt color des Typs Color zu erstellen, verwenden wir folgendes Code-Snippet:

                    
    Color color = new Color(255, 0, 0);
                    
                

Bevor ich nun genauer auf die Erklärung dieses Snippets eingehe, erst noch ein paar Worte zu der Formulierung "Ein Objekt ... des Typs ...":

Mit dieser Formulierung lässt sich ausdrücken mithilfe welcher Klasse ein Objekt erstellt wird.

So bedeutet in unserem Fall "ein Objekt color des Typs Color", dass das Objekt color durch die Klasse Color festgelegt und sie damit also der Bauplan für das Objekt ist.

In ihr steht also genau definiert, welche Eigenschaften und Fähigkeiten, also Attribute und Methoden ein Farb-Objekt haben sollte.

Jetzt aber mal zur richtigen Erklärung des Snippets:

Bisher sind wir nur darauf eingegangen, was eine Klasse eigentlich ist und wofür wir sie benötigen. Die Frage, wie wir denn nun ein Objekt nach dem Bauplan, den die Klasse vorgibt, erstellen ist allerdings immer noch offen.

Das magische Wort lautet hier Konstruktor.

Was ist nun aber ein Konstruktor?

Jede Klasse muss über eine Methode verfügen, die bei der Erzeugung eines Objekts der Klasse aufgerufen wird. In dieser Methode können dann Werte initialisiert und erste Anweisungen durchgeführt werden. Diese Methode heißt Konstruktor.

Er wird bei der Erstellung, also bei der Konstruktion eines Objekts aufgerufen.

Für ihn gibt es ein paar Sonderregeln, die immer gelten:

Die wichtigste davon ist dabei mit Sicherheit die folgende: Der Konstruktor muss immer in jeder Klasse ohne Ausnahme wie die Klasse benannt sein.

Gleichzeitig muss er immer als public definiert werden, da er ja von außerhalb eines Objektes aufgerufen wird.

Eine weitere Besonderheit ist, dass ein Konstruktor niemals einen Rückgabetyp hat, in seiner Definition also nie ein void oder ein Datentyp stehen darf.

Im Großen und Ganzen ist der Konstruktor aber eben auch nur eine Methode.

Das heißt für ihn gelten mit den paar zuvor genannten Einschränkungen, exakt dieselben Regel wir für jede andere beliebige Methode.

Also können wir auch einem Konstruktor bestimmte Parameter übergeben, mit denen wir dann etwas in ihm anstellen können.

So wollen wir ja schon bei der Erstellung eines Auto-Objektes unsere eigenen Farbe und den Modelnamen individuell festlegen lassen.

Mit diesem ganzen neuen Wissen ist es uns nun sogar schon möglich eine erste Version (bisher ohne weitere Methoden, als den Konstruktor) der Klasse Auto zu entwerfen.

Um es einmal davor noch kurz und knapp zusammenzufassen:

  • Die Klasse soll die zwei Attribute color und model besitzen, die beide als private definiert werden. Dabei hat color den Datentyp Color und model den bereits bekannten Datentyp String.
  • Außerdem benötigt sie einen Konstruktor, der den gleichen Namen wie sie selbst hat - Also Auto() - und als public definiert ist.
    Außerdem soll er die beiden Parameter color vom Typ Color und model vom Typ String entgegennehmen.

Damit sieht unser erster Entwurf der Auto Klasse wie folgt aus:

                    
    public class Auto{
        private Color color;
        private String model; 

        public Auto(Color color, String model){ }

        public Color getColor(){
            return this.color;
        }
        public void setColor(Color newColor){
            this.color = newColor;
        }

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

Hierbei sei noch zu beachten, dass die Attribute bei ihrer Deklaration nicht direkt mit einem Wert initialisiert werden, sondern dies in dem Konstruktor geschehen soll.

Eine Außnahme hierfür stellen konstante Attribute dar, da diese immer direkt in ihrer Deklaration initialisiert werden müssen. Anschließend kann ihr Wert jedoch auch an keinem Punkt in unserem Programm abgeändert werden.

Würden wir zum Beispiel davon ausgehen, dass die Räderanzahl eines Autos immer nur gleich 4 sein sollte, so könnten wir das folgende Attribut einfügen (Das kannst du auch gerne tun 😄. Für den weiteren Verlauf dieses Turtorials ist dies allerdings irrelevalt):

                    
    private final int tires = 4;
                    
                

Zuletzt noch ein paar Worte zu den Gettern und Settern der beiden privaten Attribute:

In diesen Methoden ist dir wahrscheinlich schon das Schlüsselwort this aufgefallen. In diesen Fällen ist es zwar nicht notwendig, später werden wir allerdings noch sehen, warum wir es verwenden sollten.

Unter this kannst du eine Art Referenz auf das eigene Objekt verstehen. Ein Ausdruck wie this.color bezieht sich also immer direkt auf das Objekt, bzw. genau das Attribut dieses Objektes, aus dem es aufgerufen wird.

Die folgende Version des Quellcodes wäre damit auch vollkommen korrekt, wenn auch nicht gleich leicht verständlich:

                    
    public class Auto{
        private Color color;
        private String model; 

        public Auto(Color color, String model){ }

        public Color getColor(){
            return color;
        }
        public void setColor(Color newColor){
            color = newColor;
        }

        public String getModel(){
            return model;
        }
        public void setModel(String newModel){
            model = newModel;
        }
    }
                    
                

Basics - Der Bauplan formt sich immer mehr und mehr

Unser erster Entwurf steht jetzt. Wir können die Dateien zwar schon komplilieren, jedoch fehlt noch eine kleine Sache.

Setzen wir denn schon irgendwo die Werte der beiden Attribute?

Um herauszufinden, was hier fehlt, erstelle, wenn du es bisher nicht sowieso von alleine weise vorausschauend gemacht hast, einen neuen Ordner und erstelle in diesem eine neue Datei für die Main-Klasse und eine weitere für die Auto-Klasse

Ausgehend davon, dass der Ordner AutoProject heißt, sieht die Ordnerstruktur also wie folgt aus:

                    
    AutoProjekt
        > Main.java
        > Auto.java
                    
                

Den Basis-Code für eine die "Start"-Klasse, in der sich die main() Methode befindet, können wir hierbei einfach aus den Beispielen von zuvor kopieren und in Main.java einfügen.

Damit steht in Main.java:

                    
    public class Main {
        public static void main(String[] args) {
            // Anweisungen
        }
    }
                    
                

In die Auto Klasse fügst du einfach den Entwurf aus dem letzten Abschnitt ein:

                    
    import java.awt.Color;

    public class Auto{
        private Color color;
        private String model; 

        public Auto(Color color, String model){ }

        public Color getColor(){
            return color;
        }
        public void setColor(Color newColor){
            color = newColor;
        }

        public String getModel(){
            return model;
        }
        public void setModel(String newModel){
            model = newModel;
        }
    }
                    
                

Hierbei darfst du jedoch nicht den Import der Color Klasse vergessen, sonst meckert der Compiler bereits beim Kompilieren.

Basics - Initialisierung im Konstruktor

Wie ich im letzen Abschnitt bereits ein wenig vorweg genommen habe, weisen wir unseren beiden Attributen bisher noch nirgendwo Werte zu.

Das heißt sie zeigen bisher noch auf gar keine Referenz oder einen Wert, sondern lediglich null.

Aus dem Abschnitt Konstruktoren im Allgemeinen ist dir eventuell noch im Kopf geblieben, für was sie denn normalerweise verwendet werden. Nämlich für die Initialisierung von Attributen.

In unserem Fall wollen wir dafür ja dem Konstruktor zwei Werte übergeben, die er dann den beiden Attributen zuweist.

Also schreiben wir doch einfach mal den Code hierfür. Das sollte leicht getan sein, sollte der Konstruktor also so aussehen:

                    
    public Auto(Color color, String model){ 
        color = color;
        model = model;
    }
                    
                

Nun ja...

Das ist doch schon etwas sehr verwirrend.

Der Java-Compiler versteht zwar genau, was wir eigentlich meinen, wir selbst sind allerdings etwas verwirrt.

Um diese Verwirrung zu beseitigen, verwenden wir für solche Fälle einfach das this Schlüsselwort, um eindeutig zu zeigen, welche Variable woherkommt.

                    
    public Auto(Color color, String model){ 
        this.color = color;
        this.model = model;
    }
                    
                

So ist nun klar ersichtlich, dass der Teil des Ausdrucks links neben dem Gleichheitszeichen sich eindeutig auf das Attribut der Klasse bezieht und der rechte Teil die beiden Parameter meint.

Basics - Unser Auto soll fahren!

Da unser Auto bisher noch nicht wirklich etwas kann und das ja doch echt ein bisschen langweilig wäre, fügen wir nun noch unsere zwei anfangs geplanten Methoden fahren() und hupen() ein.

Um mit diesen allerdings nicht den Rahmen zu sprengen, halten wir sie sehr simpel und geben in ihnen nur einen Hinweis in der Konsole aus, dass sie aufgerufen wurden.

Beide Methoden sollen dabei von außen aufgerufen werden können und nichts zurückgeben.

Damit lautet die Methoden-Definition wie folgt:

                    
    public void fahren(){ 
        System.out.println("Das Model " + this.model + " fährt");
    }

    public void hupen(){
        System.out.println("Das Model " + this.model + " hupt");
    }
                    
                

Hier verwenden wir, damit das Beispiel doch ein wenig interessanter wird, ein sehr praktisches Feature von Strings:

Diese lassen sich nämlich unter Verwendung des Pluszeichens (+) sehr einfach zusammenfügen.

In model ist ja der Modelname des Auto-Objekts als String gespeichert. Damit können wir ihn auch ganz einfach in einen Satz mit einfügen und uns diesen zusammengefügten Satz anschließend in der Konsole anschauen.

So sieht unsere fertige Auto Klasse nun vervollständigt wie folgt aus:

                    
    public class Auto{
        private Color color;
        private String model; 

        public Auto(Color color, String model){ 
            this.color = color;
            this.model = model;
        }

        public void fahren(){ 
            System.out.println("Das Model " + this.model + " fährt");
        }

        public void hupen(){
            System.out.println("Das Model " + this.model + " hupt");
        }

        public Color getColor(){
            return color;
        }
        public void setColor(Color newColor){
            color = newColor;
        }

        public String getModel(){
            return model;
        }
        public void setModel(String newModel){
            model = newModel;
        }
    }
                    
                

Basics - Das Auto fährt!

Mit unserer fertigen Auto Klasse können wir nun also unser erstes richtiges Auto Objekt erstellen.

Dafür gehen wir nun in die main() Methode der Main Klasse und erstellen in dieser unser Objekt.

Wie bereits in dem Abschnitt über den Konstruktor im Allgemeinen gezeigt, rufen wir bei der Erstellung eines Objektes einer Klasse den Konstruktor über das Schlüsselwort new gefolgt von seinem Namen auf.

Allerdings benötigen wir ja zunächst erst noch zwei Werte, die wir ihm übergeben können - Die Farbe und den Modelnamen.

Hierfür müssen wir nun zuerst in die erste Zeile in der Main.java Datei ebenfalls die Klasse Color importieren, da wir ja dem Konstruktor ein Objekt des Typs Color übergeben müssen.

Dann initialisieren wir einfach zwei Variablen in der main() Methode, farbe vom Typ Color und modelName vom Typ String.

Diesen können wir dann jeweils einen beliebigen Wert zuweisen. Für modelName suchen wir uns einfach einen Auto-Modelnamen, während farbe ja ein Objekt ist, weshalb wir hier den Konstruktor von Color aufrufen und ihm drei Werte für R, G und B übergeben müssen.

Diese beiden Variablen übergeben wir dann einfach dem Auto Konstruktor.

Um anschließend zu überprüfen, ob unser Auto-Objekt auch das tut, was es soll, können wir nun noch über das erstellte Objekt auto1 die beiden Methoden fahren() und hupen() aufrufen.

                    
    import java.awt.Color; 

    public class Main {
        public static void main(String[] args) {
            Color farbe = new Color(0, 0, 0); // schwarz
            String modelName = "AMG";
            
            Auto auto1 = new Auto(farbe, modelName);
            auto1.fahren();
            auto1.hupen();
        }
    }

    // Gibt auf der Konsole aus:
    // Das Model AMG fährt
    // Das Model AMG hupt
                    
                

Durch dieses Snippet sollte auch gleich klar werden, wie man Methoden, die als public definiert sind über ein Objekt aufrufen kann.

Probiere doch einfach mal dir nur den Modelnamen des Autos auf der Konsole ausgeben zu lassen oder ein zweies Auto-Objekt auto2 zu erstellen, welches dann allerdings eine andere Frabe und einen anderen Modelnamen haben soll. Rufe dann auch hier die beiden Methoden auf und schau, was auf der Konsole ausgegeben wird.

Abschließend sei noch gesagt, dass es auch kürzer als in dem Beispiel oben geht, da wir die beiden Variablen farbe und modelName eigentlich nicht benötigen, sondern deren Werte direkt dem Konstruktor übergeben können.

Damit lässt sich das Programm ein wenig abkürzen:

                    
    import java.awt.Color; 

    public class Main {
        public static void main(String[] args) {
            Auto auto1 = new Auto(new Color(0, 0, 0), "AMG");
            auto1.fahren();
            auto1.hupen();
        }
    }

    // Gibt auf der Konsole aus:
    // Das Model AMG fährt
    // Das Model AMG hupt
                    
                

Wenn du noch etwas mehr über JAVA erfahren möchtest, dann kannst du gerne einmal auf dieser Website (Vor allem in Kapitel 1) vorbeischauen: Java Tutorial (leider nicht auf Smartphones nutzbar)