# statische Attribute: Vererbung und Zugriff darauf



## automatix (26. Okt 2008)

Hallo!

Ein Verständnisproblem...

Es gibt drei Klassen: *MyClass*, *MySubClass* und *MyChildClass*. Dabei ist MyClass die direkte Basisklasse für die anderen zwei:

```
public class MyClass {
	
	private static int counter;
	
	public static void setCounter(int counter) {
		MyClass.counter = counter;
	}
	
	public static int getCounter() {
		return counter;
	}
	
}
```


```
public class MySubClass extends MyClass {
	
}
```


```
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.


```
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());
		
	}

}
```



> MyClass.counter = 123
> MySubClass.counter = 123
> MyChildClass.counter = 123
> MyClass.counter = 456
> ...


Kann jemand sagen, warum alle drei Attribute nicht *dasgleiche*, sondern *dasselbe* referenzieren?

Danke.


----------



## tfa (26. Okt 2008)

automatix hat gesagt.:
			
		

> D.h. alle drei Klassen haben das Attribut _counter_ -- die Basisklasse von sich aus und die abgeleiteten erben es.


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.


----------



## automatix (26. Okt 2008)

Stimmt, mein Fehler...

MyClass.counter = counter;


----------



## Landei (26. Okt 2008)

Wenn du willst, dass die Unterklassen "eigene" counter bekommen, gib sie ihnen doch einfach:

```
public class MySubClass extends MyClass {
   private static int counter;
   
   public static void setCounter(int counter) {
      MySubClass .counter = counter;
   }
   
   public static int getCounter() {
      return counter;
   }   
}
```


----------



## automatix (26. Okt 2008)

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.


----------



## Lim_Dul (27. Okt 2008)

Unter anderem Deshalb sollte man statische Attribute vermeiden.


----------



## Landei (27. Okt 2008)

*doppeldoppelpostpost*


----------



## Landei (27. Okt 2008)

Genau, aber man kann es zumindest etwas abmildern: 


```
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);
```


----------



## Leroy42 (27. Okt 2008)

tfa hat gesagt.:
			
		

> 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.



 :shock: Wieso das denn?  ???:L


----------



## tfa (27. Okt 2008)

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.)


----------



## automatix (27. Okt 2008)

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?

P.S.





			
				Landei hat gesagt.:
			
		

> *doppeldoppelpostpost*


"doppeldoppelpostpost" ist meiner Meinung nur dann problematisch, wenn man mehrmals dasgleiche innnerhalb eines Forums schreibt.


----------



## tfa (28. Okt 2008)

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.


----------



## Soi (28. Okt 2008)

Landei hat gesagt.:
			
		

> ```
> public class MyClass {
> 
> public static Counter counter = new Counter();
> ...




--> public class MySubClass extends MyClass


----------



## automatix (29. Okt 2008)

Warum ist die innere Klasse Counter protected und wozu soll das Ganze gut sein?


----------



## Landei (29. Okt 2008)

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.


----------



## automatix (29. Okt 2008)

Achso... OK. Ich denke, ich sollte mich mit der inneren Klassen näher befassen...  Danke.


----------

