# Direkten Aufruf von Methoden aus Superklassen verhindern



## Rumborak (8. Mai 2004)

Hallo zusammen,

gibt es in Java eigentlich die Möglichkeit, in einer abgeleiteten Klasse den direkten Aufruf von Methoden der Basisklasse zu verhindern? Also wenn ich z. B. eine Klasse schreibe, die von einer anderen abgeleitet ist, möchte ich sicherstellen, daß nur die in der neuen Klasse definierten Methoden verwendet werden können und es nicht möglich ist, diese durch den direkten Aufruf von übergeordneten Methoden zu umgehen.
Bsp:
	
	
	
	





```
class Stackdemo extends Stack {

	/**
	* Entfernen und Rueckgabe des obersten Elements:
	*/
	Object popElem() {

		// Waechter:
		if(this.empty())
			return null;

		return this.pop();

	}
...
```
Die Methode "popElem()" verhindert hier das Auftreten der _EmptyStackException_. Wenn aber die übergeordnete Methode "pop()" der Basisklasse "Stack" direkt benutzt wird, ist der ganze Aufwand für die Katz´...!


----------



## Beni (8. Mai 2004)

Du kannst die Methoden der Superklasse kurzerhand überschreiben:


```
public class StackDemo extends Stack{
  public Objetct pop(){
    if( empty() )
      return null;
    else
      return super.pop();
  }
}
```

Sollte allerdings die Methode mit _final_ deklariert sein, hilft wohl nur noch ein Delegate:


```
public class StackDemo{
  private Stack stack = new Stack();

  public Object pop(){
    if( stack.empty() )
      return null;
    else
      return stack.pop();
  }
}
```

mfg Beni


----------



## Rumborak (8. Mai 2004)

Beni hat gesagt.:
			
		

> Du kannst die Methoden der Superklasse kurzerhand überschreiben:
> 
> 
> ```
> ...



Danke Beni, die erste Version war´s schon!


----------



## Xenophon (25. Mai 2004)

Hallo!

Ich habe eine ähnliche Frage, nur möchte ich in einer abgleiteten Klasse eine Methode der Superklasse überladen und den Aufruf der eigentlichen Methode aus der Superklasse verhinderten. Als Beispiel mal folgendes:


```
public class Superklasse
{
    public void set(Model model)
    {
        this.model = model;
    }
}

public class Klasse extends Superklasse
{
    public void setModel(ExtendetModel model)
    {
        this.model = model;
    }
}
```

ExtendetModel erbt dabei natürlich von Model. Den Aufruf von "setModel()" will ich nun verhinderen, da die zweite Klasse ja ein spezielles Model zum arbeiten braucht. Bleibt mir hier nur das Überschreiben der Methode "setModel()" und Überprüfen durch "instanceof" oder gibt es noch eine andere Möglichkeit? Das herabsetzen der Sichtbarkeit funktioniert ja leider nicht. Danke für Eure Hilfe.

MfG

Xenophon


----------



## Pulvertoastman (25. Mai 2004)

Das verstehe ich nicht. Wenn ExtendedModel von Model erbt, brauchst du doch keine weitere set-Methode.


----------



## Guest (26. Mai 2004)

...um Methoden einer Superklasse in einer abgeleiteten Klasse zu überlagen, muß die Signatur der Methode in der Sohnklasse genau der Signatur der zu überschreibenden Methode entsprechen! Also zu deutsch: Du deklarierst eine neue Methode, die exakt gleich heißt und die gleichen Parameter entgegennimmt. Der Zugriff aus der Sohnklasse auf die Methoden der Vaterklasse ist dann zwar noch mit "super.Methodenname()" möglich, nicht aber der direkte Aufruf von außen!


----------



## Guest (26. Mai 2004)

Pulvertoastman hat gesagt.:
			
		

> Das verstehe ich nicht. Wenn ExtendedModel von Model erbt, brauchst du doch keine weitere set-Methode.



Naja, meine erbende Klasse erwartet ja ein spezielleres Model (also ein ExtendedModel und nicht nur ein Model). Das ExtendedModel soll ja neue Methoden anbieten, mit denen dann die Klasse arbeitet. Also sollte es nicht möglich sein, nur ein Model zu setzten, da dieses die benötigten Methoden ja nich hat. Hoffe das war jetzt verständlicher.



			
				Gast hat gesagt.:
			
		

> Du deklarierst eine neue Methode, die exakt gleich heißt und die gleichen Parameter entgegennimmt.



Das ist meiner Ansicht nach ja ein Überschreiben. Da ich aber wie gesagt ein spezielles Model brauche, müsste ich dabei mit instanceof prüfen oder?(siehe mein Posting)


----------



## Pulvertoastman (26. Mai 2004)

Anonymous hat gesagt.:
			
		

> Pulvertoastman hat gesagt.:
> 
> 
> 
> ...



Ich denke, dass du in diesem Fall dann einen Designfehler hast. Wenn SuperKlasse keine Models bearbeiten kann, ist es dann wohl auch keine Klasse, die nämlich Models bearbeiten kann.


----------



## Xenophon (27. Mai 2004)

Ich glaub wir reden ein wenig an einander vorbei. Ich bring noch mal ein neues Beispiel, mit dem das Problem besser erkennbar ist. Also hier etwas Code.

```
public class Model
{
//hier kommen Methoden, die jedes Model hat zB. addView(View view)
}

public class NamedModel extends Model
{
    public void setName(String name)
    {
        this.name = name;
    }

    public String getName()
    {
        return name;
    }
}

public class View
{
    public void setModel(Model model)
    {
        this.model = model;
    }

    public Model getModel()
    {
        return model;
    }
}

public class NamedModelView extends View
{
    public void setNamedModel(NamedModel model)
    {
        setModel(model);
    }

    public NamedModel getNamedModel()
    {
        return (NamedModel) getModel();
    }
}
```
Der Punkt ist nun der, das NamedModelView auch ein NamedModel benötigt, da sie den Namen von Model holt und ein normales Model die Eigenschaft nicht besitzt. Deshalb soll der direkte Aufruf "setModel(Model model)" von außen verhindert werden.


----------



## bygones (27. Mai 2004)

inuitiv: streich die setModel methode aus View raus und mach die Variable protected. 
Oder mach die Methode setModel protected - so können nur Klassen in der Vererbungshierarchie dies nutzen 
(hoffe ich verwechsle das nicht mit "im gleichen package" - aber das ließe sich ja auch regeln)


----------



## Pulvertoastman (27. Mai 2004)

Xenophon hat gesagt.:
			
		

> Der Punkt ist nun der, das NamedModelView auch ein NamedModel benötigt, da sie den Namen von Model holt und ein normales Model die Eigenschaft nicht besitzt. Deshalb soll der direkte Aufruf "setModel(Model model)" von außen verhindert werden.



Sei mir nicht böse, aber ich bleibe bei meiner Ansicht, dass namedModelView dann kein View mehr ist. Was du vorhast ist meiner Ansicht nach keine Spezialisierung, da die abgeleitete Klasse nicht mehr typkompatibel zu Oberklasse ist. Dadurch verletzt du eine wichtige Regel bei der Vererbung.

Eine Möglichkeit aus dem Dilemma ist eine Fallunterscheidung in deiner Klasse, die garantiert, das alle Methoden, die ein NamedModel benötigen z.B. einen Fehler werfen, wenn das Model kein NamedModel ist.


----------



## Xenophon (30. Mai 2004)

Pulvertoastman hat gesagt.:
			
		

> Eine Möglichkeit aus dem Dilemma ist eine Fallunterscheidung in deiner Klasse, die garantiert, das alle Methoden, die ein NamedModel benötigen z.B. einen Fehler werfen, wenn das Model kein NamedModel ist.



Also ich habe jetzt eine Methode "acceptModel(Model model)" eingeführt, die von einer View eventuell zu überschreiben ist. Bei "setModel" wird diese benutzt und bei "false" eine Exception geworfen.



			
				Pulvertoastman hat gesagt.:
			
		

> Ich denke, dass du in diesem Fall dann einen Designfehler hast. Wenn SuperKlasse keine Models bearbeiten kann, ist es dann wohl auch keine Klasse, die nämlich Models bearbeiten kann.



Wie wäre das Design Deiner Meinung nach richtig?


----------

