Vererbung Basisklasse soll eigene Methode benutzen

Pepe Rohny

Aktives Mitglied
Hi,

ich habe ein grundsätzliches Problem: eine Basisklasse soll die eigene Methode benutzen und nicht die gleichartige der abgeleiteten Klasse.

Hier das Ganze mal als sourcecode:
Java:
class Test {

    Test() {
    }

    @Override
    public String toString() {
        return this.getClass().toString();
    }

    public static void main(String[] args) {
        System.out.println(new DerivedTest().toString());
    }

    private static class DerivedTest extends Test {

        DerivedTest() {
        }

        @Override
        public String toString() {
            return super.toString();
        }

    }

}

Kann mir jemand erklären was ich falsch mache?

Pepe
 

Haave

Top Contributor
Aber du rufst in Zeile 22 doch nur wieder die Methode der Superklasse auf (dafür dient das Schlüsselwort super)!
[JAVA=22]return super.toString();[/code]

Da musst du dann natürlich was anderes hinschreiben, versuch halt mal testweise sowas:
Java:
return "hallo";
 

andiv

Bekanntes Mitglied
Du rufst zwar mit super.toString() eine Methode der Basisklasse auf, aber dort wird ja this.getClass() aufgerufen und damit landest du in der getClass()-Methode der abgeleiteten Klasse. Probier doch mal statt super.toString() super.getClass().toString() aus.
 

Pepe Rohny

Aktives Mitglied
Probier doch mal statt super.toString() super.getClass().toString() aus.
Das wäre etwas anderes als das was ich brauche. Das muss bzw. sollte schon so wie beschrieben ablaufen. Mein (Verständnis-)Problem dabei ist, dass trotz "this" die abgeleitete Methode aufgerufen wird.

Hinweis: das Beispiel ist etwas vereinfacht. Die abgeleitete Methode macht - nachdem die Basis-Methode ihren Job erledigt hat - noch etwas. Daher ist es wichtig, dass in der Basisklasse die Basis-Methode ausgeführt wird.

Pepe
 
Zuletzt bearbeitet:

andiv

Bekanntes Mitglied
Das this kannst du dir an der Stelle sparen, das bewirkt gar nichts. getClass() wird von der abgeleiteten Klasse überschrieben und durch die Polymorphie wird automatisch die Methode in der abgeleiteten Klasse aufgerufen. Verwende Test.class.toString().
 

Andi_CH

Top Contributor
Du denkst in Klassen statt in Objekten.

Es wird immer die Methode in der abgeleiteten Klasse ausgeführt - das willst du ja auch, sonst hättest du die nicht überschrieben ;-)

Wenn du trotzdem den Code der Vaterklasse aufrufen willst geht das nur mit
Java:
super.funktionC();

Schau dir das folgende Beispiel an:

Der erste Teil der Ausgabe ist völlig klar - funktionA -> funktionB -> funktionC alle in der Superklasse

Der zweite Teil mag dich vielleicht überraschen
Die funktionA in der Subklasse ruft funktionB auf welche hier nicht implementiert ist - also wird der in der Superklasse implementierte code ausgeführt

Diese ruft die funktionC auf und, das es sich um ein Objekt der Subklasse handelt wird der Code in der Subklasse ausgeführt.

Zuerst die Ausgabe:
Code:
Aufruf funktionA direkt in der Superklasse
Superklasse.funktionA()
Superklasse.funktionB()
Superklasse.funktionC()

Aufruf funktionA in der Subklasse
Subklasse.funktionA()
Superklasse.funktionB()
Subklasse.funktionC()

Hier die Klassen:
Java:
public class Superklasse {

	protected void funktionA() {
		System.out.println("Superklasse.funktionA()");
		funktionB();
	}

	protected void funktionB() {
		System.out.println("Superklasse.funktionB()");
		funktionC();
	}

	protected void funktionC() {
		System.out.println("Superklasse.funktionC()");
	}
}

Java:
public class Subklasse extends Superklasse {

	@Override
	protected void funktionA(){
		System.out.println("Subklasse.funktionA()");
		funktionB();
	}

	@Override
	protected void funktionC() {
		System.out.println("Subklasse.funktionC()");
	}
}

Java:
public class Test {

	public static void main(String[] args) {
		Superklasse superKl = new Superklasse();
		Subklasse subKl = new Subklasse();

		System.out.println("Aufruf funktionA direkt in der Superklasse");
		superKl.funktionA();
		System.out.println();
		System.out.println("Aufruf funktionA in der Subklasse");
		subKl.funktionA();
	}
}
 
Zuletzt bearbeitet:

Pepe Rohny

Aktives Mitglied
Danke für die (Nach-)Hilfe!

Das mit dem ableiten bzw. überschreiben und wann welche Methode aufgerufen wird habe ich schon verstanden.

Mein Problem ist: kann ich in der Basis-Klasse die (Basis-)Methode aufrufen?

Mein Eindruck: nein. Jedenfalls ist es durch das Voranstellen von "this" nicht möglich. Schade eigentlich.

Um meine (eigentliche) Frage noch mal auf den Punkt zu bringen: ist mein Eindruck richtig - oder habe ich etwas übersehen (wie es doch geht)?

Pepe
 

Andi_CH

Top Contributor
???:L???:L???:L Verstanden? Warum fragst du denn?

Also du willst aus funktionB die funktionC in der Superklasse aufrufen?
Warum hast du die denn überschrieben?

Instanziere ein Objekt vom Typ Superklasse und dann geht es so wie du willst
Im Objekt vom Typ Subklasse ist die Methode überschrieben, das heisst schlicht und ergreifend nicht mehr sichtbar.

Wenn du das machen müsstest, hättest du die Methode der Vaterklasse nicht überschreiben sollen.

Also entweder die Richtig Klasse instanzieren oder der Methode in der Subklasse einen anderen Namen geben.
 
Zuletzt bearbeitet:

Pepe Rohny

Aktives Mitglied
Warum fragst du denn?

Weil ich wissen will, ob mein Eindruck richtig ist. Das schrieb ich doch schon in meinem letzten Beitrag :rolleyes:

Instanziere ein Objekt vom Typ Superklasse ...

Nee - is' nich. Die Basis-Klasse ist "abstract". Und das muss auch so sein.

Im Objekt vom Typ Subklasse ist die Methode überschrieben, das heisst schlicht und ergreifend nicht mehr sichtbar.

Is' wohl so. Und es gibt keine Möglichkeit da ran' zu kommen. Oder?

Trotzdem: Danke.

Pepe
 

tfa

Top Contributor
Dass man "super" benutzen kann, um die Methoden der Superklasse aufzurufen weißt du ja. Was möchtest du noch?

In deinem Beispiel gibt es nur ein Objekt der Klasse DerivedTest, also kann niemals "Test" heraus kommen.
 

Pepe Rohny

Aktives Mitglied
Was möchtest du noch?

Ganz einfach: die Basis-Klasse soll die in ihr deklarierte Methode benutzen und nicht die durch irgendeine abgeleitete bzw. überschriebene. Zumindest hätte ich das gerne. Anscheinend geht das aber nicht.

Der Hintergrund ist der folgende: eine abstrakte Basis-Klasse garantiert eine Eigenschaft. Diese Eigenschaft wird mittels des Konstruktors initialisiert, der die entsprechende set-Methode aufruft. In einer abgeleiteten Klasse wird die set-Methode überschrieben. Diese Methode (der abgeleiteten Klasse) ruft die überschriebene Methode (der Basis-Klasse) auf und macht dann noch etwas. Für dieses etwas wird eine Eigenschaft der abgeleiteten Klasse benutzt, die im Konstruktor initialisiert wird. Nur: wenn die Basis-Klasse die Methode (der abgeleiteten Klasse) aufruft, ist die Eigenschaft der abgeleiteten Klasse natürlich noch nicht initialisiert.

In deinem Beispiel gibt es nur ein Objekt der Klasse DerivedTest, also kann niemals "Test" heraus kommen.

Ach ja? Frag das Objekt doch mal ob es ein "Test" ist.

Es ist wohl so, dass beim Überschreiben die Überschriebene verschwindet bzw. nicht mehr erreichbar ist.

Allerdings: ich würde mich gerne eines besseren belehren lassen ...

Pepe
 
G

Gonzo17

Gast
Nur: wenn die Basis-Klasse die Methode (der abgeleiteten Klasse) aufruft, ist die Eigenschaft der abgeleiteten Klasse natürlich noch nicht initialisiert.

Die Basis-Klasse kann niemals die Methode einer abgeleiteten Klasse direkt aufrufen denke ich. Du kannst in der Sub-Klasse die überschriebene Methode um super.method() erweitern, dann wird die Methode der Basis-Klasse aufgerufen. Ansonsten wird die Methode der Basis-Klasse nur dann aufgerufen, wenn es wirklich ein Objekt vom Typ Basis-Klasse gibt. Wie denn auch sonst?
 
G

Gonzo17

Gast
Falsch gedacht. Probier's einfach mal aus.

Der code in meinem ersten Beitrag sollte das eigentlich zeigen.

Sorry aber zu welchem Zeitpunkt ruft denn da die Basis-Klasse die Sub-Klasse auf? Es ist doch vielmehr so, dass die Sub-Klasse eine Methode der Basis-Klasse aufruft. Das getClass() bezieht sich dabei auf die Sub-Klasse, weil die Methode ja auch von dieser ausgeführt wird und nicht von der Basis-Klasse.
Rufst du die Methode der Basis-Klasse direkt aus von einem Objekt der Basis-Klasse auf, dann wird dir getClass() natürlich auch das liefern, was du erwartest.

Java:
public class BasicClass {
	public void method() {
		System.out.println(getClass());
	}
	
	public static void main(String[] args) {
		BasicClass basic = new BasicClass();
		SubClass sub = new SubClass();
		
		basic.method();
		sub.method();
	}
}

class SubClass extends BasicClass{
	@Override
	public void method() {
		super.method();
	}
}

Edit: Das Beispiel soll eigentlich nur nochmal verdeutlichen, dass zuerst eine Variable vom Typ BasicClass die Methode aufruft, danach eine Variable vom Typ SubClass. Und die Methodenaufrufe beziehen sich eben immer auf das Objekt, das es ausführt, deswegen kommt auch beim zweiten Mal SubClass und nicht BasicClass heraus. Das ist vielleicht dein Denkfehler, dass du dich da zu sehr an den "Ort" der Methode klammerst.
 
Zuletzt bearbeitet von einem Moderator:

Andi_CH

Top Contributor
Dass man "super" benutzen kann, um die Methoden der Superklasse aufzurufen weißt du ja. Was möchtest du noch?

In deinem Beispiel gibt es nur ein Objekt der Klasse DerivedTest, also kann niemals "Test" heraus kommen.

Der Aufruf super bringt rein gar nichts

Ich bleibe mit den Namen bei meinem Beispiel:

Er hat ein Objekt vom Typ Subklasse
Er will aus der funktionB() (die es nur in der Superklasse gibt) die funktionC() aufrufen, will aber dass der Code Superklasse.funktionC() ausgeführt wird obwohl die funktionC() überschrieben ist.
Ich sag es jetzt halt mal direkt - wer das machen will hat entweder einen groben Architekturfehler begangen oder keine Ahnung von Vererbung!

Eine andere Art der Erklärung - du hast ein Objekt vom Typ Subklasse.
Da drin sind funktionA() und funktionC() implementiert - die funktionB() wird sozusagen in dieses Objekt kopiert - es gibt in diesem Objekt den Code den du ausführen willst gar nicht.

(Ich weiss, dass es so nicht wirklich stimmt, aber es verhält sich so wie wenn ... )
 

Pepe Rohny

Aktives Mitglied
Hier noch mal ein konkretes Beispiel:
Java:
public abstract class AbstractNamedEntity {

    private String name = null;

    public AbstractNamedEntity(String name) {
        setName(name);
    }

    public String getName() {
        return name;
    }

    public static void main(String[] args) {
        new NamedEntity("Java", new Database());
    }

    public void setName(String name) {
        this.name = name;
    }

    private static class NamedEntity extends AbstractNamedEntity {

        private final Database database;

        public NamedEntity(String name, Database database) {
            super(name);
            this.database = database;
        }

        @Override
        public void setName(String name) {
            super.setName(name);
            database.update(this);
        }
        
    }

    private static class Database {

        Database() {
        }

        public void update(NamedEntity namedEntity) {
        }

    }

}

Pepe

P.S.
Die NullPointerException kann man natürlich einfach vermeiden - schon klar -, aber so wird das Problem vielleicht klar(er).
 
Zuletzt bearbeitet:
G

Gonzo17

Gast
Musst du hier die Methode setName(String) im Konstruktor aufrufen? Denn da ist ja der (Denk-)Fehler begraben. Ich weiß nicht was du in deinem konkreten Beispiel noch so alles tun musst (außer den Namen zu übergeben), aber wenns wirklich nur das ist, kannst du dir den Aufruf auch sparen und da "nur" eine Zuweisung machen. Ansonsten gibts noch einige Alternativen, um das Problem zumindest hier zu lösen, aber da ich die genauen Anforderungen nicht kenne, ists natürlich schwer zu beurteilen.
 

Pepe Rohny

Aktives Mitglied
Musst du hier die Methode setName(String) im Konstruktor aufrufen? Denn da ist ja der (Denk-)Fehler begraben.Ich weiß nicht was du in deinem konkreten Beispiel noch so alles tun musst (außer den Namen zu übergeben), aber wenns wirklich nur das ist, kannst du dir den Aufruf auch sparen und da "nur" eine Zuweisung machen.

Die (Original-)Klasse garantiert, das die Eigenschaft (im konkreten Beispiel hier: name) immer erfüllt ist. Das wird dadurch verwirklicht, dass die Eigenschaft "privat" ist und nur mittels der set-Methode geändert werden kann. Eine einfache Zuweisung kommt daher nicht in Betracht. Weiterhin muss die Eigenschaft durch den Konstruktor initialisiert werden.

Was ich noch nicht verstanden habe: worin besteht der Denkfehler?

Ansonsten gibts noch einige Alternativen, um das Problem zumindest hier zu lösen, aber da ich die genauen Anforderungen nicht kenne, ists natürlich schwer zu beurteilen.

Die anderen Anforderungen sind kein Problem. Das eigentliche Problem ist, dass die überschriebene Methode nicht erreichbar ist.

Pepe
 

Illuvatar

Top Contributor
Wenn du willst, dass man sie nicht überschreiben kann: Mach ein "final" davor.
Wenn das nicht geht, weil die Methode manchmal doch überschrieben sein soll, musst du nochmal überlegen: bei der gleichen Methode kann nicht manchmal die Methode der Unterklasse und manchmal die Methode der Basisklasse rauskommen.
Das sollte dann wohl eher 2 Methoden sein, denk ich mal.
 

xehpuk

Top Contributor
Die (Original-)Klasse garantiert, das die Eigenschaft (im konkreten Beispiel hier: name) immer erfüllt ist. Das wird dadurch verwirklicht, dass die Eigenschaft "privat" ist und nur mittels der set-Methode geändert werden kann. Eine einfache Zuweisung kommt daher nicht in Betracht. Weiterhin muss die Eigenschaft durch den Konstruktor initialisiert werden.
Also ich hab das jetzt nicht verstanden. Was ist eine erfüllte Eigenschaft? Private Variablen können noch immer in der Klasse und deswegen auch insbesondere im Konstruktor zugewiesen werden, in der sie stehen. Daran ändert auch ein vorhandener Setter nichts.

Die anderen Anforderungen sind kein Problem. Das eigentliche Problem ist, dass die überschriebene Methode nicht erreichbar ist.
In Zeile 32 wird sie doch aufgerufen?
 

Andi_CH

Top Contributor
Was ich noch nicht verstanden habe: worin besteht der Denkfehler?

Das eigentliche Problem ist, dass die überschriebene Methode nicht erreichbar ist.

Der Denkfehler und das eigentliche Problem liegen IMO darin, dass du meine Erklärungen nicht verstanden oder wohl eher (Sorry wenn ich direkt bin) gar nicht wirklich gelesen hast.

Wer Code überschreibt will ganz bewusst, dass der überschriebene Code eben NICHT mehr ausgeführt wird - Punkt!

Es gibt eine Möglichkeit das doch zu tun und das ist es aus der abgeleiteten Klasse das mit
Code:
super.funktionB()
zu machen. Punkt.

Denk zur Laufzeit in Objekten und NICHT in Klassen! Wenn du ein Objekt der abgeleiteten Klasse hast gibt es kein "aus der Superklasse" ---- es gibt keine Superklasse, es gibt nur ein Objekt der Subklasse - Punkt.

Wenn sogar ich es begriffen habe, kann es nicht soooo schwieirig sein :bahnhof:
 
Zuletzt bearbeitet:
B

Beni

Gast
Ich löse ein ähnliches Problem meistens mit einer speziellen init-Methode, die von der Unterklasse aufgerufen werden muss. Das ist zwar nicht 100% sicher, aber für die meisten Fälle gut genug.

Java:
public abstract class Test{
  protected Test( boolean init ){
    if( init ){
      init();
    }
  }

  protected void init(){
    setName(...)
  }
}
Java:
public class SubTest extends Test{
  public SubTest(){
    this(true);
  }

  protected SubTest( boolean init ){
    super(false);
    if( init ){
      init();
    }
  }

  protected void init(){
    database = new ...
    super.init();
    ...
  }

  public void setName(...){
    ...
  }
}
 
G

Gonzo17

Gast
Was ich noch nicht verstanden habe: worin besteht der Denkfehler?

Denk zur Laufzeit in Objekten und NICHT in Klassen!

Ich denke das ist der springende Punkt. Ein Objekt vom Typ Subklasse kann eben per Definition nicht eine Methode der Basisklasse aufrufen, wenn diese überschrieben wurde. Wenn du die Methode aus der Basisklasse verwenden willst, darfst du sie nicht überschreiben und musst die Methode in der Subklasse anders benennen. Nur wenn du das tust, dann geht dir eben der Vorteil der Vererbung verloren und du kannst die Methode wirklich nur dann aufrufen, wenn du weißt, dass dein Objekt vom Typ Subklasse ist.
 

Pepe Rohny

Aktives Mitglied
Also ich hab das jetzt nicht verstanden. Was ist eine erfüllte Eigenschaft?

Das ist im Sinne von "Design by Contract" bzw. "Design by Covenant" gemeint.

Private Variablen können noch immer in der Klasse und deswegen auch insbesondere im Konstruktor zugewiesen werden, in der sie stehen. Daran ändert auch ein vorhandener Setter nichts.

In Zeile 32 wird sie doch aufgerufen?

Das ist richtig. Die Einhaltung der Zusicherung erfordert Disziplin vom Programmierer: die Änderung der Eigenschaft darf nur durch die set-Methode erfolgen.

Pepe
 

Pepe Rohny

Aktives Mitglied
Der Denkfehler und das eigentliche roblem liegen IMO darin, dass du meine Erklärungen nicht verstanden oder wohl eher (Sorry wenn ich direkt bin) gar nicht wirklich gelesen hast.

Direkte und klare Worte sind schon in Ordnung. Aber trotzdem liegst du falsch: ich habe deinen Beitrag gelesen und verstanden. Möglicherweise anders als du es gemeint hast, aber sowas passiert schon mal.

Wer Code überschreibt will ganz bewusst, dass der überschriebene Code eben NICHT mehr ausgeführt wird - Punkt!

Das stimmt so nicht. Man kann in einer überschreibenden Methode die überschriebene Methode aufrufen. Was in diesem Fall ja auch passiert. So wird neben der ursprünglichen Aktion noch eine weitere Aktion ausgeführt.

Es gibt eine Möglichkeit das doch zu tun und das ist es aus der abgeleiteten Klasse das mit
Code:
super.funktionB()
zu machen. Punkt.

Eben.

Denk zur Laufzeit in Objekten und NICHT in Klassen! Wenn du ein Objekt der abgeleiteten Klasse hast gibt es kein "aus der Superklasse" ---- es gibt keine Superklasse, es gibt nur ein Objekt der Subklasse - Punkt.

Ein Objekt ist immer ein Exemplar einer Klasse. Die Eigenschaften und Verhaltensweisen werden als Klasse definiert. Soweit klar?

Ein Exemplar (Objekt) einer abgeleiteten Klasse ist immer auch ein Exemplar der Basis-Klasse. Wenn du solch ein Objekt fragst, welcher Klasse es angehört wird es antworten, dass es der abgeleiteten Klasse angehört. Wenn du es aber fragst, ob es vielleicht auch der Basis-Klasse angehört, wird es das bestätigen. Das ist dir klar - oder?

Wenn sogar ich es begriffen habe, kann es nicht soooo schwieirig sein :bahnhof:

Ich bin auch ein Freund klarer Worte: du trittst hier zwar ziemlich bestimmt auf, aber das du es richtig verstanden hast glaube ich eher nicht.

Pepe
 

Pepe Rohny

Aktives Mitglied
Wenn du willst, dass man sie nicht überschreiben kann: Mach ein "final" davor.
Wenn das nicht geht, weil die Methode manchmal doch überschrieben sein soll, musst du nochmal überlegen: bei der gleichen Methode kann nicht manchmal die Methode der Unterklasse und manchmal die Methode der Basisklasse rauskommen.
Das sollte dann wohl eher 2 Methoden sein, denk ich mal.

Das mit dem "final" hat was für sich: wenn die Klasse das garantieren soll, darf das natürlich nicht überschrieben werden können.

In dem Sinne gebe ich dir Recht.

Das eigentliche Problem, um das es mir geht, ist aber: durch das überschreiben einer Methode ist die überschriebene Methode für die Basis-Klasse nicht mehr erreichbar. Auch nicht durch das voranstellen von "this". Schade eigentlich. Da in diesem Punkt bisher keiner widersprochen hat, markiere ich diesen Faden hier mal als erledigt.

Pepe
 

Suinos

Bekanntes Mitglied
Genau wegen diesem Problem sollte man in einem Konstruktor keine überschreibbaren Methoden aufrufen!
Siehe auch hier.

Wie wäre es mit so einer Lösung?:
Java:
class SuperClass
{
	protected String name;
	
	public SuperClass(String name)
	{
		setName0(name);
	}
	
	public void setName(String name)
	{
		setName0(name);
	}
	
	// oder auch 'protected final'
	private void setName0(String name)
	{
		this.name = name;
	}
}
Java:
class Sub extends SuperClass
{
	public Sub(String name)
	{
		super(name);
	}
	
	@Override
	public void setName(String name)
	{
		super.setName(name);
		
		// whatever
	}
}

Das sieht zwar komisch aus, lässt dich aber deine Restriktionen behalten und löst das Problem.
 
G

Gonzo17

Gast
Das eigentliche Problem, um das es mir geht, ist aber: durch das überschreiben einer Methode ist die überschriebene Methode für die Basis-Klasse nicht mehr erreichbar.

Das stimmt doch schlicht und ergreifend nicht. Natürlich ist sie für die Basis-Klasse erreichbar. Aber nicht für die Sub-Klasse. Und du hast ein Objekt der Sub-Klasse, deswegen wird auch die überschriebene Methode aufgerufen.
Wie gesagt, du denkst da wohl zu sehr in Klassen. Wenn du an Objekte denkst, dann müsste doch klar sein, dass ein Objekt vom Typ Sub-Klasse nur die überschriebene Methode sieht (und auch nur sehen darf!).
 

Pepe Rohny

Aktives Mitglied
Genau wegen diesem Problem sollte man in einem Konstruktor keine überschreibbaren Methoden aufrufen!
Siehe auch hier.

Yep - is' angekommen.

Kommt nun mal selten vor, dass ich so ein Konstrukt gebrauche. Bin da einfach so rein gestolpert.

Aber: wenn es möglich wäre ...

Ich schenk mir mal den Rest - es ist eben wie es ist.

Wie wäre es mit so einer Lösung?: [...]

Ja - fast: die Eigenschaft ("name") ist in der abgeleiteten Klasse und darüber hinaus im gesamten Package sichtbar und damit änderbar. Wenn man die privatisiert sollte es funktionieren.

Pepe
 

Pepe Rohny

Aktives Mitglied
Das stimmt doch schlicht und ergreifend nicht. Natürlich ist sie für die Basis-Klasse erreichbar. Aber nicht für die Sub-Klasse.

Probier's doch mal aus. Hier ein Vorschlag als Diskussionsgrundlage:
Java:
class BaseClass {

    BaseClass() {
        System.out.print("BaseClass-Constructor: ");
        this.method();
    }

    void method() {
        System.out.println("BaseClass");
    }

    public static void main(String[] args) {
        DerivedClass derivedClass = new DerivedClass();
        System.out.print("direct call: ");
        derivedClass.method();
        System.out.print("casted call: ");
        ((BaseClass)derivedClass).method();
    }

    private static class DerivedClass extends BaseClass {

        DerivedClass() {
            System.out.print("DerivedClass-Constructor: ");
            this.method();
        }

        @Override
        void method() {
            System.out.println("DerivedClass");
        }

    }

}

Wie gesagt, du denkst da wohl zu sehr in Klassen. Wenn du an Objekte denkst, dann müsste doch klar sein, dass ein Objekt vom Typ Sub-Klasse nur die überschriebene Methode sieht (und auch nur sehen darf!).

Nein - nicht ich denke zu sehr in Klassen, sondern du übersiehst den entscheidenden Punkt: ich würde gerne in der Basis-Klasse auf die in ihr definierte Methode zugreifen können. Das ist aber nicht möglich. Nicht mal durch das voranstellen von "this". Das sollte im Beispiel egentlich deutlich zu erkennen sein.

Pepe
 
G

Gonzo17

Gast
Nein - nicht ich denke zu sehr in Klassen, sondern du übersiehst den entscheidenden Punkt: ich würde gerne in der Basis-Klasse auf die in ihr definierte Methode zugreifen können. Das ist aber nicht möglich. Nicht mal durch das voranstellen von "this". Das sollte im Beispiel egentlich deutlich zu erkennen sein.

Du siehst, wir drehen uns im Kreis. Mit jedem Mal wird mir klarer, was du meinst. Und trotzdem bin ich mir jedesmal sicherer, dass das, was du tun willst, nicht funktionieren kann. Aus Gründen, die ich schon genannt habe.

Der Cast bringt dir übrigens garnichts an dieser Stelle. Damit stellst du nur sicher, dass dieses Objekt vom Typ BaseClass erbt und somit die Methode verwenden darf - ändert ja aber nichts daran, dass das Objekt tatsächlich ein DerivedClass ist und die Methode überschrieben wird. Oder ums mal "bildlich" auszudrücken, wie es Andi_CH mal gemacht hat in einem anderen Post: die Variable
Code:
derivedClass
"sieht"
Code:
method()
aus der BaseClass nichtmehr, weil es eine eigene Methode hat, die genauso heißt und dementsprechend die Methode überschreibt.
 

Pepe Rohny

Aktives Mitglied
Der Cast bringt dir übrigens garnichts an dieser Stelle. Damit stellst du nur sicher, dass dieses Objekt vom Typ BaseClass erbt ...

Nein - das stimmt nicht. Die Vererbung erfolgt mittels des Schlüsselwortes "extends". Der cast bewirkt, dass das Exemplar als Basis-Klasse behandelt wird. Ein Exemplar der abgeleiteten Klasse ist immer auch ein Exemplar der Basis-Klasse. Daher: Klassenbewusstsein ist wichtig.

... ändert ja aber nichts daran, dass [...] die Methode überschrieben wird.

Das ist der Kern des Problems: die überschriebene Methode ist nur für Exemplare der Basis-Klasse erreichbar - das ist klar. Hinweis: in einigen meiner vorigen Beiträge hatte ich angenommen, dass die Basis-Klasse abstrakt ist, aber nicht darauf hingewiesen - sorry.

Was ich gerne hätte ist folgendes: durch das voranstellen von "this" auf die überschriebene Methode zugreifen. Was aber nicht möglich ist. Andererseits ist es aber möglich, von der abgeleiteten Klasse aus - mittels "super" - auf die überschriebene Methode zuzugreifen. Nun ja - es ist eben wie es ist.

Pepe
 

xehpuk

Top Contributor
Nein - das stimmt nicht. Die Vererbung erfolgt mittels des Schlüsselwortes "extends". Der cast bewirkt, dass das Exemplar als Basis-Klasse behandelt wird.
AFAIK dient der Cast nur dem Compiler und hat keine Auswirkung auf die Laufzeit (es sei denn, man löst eine ClassCastException aus :D).
Es lässt sich immer nur der Typ der Referenz ändern, aber nicht des Objekts.

Was ich gerne hätte ist folgendes: durch das voranstellen von "this" auf die überschriebene Methode zugreifen. Was aber nicht möglich ist. Andererseits ist es aber möglich, von der abgeleiteten Klasse aus - mittels "super" - auf die überschriebene Methode zuzugreifen. Nun ja - es ist eben wie es ist.
Also ist es doch möglich. ???:L

Java wählt für jedes Objekt die speziellste Methode, was ja auch sinnvoll ist. Hast du ein Objekt einer konkreten BaseClass, dann wird auch dessen Operation aufgerufen. In einer abgeleiteten Klasse dann natürlich die überschriebene (wozu denn sonst Methoden überschreiben?).

Und non-static Operationen werden sowieso immer auf this aufgerufen, wenn nichts anderes angegeben ist.
 
Zuletzt bearbeitet:
G

Gonzo17

Gast
Nein - das stimmt nicht. Die Vererbung erfolgt mittels des Schlüsselwortes "extends". Der cast bewirkt, dass das Exemplar als Basis-Klasse behandelt wird. Ein Exemplar der abgeleiteten Klasse ist immer auch ein Exemplar der Basis-Klasse. Daher: Klassenbewusstsein ist wichtig.

Stimmt, das war grad Mist, was ich da gesagt hab. Das was ich meinte ist wohl eher ein
Code:
instanceof
.
 

Pepe Rohny

Aktives Mitglied
Also ist es doch möglich. ???:L

Probier's aus. Ich bin schon gespannt auf das Ergebnis :applaus:

Java wählt für jedes Objekt die speziellste Methode, was ja auch sinnvoll ist. Hast du ein Objekt einer konkreten BaseClass, dann wird auch dessen Operation aufgerufen. In einer abgeleiteten Klasse dann natürlich die überschriebene (wozu denn sonst Methoden überschreiben?).

Ja - aber ich will auch die überschriebene Methode aufrufen können. Beispielcode an dem man erkennen kann wie ich mir das vorstelle habe ich ja schon ein paarmal eingestellt.

Und non-static Operationen werden sowieso immer auf this aufgerufen, wenn nichts anderes angegeben ist.

Is' wohl so ...

Pepe
 

tfa

Top Contributor
Nein - das stimmt nicht. Die Vererbung erfolgt mittels des Schlüsselwortes "extends". Der cast bewirkt, dass das Exemplar als Basis-Klasse behandelt wird. Ein Exemplar der abgeleiteten Klasse ist immer auch ein Exemplar der Basis-Klasse. Daher: Klassenbewusstsein ist wichtig.
Ein Objekt ist immer nur Exemplar einer Klasse. Was du meinst, sind Typen. Ein Objekt hat i.d.R. viele Typen: Den Typ der eigenen Klasse, sämtlicher Oberklassen und aller implementierter Interfaces. Trotzdem gibt es nur eine konkrete Klasse, von der das Objekt erzeugt wurde (von synthetischen Proxys mal abgesehen).

Und der Cast ist wirklich nur eine Zusicherung für das Laufzeitsystem, dass ein Objekt einen bestimmten Typ hat. Eine Umwandlung oder Anweisung, wie irgendwelche Methoden aufzurufen sind, ist das nicht.
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
E gleicher Name in der Basisklasse und in der Subklasse Java Basics - Anfänger-Themen 45
M Vererbung Funktionen in Basisklasse deklarieren Java Basics - Anfänger-Themen 4
S Vererbung Zugriff auf die Basisklasse einer "zweiten" Erweiterungsklasse Java Basics - Anfänger-Themen 2
S Vererbung Array aus Basisklasse bilden? Java Basics - Anfänger-Themen 5
H Abstrakte Basisklasse Verständnisproblem! Java Basics - Anfänger-Themen 8
J Vererbung Zugriff auf die Basisklasse Java Basics - Anfänger-Themen 4
A Aufruf von Konstruktor aus Basisklasse Java Basics - Anfänger-Themen 7
J Vererbung Frage zu Basisklasse Java Basics - Anfänger-Themen 6
F OOP von Basisklasse in Kindklasse umwandeln Java Basics - Anfänger-Themen 9
K feld von basisklasse ändern Java Basics - Anfänger-Themen 11
Ü Methode soll Quadrat aus der Summer zurückgeben Java Basics - Anfänger-Themen 10
DrahtEck Schleife soll wieder da anfangen wo ich es möchte ! Java Basics - Anfänger-Themen 17
T Methode soll etwas ausrechnen und zurückgeben (klappt nd) hat wer eine Idee? Java Basics - Anfänger-Themen 11
Com.Roter Wie soll ich lernen? Java Basics - Anfänger-Themen 17
T code so schreiben das er von sich selber anpasst (code soll die anzahl aller bustaben bestimmen) Java Basics - Anfänger-Themen 16
T float soll durch schleife die größte mögliche Zahl herausfinden, Ausgabe ist aber "Infinity" Java Basics - Anfänger-Themen 1
I aus 2 random zahlen soll nur die ungerade summe der beiden genommen werden. Java Basics - Anfänger-Themen 13
H Erste Schritte Nach einer Zahl n soll n Mal der String untereinander ausgegeben werden Java Basics - Anfänger-Themen 3
berserkerdq2 Warum soll ich shuffle nutzen, um bei Rückgabewert Collection eine Liste zurückzugeben? Java Basics - Anfänger-Themen 3
berserkerdq2 Wann soll ich den Stream schließen, wenn ich das in einer Methode habe? Java Basics - Anfänger-Themen 8
A String split funktioniert nicht, wenn mehr als 1 Ziffer vor dem Zeichen steht nach dem er trennen soll? Java Basics - Anfänger-Themen 4
M Bei nach oben scrollen soll Seite aktualisiert werden (Userscript mit Javascript) Java Basics - Anfänger-Themen 10
R App soll selbstständig reagieren, anstatt via Models Java Basics - Anfänger-Themen 0
A Wenn eine Zahl durch 7 teilbar ist, soll statt der Zahl ein ‘*‘ angezeigt werden. java? Java Basics - Anfänger-Themen 47
C Ein Algorithmus soll schneller werden Java Basics - Anfänger-Themen 24
K Ein Objekt Auto kennt den Inhalt seines links und rechtsstehenden Autos, wie soll man das ermöglichen Java Basics - Anfänger-Themen 2
HeiTim Brauche Hilfe soll ein nummeriertes Feld ausgeben lassen Java Basics - Anfänger-Themen 17
O Ich habe einen String und soll mit matches schauen, ob ein Buchstabe zu einer geraden ANzahl im String vorkommt, wie soll das gehen? Java Basics - Anfänger-Themen 7
O Ich ahbe einen char und diesen soll ich bei .matches prüfen, also ob der char in meiner Zeichenkette vorhanden ist, wie mache ich das? Java Basics - Anfänger-Themen 9
B Java Programm soll mit Python kommunizeren Java Basics - Anfänger-Themen 1
J Kreis soll die gleiche Fläche wie das Rechteck haben wie mache ich das? Java Basics - Anfänger-Themen 3
MichelNeedhelp Brauche zu diesem Labyrinth ein Skript? Der Hamster soll im Urzeigersinn das ganze Labyrinth abgehen und wieder an seinem Ursprungsplatz sein. Java Basics - Anfänger-Themen 40
J Problem mit einer Methode die gewissen Inhalt einer Array löschen soll Java Basics - Anfänger-Themen 9
J Problem mit einer Methode, die beliebig viele Objekte in Array speichern soll Java Basics - Anfänger-Themen 6
F Java Programm, das kleine Buchstaben in einem String zählen soll und bei großen Buchstaben oder Sonderzeichen abbrechen soll. Java Basics - Anfänger-Themen 5
kazzam94 Methode soll Array von Boolean zurückgeben Java Basics - Anfänger-Themen 5
S Scanner soll Groß-/ Kleinschreibung ignorieren Java Basics - Anfänger-Themen 2
E Division von BigInteger soll Gelitkommazahl liefern Java Basics - Anfänger-Themen 46
M Unterklasse soll nicht alle Methoden erben Java Basics - Anfänger-Themen 3
E Methode soll andere Methode der selben Klasse aufrufen Java Basics - Anfänger-Themen 28
S Vergleichen ob der Integer der benutzt eingeben werden soll überhaupt ein int ist Java Basics - Anfänger-Themen 1
C Ganzzahlige Werte in Boolean ausgeben und überprüfen ob Primzahl oder nicht, wenn es keine Primzahl ist soll es die Primfaktorzerlegung ausgeben Java Basics - Anfänger-Themen 4
E Kreis soll eine Raupe darstellen Java Basics - Anfänger-Themen 37
V Erste Schritte for-Schleife; Ausgabe soll alle 5 Sekunden erfolgen. Java Basics - Anfänger-Themen 4
H Koordinateneingabe im 2D Array soll true/false zurückgeben Java Basics - Anfänger-Themen 5
D Etwas unsicher wie es weitergehen soll Java Basics - Anfänger-Themen 2
N Bewegtes Objekt soll sich um eine Parallele bewegen Java Basics - Anfänger-Themen 0
B Button soll sowohl auf Klicken als auch auf die Enter-Taste reagieren Java Basics - Anfänger-Themen 9
B Derzeit JSF - Projekt, später soll MobileApp folgen Java Basics - Anfänger-Themen 5
scratchy1 Wie deklariert man eine Methode, die ein Objekt zurückgeben soll? Java Basics - Anfänger-Themen 22
V Vererbung Subklasse soll Superklasse verändern Java Basics - Anfänger-Themen 2
T Random soll Zufallszahl beibehalten. Java Basics - Anfänger-Themen 11
C Objekt soll ein Array sein. Java Basics - Anfänger-Themen 15
N Ich weiß nicht, wie ich meinen Code richtig designen soll und komme nicht weiter Java Basics - Anfänger-Themen 4
K Zufalsszahl soll sich nicht wiederholen Java Basics - Anfänger-Themen 9
W Eigener Iterator soll mehrdimensionales Array durchlaufen Java Basics - Anfänger-Themen 4
P Methode soll Variable einer anderen Klasse ändern. Wie? Java Basics - Anfänger-Themen 1
J Kopierte Datei soll alte ersetzen. Java Basics - Anfänger-Themen 6
A Variablen Main Klasse soll auf eine andere Klasse zugreifen Java Basics - Anfänger-Themen 3
I Programm tut nicht was es soll :) Java Basics - Anfänger-Themen 5
Tommy135 Klassen jComboBox macht nicht was sie soll Java Basics - Anfänger-Themen 4
D JButton soll Farbe von JTextfield ändern Java Basics - Anfänger-Themen 5
R While-Schleife macht nicht was sie soll Java Basics - Anfänger-Themen 24
kilopack15 Methode soll int-Array zurückgeben Java Basics - Anfänger-Themen 2
S Variable in JTextField soll immer um 5 zunehmen Java Basics - Anfänger-Themen 8
S JButton soll für bestimmte Zeit verschwinden Java Basics - Anfänger-Themen 5
J-Gallus Ein Getter bekommt eine anderen Type als er Return soll Java Basics - Anfänger-Themen 9
L Bei falscher Eingabe soll NaN zurückgegeben werden, Rückgabetyp jedoch double Java Basics - Anfänger-Themen 3
W drawLine(...) - Linie soll nur begrenzt lang sein Java Basics - Anfänger-Themen 9
I Fenster A soll Fenster B schliessen Java Basics - Anfänger-Themen 5
A Variablen Variable soll ihren Wert nach Initialisierung nicht mehr ändern Java Basics - Anfänger-Themen 2
TheMenox Methoden Bestimmung an welche Methode eine andere Methode ihren Wert weitergeben soll Java Basics - Anfänger-Themen 35
M Exception soll Werte mitgeliefert bekommen Java Basics - Anfänger-Themen 12
K Objekt soll Anwendung über Änderungen informieren Java Basics - Anfänger-Themen 8
X Einfache Frage; wie soll ich die spezielle float var speichern? Java Basics - Anfänger-Themen 2
C Ein Button soll Focus rausfinden und Methode starten Java Basics - Anfänger-Themen 9
M Panel erstellen, welches ein Control erhält. Ausgabe soll über einen Stream erfolgen. Java Basics - Anfänger-Themen 0
K Variablenname soll der Inhalt vom String sein Java Basics - Anfänger-Themen 2
K Wie lange kann / soll das dauern? Java Basics - Anfänger-Themen 6
R Button soll Wert 1 in Variable schreiben Java Basics - Anfänger-Themen 4
J Interface Bubblesort soll Arrays beliebiger Referenztypen sortieren können. Java Basics - Anfänger-Themen 5
T Array soll Werte aufnehmen Java Basics - Anfänger-Themen 2
B Anwender soll mathematische Funktion eingeben können, Einfachster Fnktionsplotter Java Basics - Anfänger-Themen 4
E Erste Schritte [Noob-Frage] Meine If-Abfrage macht nicht, was sie soll... Java Basics - Anfänger-Themen 2
S Generische Methode soll Objekte als Parameter erlauben die bestimmtes Interface implementieren^ Java Basics - Anfänger-Themen 9
M Weiß nicht, wie ich es nennen soll. Java Basics - Anfänger-Themen 1
T Wenn Schaltjahr ist, soll Februar, einen Tag mehr haben, GUI mit combobox Java Basics - Anfänger-Themen 4
H Erste Schritte Ergebniss soll kleiner als 1000 sein Java Basics - Anfänger-Themen 4
M Warum soll man die Finanlize Methode nicht überschreiben und aufrufen? Java Basics - Anfänger-Themen 2
W Erste Schritte Timer soll jede Sekunde Label aktualisieren Java Basics - Anfänger-Themen 5
T BufferReader soll datei mehrmals lesen Java Basics - Anfänger-Themen 13
M CompareTo soll Datum sortieren Java Basics - Anfänger-Themen 2
S Maus soll Programm nicht verlassen Java Basics - Anfänger-Themen 1
M Java Datei soll sich selbst löschen Java Basics - Anfänger-Themen 8
V Was soll alles in den Konstruktor? Java Basics - Anfänger-Themen 3
E Einfache For-Schleife macht nicht was sie soll Java Basics - Anfänger-Themen 2
Sogomn Wie soll ich weiermachen? Java Basics - Anfänger-Themen 4
E Erste Schritte Array soll kleiner werdenden String erstellen Java Basics - Anfänger-Themen 5
S Methoden Methode soll String zurückgeben Java Basics - Anfänger-Themen 11
C Wo soll die Methode hin? Java Basics - Anfänger-Themen 2

Ähnliche Java Themen

Neue Themen


Oben