# Methoden in abstrakter Klasse: public oder protected?



## Ocean-Driver (18. Feb 2008)

Hallo,


Ich stelle mir die Frage, ist es wirklich egal ob die Methoden / Konstruktoren protected oder public sind?
Ich mein, da die Klasse abstrakt ist, reicht es ja die Methoden öffentlich zu lassen, da sie an dem abstrakten Objekt direkt ja nicht genutzt werden kann. 

Sollten die Attribute in einer abstrakten Klasse private oder protected sein?



Und, wenn ich über super(); den Konstruktor der Oberklasse aufrufe, und dort Methoden verwendet werden, werden dann auch die Methoden aus der Oberklasse verwendet, oder die aus der abgeleiteten Klasse?


Danke schonmal.


----------



## HLX (18. Feb 2008)

Ocean-Driver hat gesagt.:
			
		

> Hallo,
> 
> 
> Ich stelle mir die Frage, ist es wirklich egal ob die Methoden / Konstruktoren protected oder public sind?


Nein.



			
				Ocean-Driver hat gesagt.:
			
		

> Ich mein, da die Klasse abstrakt ist, reicht es ja die Methoden öffentlich zu lassen, da sie an dem abstrakten Objekt direkt ja nicht genutzt werden kann.


An der konkreten Ausprägung kann sie genutzt werden. 



			
				Ocean-Driver hat gesagt.:
			
		

> Sollten die Attribute in einer abstrakten Klasse private oder protected sein?


private



			
				Ocean-Driver hat gesagt.:
			
		

> Und, wenn ich über super(); den Konstruktor der Oberklasse aufrufe, und dort Methoden verwendet werden, werden dann auch die Methoden aus der Oberklasse verwendet, oder die aus der abgeleiteten Klasse?


Die aus der Oberklasse, solange du sie nicht überschrieben hast.


----------



## maki (18. Feb 2008)

> Sollten die Attribute in einer abstrakten Klasse private oder protected sein?


Je nachdem, wo du sie brauchst.
Nur in der abstrakten Klasse -> private.
Soll es möglich sein das Unterklassen direkt darauf zugreifen, dann protected.

Es ist eigentlich immer dasselbe  egal ob abstract oder nicht...


----------



## tfa (18. Feb 2008)

maki hat gesagt.:
			
		

> Soll es möglich sein das Unterklassen direkt darauf zugreifen, dann protected.


Oder private mit den entsprechenden (public oder protected) Gettern in der Oberklasse.

EDIT: OK, das ist dann kein _direkter_ Zugriff mehr.


----------



## maki (18. Feb 2008)

(zu spät)


----------



## HLX (18. Feb 2008)

tfa hat gesagt.:
			
		

> Oder private mit den entsprechenden (public oder protected) Gettern in der Oberklasse.



Genau. Das bevorzuge ich grundsätzlich und rate daher immer zu privaten Variablen.


----------



## André Uhres (18. Feb 2008)

Zusammenfassend könnte man sagen, dass man anhand der Definition der Schlüsselwörter 
sorgfältig abwägen sollte, was jeweils zutrifft:
"public" sind alle Schnittstellen, die die ganze Welt sehen soll.
"protected" ist alles, was für Unterklassen interessant sein kann.
"private" ist alles, was nur die Klasse selbst sehen soll (hier sollte man besonders vorsichtig sein,
weil ein private an der falschen Stelle die Wiederverwendbarkeit der Klasse unnötig einschränkt;
im Zweifelsfall lieber protected statt private wählen).


----------



## Der Müde Joe (18. Feb 2008)

zum nachlesen:
http://java.sun.com/docs/books/tutorial/java/javaOO/accesscontrol.html


----------



## Ocean-Driver (18. Feb 2008)

Hi,


Ok, also attribute immer private, methoden am besten öffentlich, weil sie ja an den geerbten Klassen genutzt werden können. 

Konstruktoren hingegen, können ja public oder protected sein,oder?


----------



## HLX (18. Feb 2008)

Das wurde bereits ausgiebig erläutert. 

Ob public oder protected hängt davon ab, ob du einen Zugriff außerhalb des package zulassen willst oder nicht. Das gilt sowohl für Konstruktoren, als auch für Methoden. Hier gibt es keinen generellen "best case".

Falls du dir nicht sicher bist, mach deine Methoden erstmal private. Wenn du dann feststellst, dass deine Funktion in den Unterklassen verfügbar sein muss, ändere die Sichtbarkeit auf protected. Wenn darüber hinaus eine generelle Verfügbarkeit bestehen muss, mach sie public. Schränke die Sichtbarkeit erstmal soweit wie möglich ein. Das trägt auch zur Übersichtlichkeit bei.


----------



## André Uhres (19. Feb 2008)

HLX hat gesagt.:
			
		

> ..Wenn du dann feststellst, dass deine Funktion in den Unterklassen verfügbar sein muss..


Das ist ein heikles Problem. Wenn es eine Klasse ist, die andere benutzen und erweitern sollen, 
dann ist nicht unbedingt vorhersehbar, welche Funktion in ihrem jeweiligen Kontext verfügbar oder erweiterbar sein muss. 
Deshalb sagte ich schon oben, im Zweifelsfall eher protected wählen als private :wink:


----------



## Guest (19. Feb 2008)

Und Vorsicht beim Aufruf überschriebener Methoden aus dem Super-Konstruktor heraus. Am besten keine 
virtuelle Methoden in Konstruktoren verwenden.
z.B.
	
	
	
	





```
abstract class A
{
   public A()
   {
      namenAusgeben();
   }

   protected abstract void namenAusgeben();
}

class B extends A
{
   private String name = "Brunhilde";

   public B()
   {
      super();
   }

   protected void namenAusgeben()
   {
      System.out.println(name); // name ist noch nicht initialisiert!
   }
}
```


----------



## HLX (19. Feb 2008)

André Uhres hat gesagt.:
			
		

> Das ist ein heikles Problem. Wenn es eine Klasse ist, die andere benutzen und erweitern sollen,
> dann ist nicht unbedingt vorhersehbar, welche Funktion in ihrem jeweiligen Kontext verfügbar oder erweiterbar sein muss.
> Deshalb sagte ich schon oben, im Zweifelsfall eher protected wählen als private :wink:



Wenn ich eine Schnittstelle entwickle, sollte mir allerdings auch klar sein, welche Funktionalität ich veröffentlichen möchte und welche nicht. Ich bezog mich eher auf den Fall, dass der Entwickler sich noch nicht im Klaren darüber ist. Da sage ich, im Zweifelsfall erstmal verbergen.


----------



## André Uhres (19. Feb 2008)

Niemals! Bitte!

Eine Dialog-Klasse könnte z.B. eine Methode "handleOKBtn()" enthalten.
Jetzt will ich die Funktionalität von handleOKBtn() ändern und den Rest der Klasse
wiederverwenden. Wenn diese Methode private ist, müsste ich die ganze Klasse neu implementieren,
also das Rad neu erfinden.

Andererseits, wenn solche Helper-Methoden protected statt private sind,
könnte ich einfach die Bedeutung der Methode handleOKBtn() neu definieren und die
ganze Klasse wiederverwenden.

Wenn du also Klassen entwickelst, die andere benutzen werden, kannst du nie sicher sein,
was sie aus der Klasse machen werden. Wenn es jedoch dein Ziel ist, die
Wiederverwendbarkeit zu fördern, dann kannst du deine Klasse erweiterbar machen, indem du die
solche Helper-Methoden protected machst. Zudem gibst du vor der Öffentlichkeit keine
Sicherheit preis, weil "protected" die Benutzer daran hindert, die Methode direkt zu
gebrauchen. Andererseits haben diejenigen, die von deiner Klasse erben, Zugang zu diesen
Helper-Methoden. Allgemein musst du jedoch davon ausgehen, dass die Leute, die die
Klasse erweitern, wissen was sie tun. Selbst wenn sie es nicht wissen, dann ist das Schlimmste,
was sie tun können, dass sie ihre abgeleitete Klasse kaputtmachen.

"protected" für Helper-Methoden zu wählen, gibt deiner Klasse einen Maximum an Flexibilität, 
ohne die Kapselung aufzugeben.


----------



## HLX (19. Feb 2008)

Genau. Damit hast du einen konkreten Grund, diese Methode protected zu machen.

Ich prüfe zuerst konkret, ob  ich jeweils die entsprechende Flexibilität gewährleisten möchte. Bei Helper-Methoden oder gar Helper-Klassen ist das i.d.R. obligatorisch. Je tiefer ich jedoch in ein zusammenhängendes System komme, in dem es wenig Allgemeingültigkeiten gibt und das bestimmten Anforderungen unterliegt, desto hilfreicher kann das Verbergen von Funktionen sein, da hier ggf. Dinge behandelt werden, die auf den ersten Blick nicht sichtbare, negative Auswirkungen auf die Anwendung haben.

Ich bin somit gezwungen, mich damit auseinanderzusetzen und mein Vorgehen, ggf. auch das Konzept zu hinterfragen. So laufe ich nicht so schnell Gefahr meine Flexibilität für das Umgehen von Problemen und hacken von schnellen Lösungen zu missbrauchen. Dabei kann man sich letztendlich verzetteln und die Änderbarkeit zentraler Funktionalität erschweren.


----------



## tfa (19. Feb 2008)

Ich finde, eine gute Kapselung und geringe Kopplung sind allemal wichtiger als eine (eventuell mögliche) Wiederverwendung durch Vererbung. 
Vererbung sollte in der OOP eine "is-a"-Beziehung abbilden und nicht dem Quelltext-Recycling dienen. Das geht z.B. besser durch Komposition und Delegation. 
In so fern bin ich der Meinung von HLX, lieber private als protected.


----------



## André Uhres (19. Feb 2008)

Ja gut, Zweifelsfall hatte ich ja auch nicht im Sinne von undurchsichtig gemeint. Die Vokabel war wohl nicht glücklich gewählt.


----------

