Getter und setter richtig verstanden & vererbung erklären?

2 Antworten

Vom Verständnis ist es dir vielleicht schon klar, aber dennoch birgt dein Code noch einige Fehler.

private int x = 10;

public void setX(int x){ this.x = x; }
public int getX(){ return this.x; }
  1. Das Feld, dem du einen Getter/Setter gibst, sollte mindestens den protected access modifier haben. Sonst macht das Data Hiding-Prinzip keinen großen Sinn mehr.
  2. Laut Konvention setzt sich der Name eines Getters/Setters aus get/set und dem Namen des Felds zusammen.
  3. Da der Getter einen Wert zurückgibt, muss auch ein Rückgabetyp definiert werden.

(...) kann mithilfe von instanzen aus anderen klassen abgerufen werden (...)

Das gilt für Getter und Setter, sofern sie Instanzmethoden sind. Denn es können ja auch Getter/Setter für statische Felder definiert werden.

Vererbung:


Vererbung bedeutet, dass eine Basisklasse um Zustände erweitert wird.
Stell dir vor, du möchtest eine Gruppe an Menschen in einem Programm darstellen: Programmierer, Bauarbeiter und Ärzte. Sie alle haben bestimmte Fähigkeiten und Eigenschaften, die sie untereinander teilen. Z.B. können sie alle essen, schlafen, laufen, sprechen. Um diese Basiseigenschaften nicht immer neu schreiben zu müssen, kann man alle Menschen zu einem abstrakten Oberbegriff vereinen: Mensch. Dies wird die Basis-/Superklasse. Alle Kind-/Subklassen stellen lediglich eine Erweiterung oder konkretere Implermentierung dar.

Codebeispiel (in Java):
class Mensch {
 public void essen() { System.out.println("Isst"); }
 
public void laufen() { System.out.println("Läuft"); }
public void sprechen() { System.out.println("Spricht"); } }
class Programmierer extends Mensch { public void programmieren(){ // ... this.essen(); }
@Override public void sprechen() { System.out.println("Hello World!"); }
}
Programmierer hans = new Programmierer(); hans.laufen(); // Ausgabe: "Läuft"

Wie du siehst, könnte der Programmierer nun auch auf Methoden zugreifen, die von der Basisklasse vererbt wurden (essen, laufen, ...). Ebenso können vererbte Methoden überschrieben werden, um bspw. ein konkreteres Verhalten zu definieren.

1. Vorteil also: Redundanter Programmcode kann eingespart werden. Ein Problem stellt lediglich das Diamond-Dilemma dar. Dazu solltest du allerdings selbst recherchieren.

Der 2. Vorteil entsteht durch Polymorphie, welche auf der Fähigkeit der Vererbung aufbaut:
Mensch mensch = new Programmierer();

Ein Objekt kann in einer Referenz mit dem Typ der Basisklasse gespeichert werden. Dies funktioniert, weil Basis- und Subklasse eine gemeinsame Basis haben. Möglich ist dies logischerweise nur in diese Richtung (Sub in Basis).
Nun zu einem komplexeren Beispiel:
Mensch[] menschen = new Mensch[3];
menschen[0] = new Programmierer();
menschen[1] = new Bauarbeiter();
menschen[2] = new Arzt();

for(Mensch mensch : menschen){ mensch.essen(); mensch.sprechen(); }

Alle aufgeführten Klassen sind Subklassen von Mensch und können daher in dem Array aufgenommen werden. Und da der "offizielle" Datentyp die Methoden essen und sprechen kennt, kann er sie auch in jedem Fall in der Schleife aufrufen.
Konkrete Methoden der Subklasse sind allerdings nicht mehr bekannt, außer man nimmt einen Typecast vor:
menschen[0].programmieren(); // geht nicht, die Klasse Mensch kennt die Methode nicht
((Programmierer)menschen[0]).programmieren(); // nach dem Typecast funktioniert es wieder

Während der Ausgabe der Schleife kommt es übrigens zu einer interessanten Besonderheit der Polymorphie: Der späten Bindung.

Während der Laufzeit wird bei Aufruf der Methoden die Vererbungskette durchlaufen und das letzte Vorkommen der Eigenschaft/Methode genutzt. Im ersten Fall ist dies die überschriebene Methode in der Klasse Programmierer. In den nachfolgenden Fällen ist es die Implementation der Basisklasse.
So können 3 Begriffe definiert werden:
  • Überdeckung: Ein Feld überdeckt ein Feld seiner Basisklasse, wenn es den gleichen Namen und Datentyp besitzt.
  • Überladung: Eine Methode überlädt eine Methode der Basisklasse, wenn sie eine andere Signatur besitzt.
  • Überschreiben: Eine Methode überschreibt eine Methode der Basisklasse, wenn sie die gleiche Signatur besitzt.

Sowie der Begriff der Polymorphie selbst: Polymorphie bezeichnet die Fähigkeit eines Objekts, seinen eigenen Zustand (Eigenschaften und Methoden) zu kennen. Das heißt, auch wenn ein Objekt des Typs Programmierer in eine Referenz des Basistyps gelagert wird, vergisst das Objekt seinen Zustand nicht, und weiß, dass es ein Programmierer ist (nur die Referenz weiß es nicht).


Ausnahmefälle bei der Vererbung:
  • Felder/Methoden mit dem private access modifier werden nicht vererbt.
  • Statische Felder/Methoden werden nicht vererbt, können also auch nicht überschrieben werden.
  • Finale Methoden können nicht überschrieben werden.
  • Finale Klassen können keine Subklassen besitzen.

Hallo,

das Grunprinzip von Getter und Setter hast du verstanden. 

Ich möchte es dennoch kurz zusammenfassen:

Generell ist es in der Programmierung wichtig, dass du deine Variablen/Attribute von der Sichtbarkeit so restriktiv wie möglich und so offen wie nötig erstellst. Man sollte hierbei von "außen", also von anderen Objekten immer über die Setter/Getter gehen, da hier kontrolliert Veränderungen der Attribute vorgenommen werden können. 

Du hast beispielsweise die Klasse Auto mit dem Attribut alter (private int alter = 10;). Nun gibt es dafür einen Setter (public void setAlter(int alter){ this.alter = alter;}) und einen Getter (public int getAlter(){ return this.alter;}).

Man kann in dem Setter noch if/else-Bedingungen reinprogrammieren, um damit das Alter kontrolliert durch den Setter zu verändern. Außerdem ist es von der Konvention gängig den Namen des Setters mit set + Name des Attributs zu bilden. Also setAlter beispielsweise. Genauso verläuft es bei den Getter, Also getAlter beispielsweise.

Als Beispiel für die Vererbung nenne ich einfach einmal die Klasse Auto und die Klasse BMW i8. Die Klasse BMW i8 erbt von der Klasse Auto und erbt dadurch auch alle Eigenschaften und Methoden. In der Klasse Auto gibt es bereits eine Methode public void fahren(){}, die die Klasse BMW i8 ebenfalls benötigt. Falls es doch notwendig ist, kann die Klasse BMW i8 diese Methode immer noch erweitern oder komplett neu modifizieren.

Man greift deshalb auf die Vererbung zurück, um Redundanzen zu vermeiden. Soll heißen, wenn es noch Klassen gibt, die die Grundstruktur der Methoden aus der Klasse Auto benötigen, muss man diese nicht jedes mal neu in den Klassen programmieren.

In dem Artikel Programmiersprache Java ist die Programmiersprache Java und wichtige Elemente kurz erklärt http://www.andreasgeiger-it.de/programmiersprache-java/

Viele Grüße

Andreas

C# Variable in anderer Klasse verwenden

Guten Abend,

wie kann ich eine Variable aus einer Klasse in einer anderen Klasse verwenden? Hier mein Quellcode:

 public class Spielfeld
{
    int weite;
    int höhe;

    public void abmessungSpielfeld(int iweite, int ihöhe)
    {
        weite = iweite / 20;
        höhe = ihöhe / 20;
    }
}

public class Snake
{   
    public void neuerPunkt()
    {
        Random r = new Random();
        int zahl1 = r.Next(0, weite);
        int zahl2 = r.Next(0, höhe)
    }
}

Danke schonmal

...zur Frage

LWJGL lernen?

Wo kann ich am besten LWJGL lernen, gibt es dazu vielleicht ein Buch? Was muss ich (bzw. sollte ich können) um LWJGL zu lernen, also welche Themenbereiche von generell Java sollte ich kennen und anwenden können?

Ich will mich von LibGDX lösen und mit LWJGL anfangen.

LF und bitte begründete Antworten!

...zur Frage

Hallo zusammen! Brauche Hilfe in Java, bei einem Programm über Lottozahlen (Zufallszahlen). Danke im Voraus schon mal! ?

Mein Programm zieht 10-mal 6 Zufallszahlen. Das erste Problem ist, dass die Zahlen doppelt vorkommen können, und es auch tun. Mein zweites Problem ist, dass ich den Auftrag habe, angeben zu können welche Zahl wie oft gezogen wurde. Dies bezieht sich darauf, dass wir eine Statistik erstellen sollen, welche Zahl wie oft vorkommt, wenn man 1000-mal die 10 Zahlen ziehen lässt. Hier nun mein Programm : /** * * Beschreibung * * @version 1.0 vom 21.08.2015 * @author / public class ConLotto { // Anfang Attribute private static int [] ziehung = new int [6]; // Ende Attribute // Anfang Methoden public static void main(String[] args) { for (int i=0;i<10 ;i++ ) { bildeZiehungszahlen(); zeigeZiehungszahlen(); } // end of for } // end of main public static void bildeZiehungszahlen () { for (int i = 0 ; i < 6 ; i++) { ziehung [i] = 1+(int)(49Math.random()); } // end of for } public static void zeigeZiehungszahlen () { System.out.print (" Ziehung ergab:"); for (int i = 0;i<6 ;i++ ) { System.out.print(" " + ziehung [i]) ; } // end of for System.out.println(); } public static void anzahlZiehungszahlen () {

} // Ende Methoden } // end of class ConLotto

Danke im Voraus schon mal!

...zur Frage

C++: nicht definierter Verweis?

Templates.hpp

#ifndef TEMPLATES#define TEMPLATESnamespace templates{   template<class T>void set(T&, T);   template<class T>T get(T);}#endif

Templates.cpp

#include"Templates.hpp"namespace templates{   template<class T>void set(T &variable, T value)   {      variable=value;   }   template<class T>T get(T variable)   {      return variable;   }}

Test.cpp

#include<iostream>#include"Templates.hpp"namespace Test{   class CTest   {         int Test;      public:         CTest();         int Testfkt() const;   };}int main(){   Test::CTest Test;}namespace Test{   int CTest::Testfkt() const   {      return this->Test;   }   CTest::CTest()   {      templates::set<int>(this->Test, 10);   }}

Vom linker erhalte ich dann "Nicht definierter Verweis auf 'void templates::set<int>(int&, int)'

Was ist da falsch?

Einen schönen Dank schon mal. Stehe auf dem Schlauch.

...zur Frage

Wie sieht die Punktnotation in Java aus oder wie kann ich auf auf andere Klassen zugreifen?

Wie kann ich in der Klasse Telefon die Methoden aus der Klasse Telefonbuch verwenden ? Wenn ich es mit Punktnotation versuche wie z.B.

public void eintrag_hinzufuegen(String name)
{
    Telefonbuch.hinzufuegen(name);
}

, kommt die Fehlermeldung : non static method cannot be referenced from a static context

1)

import java.util.ArrayList;
public class Telefon
{
protected ArrayList <Telefonbuch> telefonbuch;
protected boolean eingeschaltet;
        
        public Telefon()
    {
        // initialise instance variables
        telefonbuch = new ArrayList <Telefonbuch>();
    }
    
    public void anrufen (String name)
    {
    }
    
    public void einschalten()
    {
        eingeschaltet = true;
    }
    
    public void telefonbuch_uebersicht()
    {
        
    }
    
    public void eintrag_hinzufuegen(String name)
    {
    }
    
    public void eintrag_entfernen(String name)
    {
    }
    
    public boolean eintrag_suchen(String name)
    {
    }
}

2)

import java.util.Arrays;

/**
 * Write a description of class Telefonbuch here.
 * 
 * @author (your name) 
 * @version (a version number or a date)
 */
public class Telefonbuch
{
    // instance variables - replace the example below with your own
    private int anzahl_eintrag;
    private int kapazitaet;
    private String[] name_liste;
    protected boolean gefunden;

    /**
     * Constructor for objects of class Telefonbuch
     */
    public Telefonbuch()
    {
        // initialise instance variables
        String [] name_liste = new String[kapazitaet];
        gefunden = false;
    }
    
    public void set_kapazitaet(int x)
    {
        kapazitaet = x;
    }
    
    public void telefonbuch_uebersicht()
    {
        for(int i=0; i < name_liste.length; i++)
        {
        System.out.println(name_liste[i]);
        }
    }
    
    public void hinzufuegen(String name)
    {
        
    }
    
    public void entfernen(String name)
    {
    }
    
    public boolean suchen(String name)
    {
        for(int i=0; i < name_liste.length; i++)
        {
         if(name_liste[i].equals(name))
         {
         gefunden = true;
         }
         else
         {
         //Abbruch
         }
        }
        return gefunden;
    }
}

...zur Frage

Java:Programm für Würfel

Hallo erstmal! Ich muss ein Java-Programm schreiben,in dem die Funktionen wurf() ,augen() (diese soll spezifisch dazu deinen,den wert als int zurückzugeben) und eine Funktion public static int augensumme(Wuerfel w1, Wuerfel w2) implementiert sind. Ich bin damit auch soweit durch,wollte dann jedoch das Programm testen und habe bemerkt,dass ich die main-methode vergessen habe. Jetzt versuche ich,die Zeile public static void main (String[] args) { hinzuzufügen,sobald ich jedoch die geschweifte Klammer setze,zeigt mir NetBeans massig "illegal start of expression" an. Wie kann ich das vermeiden und mein Programm lauffähig machen?

Hier der Code: import java.math.*; public class Wuerfel {

public int w1;
public int w2;

        public  Wuerfel() {
            wurf();  
        }
        
        public void wurf() {
            w1 = (int)(Math.random()*6) + 1;
            w2 = (int)(Math.random()*6) + 1;
        }
        
         public int augen() {
            return w1;
        }
         
     
        
    Falls sonstige Verbesserungsvorschläge gemacht werden,bin ich natürlich auch für diese dankbar!
...zur Frage

Was möchtest Du wissen?