Du verwendest einen veralteten Browser. Es ist möglich, dass diese oder andere Websites nicht korrekt angezeigt werden. Du solltest ein Upgrade durchführen oder ein alternativer Browser verwenden.
Es gibt drei Klassen: MyClass, MySubClass und MyChildClass. Dabei ist MyClass die direkte Basisklasse für die anderen zwei:
Code:
public class MyClass {
private static int counter;
public static void setCounter(int counter) {
MyClass.counter = counter;
}
public static int getCounter() {
return counter;
}
}
Code:
public class MySubClass extends MyClass {
}
Code:
public class MyChildClass extends MyClass {
}
D.h. alle drei Klassen haben das Attribut counter -- die Basisklasse von sich aus und die abgeleiteten erben es.
Was ich nicht verstehe, ist, warum beim Verändern des Wertes des Attributs counter einer (egal welcher von den drei) Klasse, sich auch die Werte der counter-Attribute der restlichen zwei Klassen ändern.
Code:
public class Main {
public static void main (String[] args) {
MyClass myClass = new MyClass();
MySubClass mySub = new MySubClass();
MyChildClass myChild = new MyChildClass();
myClass.setCounter(123);
System.out.println("MyClass.counter = " + MyClass.getCounter());
System.out.println("MySubClass.counter = " + MySubClass.getCounter());
System.out.println("MyChildClass.counter = " + MyChildClass.getCounter());
MySubClass.setCounter(456);
System.out.println("MyClass.counter = " + MyClass.getCounter());
System.out.println("MySubClass.counter = " + MySubClass.getCounter());
System.out.println("MyChildClass.counter = " + MyChildClass.getCounter());
MyChildClass.setCounter(789);
System.out.println("MyClass.counter = " + MyClass.getCounter());
System.out.println("MySubClass.counter = " + MySubClass.getCounter());
System.out.println("MyChildClass.counter = " + MyChildClass.getCounter());
}
}
Nein, tun sie nicht.
Statische Attribute werden niemals vererbt. Die Subklassen können zwar ohne Qualifizierung auf die statischen Methoden der Superklasse zugreifen, aber es ist immer MyClass.getCounter(). Das ist meiner Meinung nach eine kleine Designschwäche von Java. Du solltest deine IDE so einstellen, dass sie hier einen Fehler oder mindestens eine Warnung anzeigt.
Wenn du willst, dass die Unterklassen "eigene" counter bekommen, gib sie ihnen doch einfach:
Code:
public class MySubClass extends MyClass {
private static int counter;
public static void setCounter(int counter) {
MySubClass .counter = counter;
}
public static int getCounter() {
return counter;
}
}
Ja, anders wird es wohl nicht gehen. Nur halt doof, dass man dann die setCounter-Methode nicht einfach vererben kann, sondern in jeder Unterklasse anpassen muss... Aber das ist offensichtlich unvermeidlich.
Genau, aber man kann es zumindest etwas abmildern:
Code:
public class MyClass {
public static Counter counter = new Counter();
protected static class Counter {
private int counter;
public void set(int counter) {
this.counter = counter;
}
public int get() {
return counter;
}
}
}
public class MySubClass {
public static Counter counter = new Counter();
}
MyClass.counter.set(123);
MySubClass.counter.set(456);
Die Subklassen können zwar ohne Qualifizierung auf die statischen Methoden der Superklasse zugreifen, aber es ist immer MyClass.getCounter(). Das ist meiner Meinung nach eine kleine Designschwäche von Java.
Wenn das nicht ginge, hätte automatix z.B. dieses Problem nicht gehabt.
(Was aber ich eigentlich im Kopf hatte, war die Möglichkeit "objekt.statischeMethode()" zu schreiben, hat aber mit diesem Problem nicht viel zu tun.)
Eine weitere Frage zum Thema... Bei der Konstellation, wenn in allen drei Klassen das Attribut counter definiert ist, liefert die Methode getCounter() immer den Wert des Attributs counter der Basisklasse zurück. Erst wenn man die Methode in den abgeleiteten Klassen überschreibt, kriegt man den "richtigen" Counter zurückgeliefert... Warum?
Weder statische Felder noch statische Variablen werden vererbt. Die getCounter-Methode ist fest an die counter-Variable der entsprechenden Klasse gebunden. Über die Unterklasse kannst du die Methode zwar (syntaktisch) aufrufen, aber intern wird daraus ein "Oberklasse.methode()" gemacht. Wie gesagt, ein kleines Problem.
public class MyClass {
public static Counter counter = new Counter();
protected static class Counter {
private int counter;
public void set(int counter) {
this.counter = counter;
}
public int get() {
return counter;
}
}
}
public class MySubClass extends MyClass {
public static Counter counter = new Counter();
}
Wenn sie nicht protected wäre, könnte MySubClass ja kaum eine neue Instanz erzeugen, gell?
Und wozu das gut sein soll ist ja wohl klar: Statt den Code mit dem set- und get-Methoden in jeder Unterklasse zu wiederholen (wie in meinem ersten Beispiel), steckt er jetzt in einer innerhalb der Vererbungshierarchie wiederverwendbaren Klasse.