Zum Inhalt springen

Empfohlene Beiträge

Geschrieben

Hallo,

ich hätte eine Frage zur Vererbung - funktioniert das protected in beide Richtungen ?

Bsp.:


class foo {

public:

[INDENT]foo(){}[/INDENT]


protected:

[INDENT]int p_nBar;[/INDENT]


}


class bar : public foo{

public:

[INDENT]bar(){}[/INDENT]


protected:

[INDENT]int p_nTest;[/INDENT]


}

Das bar auf foo:: p_nBar zugreifen kann ist klar. Aber kann ich mit der Basisklasse auch auf eine abgleitete Klasse und deren protected Attributen (von foo auf bar:: p_nTest) zugreifen ?

Das ganze funktioniert nämlich in Java :eek

Wenn das in C++ funktionieren würde, dann könnte man ja theorethisch einen Konstruktor immer protected machen und über eine Factory (die die Basisklasse benutz) das Objekt der abgeleiteden erstellen...

Geschrieben

Protected erlaubt den Zugriff nur auf auf das foo-Objekt, das Bestandteil der Instanz von bar ist. Auf andere foo-Objekte hast du keinen besondern Zugriff.

Daher kann das gar nicht in die andere Richtung funktionieren.

Geschrieben

hmm, ok

aber gibt es eine Möglichkeit, herauszufinden welcher Typ eine Parameter ist ? weil dann könnte man ja eine zwischenfunktion schreiben, die dies erlaubt oder verbietet *g*

also sowas wie

if (ofoo instaceof foo)

oder in der art ?

Geschrieben

Ich hab mir überlegt zur Übung ein firmeninternes Java-Projekt in C++ zu schreiben... und da werden die Techniken angewandt

Naja... wenns nur über Umwege geht, dann lass ich das lieber :floet:

Geschrieben
Es würde mich wundern wenn Java sich an dieser Stelle anders verhalten würde als C++.

Naja... ich wollte die Verfahren auch nachbilden...

Das ganze ist über Fabriken (Factorys) realisiert... deswegen auch die Frage

Eine Hauptklasse führt da den Konstruktor einer Objektklasse aus usw...

Sprich in Java geht die Vererbung in beide Richtungen, was in C++ (anscheinend) nicht funktioniert...

Geschrieben

Dann zeige bitte ein Demonstrationsprogramm, welches das Verhalten vorführt. Im Detail: Eine Basisklasse soll auf Variable zugreifen, die erst in einer von ihr abgeleiteten Klasse eingeführt wird (natürlich ohne Typumwandlungen ("cast") durchzuführen). (Das hast Du ja, so wie ich es lese, behauptet.)

Geschrieben
Ganz sicher nicht.

Ich bin kein Java-Fachmann, aber

class Base
{
public void foo()
{
Derived d = new Derived();
int x = d.pro; // Das geht
int y = d.pri; // Das geht nicht
}
}


class Derived extends Base
{
protected int pro;
private int pri;
}[/code]

Geschrieben

Eben...

Und über so eine Reflexion kann man dann auch die Objekte der abgeleiteten Klasse erzeugen in dem man in der Factory eine Instanz der Basisklasse benutzt...

Geschrieben

meinst du vielleicht sowas?


#include <iostream>

using namespace std;

class BASE
{
public:
virtual void ausgabe()
{
cout<<"BASE"<<endl;
}

};

class A : public BASE
{
public:
void ausgabe()
{
cout<<"A"<<endl;
}
};

class B : public BASE
{
public:
void ausgabe()
{
cout<<"B"<<endl;
}

};

int main()
{
BASE* b[3];
b[0] = new A();
b[1] = new BASE();
b[2] = new B();
for (int i=0; i<3; ++i)
b[i]->ausgabe();
return 0;
}
[/PHP]

Geschrieben
Und über so eine Reflexion kann man dann auch die Objekte der abgeleiteten Klasse erzeugen in dem man in der Factory eine Instanz der Basisklasse benutzt...

So langsm wird klar, was Du eigentlich meinst. In C++ geht dies innerhalb der Konstruktoren nicht, da der Defaut-Konstruktor der abgeleiteten Klasse gleich zu Beginn auch den (die) Konstruktor(en) der Basisklasse(n) aufruft. Wenn Du nun im Konstruktor einer diese Basisklassen eine abgeleitete klasse erzeugen willst, drehst Du Dich im Kreis...

Du kannst allerdings protected-Konstruktoren von Klassen aus aufrufen, die mit friend gekennzeichnet sind. Dadurch kannst Du auch Factory-Klassen erstellen, die protected-Konstruktoren aufrufen können.

Allerdings halte ich diese Vorgehensweise (vom Design-Standpunkt aus gesehen) für eher überdenkenswürdig ;)

Geschrieben
Das ganze funktioniert nämlich in Java

Nein, tut es nicht. Verwechsle nicht Vererbung mit Sichtbarkeit. Vererbung geht in Java (und jeder anderen Sprache, die keine Mehrfachvererbung unterstützt) nur in genau eine Richtung, das heisst eine Klasse hat genau eine Superklasse. Genauso kann auch nur die Superklasse Methoden an angeleitete Klassen vererben.

Was aber nichts mit der Sichtbarkeit zu tun hat. Wenn ich mir folgende Klassenhierarchie ansehe:


class A {

  protected int integerInA;

}

class B extends A {

  protected int integerInB;

}

class C extends B{

  protected int integerInC;

}

So kann ein Objekt einer Klasse auf jedes Property von Objekten der anderen Klassen zugreifen. Ganz einfach deshalb, weil die Sichtbarkeit von protected Methoden und Attributen definiert ist als:

6.6.2 Details on protected Access

A protected member or constructor of an object may be accessed from outside the package in which it is declared only by code that is responsible for the implementation of that object.

Genau dieser Teil impliziert allerdings, dass der Zugriff von Klassen im gleichen Package ohne weiteres möglich ist.
Geschrieben
Also hat protected in Java gar nichts mit Vererbung zu tun, sondern betrifft nur Packages?

Grundsätzlich verhält sich Java ähnlich zu C++ und C#.

Für Java gibt wie in C++ drei access modifier: public, protected und private. C# kennt zusätzlich noch internal. Die Namen sind gleich, es gibt jedoch feine Unterschiede.

Zusammengefasst (vereinfacht):

Für Java gilt:

private: Nur für die Klasse selbst sichtbar.

protected: Für die Klasse, abgeleitete Klassen und Klassen im gleichen Paket sichtbar.

public: Für alle sichtbar (Standard).

Für C# gilt:

private: Nur für die Klasse selbst und eingebettete Typen sichtbar.

protected: Für die Klasse und abgeleitete Klassen sichtbar.

internal: Sichtbar in Source-Dateien, die zum gleichen Assembly gehören.

public: Für alle sichtbar.

Für C++ ist die Bedeutung sicher allen bekannt (=will jetzt keine Romane schreiben ;))

Geschrieben

Ein Package (Paket) enthält eine oder mehrere Klassen, die sich einen Geltungsbereich (Namespace) für Klassen teilen. Klassennamen brauchen nur innerhalb eines Packages eindeutig zu sein. Dies vermeidet mögliche Namenskonflikte zwischen verschiedenen Klassen, die von der lokalen Festplatte oder über das Netz dynamisch geladen werden.

Um eine Java-Datei einem Paket zuzuordnen, kann man an den Anfang der Datei eine package-Anweisung schreiben.

PS: In Java können nur Packages importiert werden... einzelne Include Dateien gibt es so nicht...

Allerdings kann man

import package.classe;
benutzen... Würde sich aber bei mehren Klassen des gleiches Packeges (relativ zu der Anzahl der Klassen in ihm) folgendes eignen:
import package.*;

Somit werden alle Klassen des Packages zugänglich...

Edit: schachteln kannst du die Pakete natürlich auch ;)

Btw: Danke für die Erklärung Perdi und Bubble - jetzt ist mir das endlich mal klar geworden

Dein Kommentar

Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.

Gast
Auf dieses Thema antworten...

×   Du hast formatierten Text eingefügt.   Formatierung wiederherstellen

  Nur 75 Emojis sind erlaubt.

×   Dein Link wurde automatisch eingebettet.   Einbetten rückgängig machen und als Link darstellen

×   Dein vorheriger Inhalt wurde wiederhergestellt.   Editor leeren

×   Du kannst Bilder nicht direkt einfügen. Lade Bilder hoch oder lade sie von einer URL.

Fachinformatiker.de, 2024 by SE Internet Services

fidelogo_small.png

Schicke uns eine Nachricht!

Fachinformatiker.de ist die größte IT-Community
rund um Ausbildung, Job, Weiterbildung für IT-Fachkräfte.

Fachinformatiker.de App

Download on the App Store
Get it on Google Play

Kontakt

Hier werben?
Oder sende eine E-Mail an

Social media u. feeds

Jobboard für Fachinformatiker und IT-Fachkräfte

×
×
  • Neu erstellen...