Forum: PC-Programmierung C#: Frage zu geerbte Klassen


von Steve (Gast)


Lesenswert?

Hallo zusammen,

vielleicht kann mir jemand bei dem nächsten Problem helfen:

- Ich habe einen Interface I
- Eine Klasse USB von I geerbt
- Eine Klasse RS232 von I geerbt
- Und eine Klasse Comm von I geerbt
- In Comm sind zwei Instanzen von USB (myUSB) und RS232(myRS232)

Wie kann ich es implementieren dass wenn der User seine Schnittstelle 
wählt nur mit dem Interface von einer der Instanzenen arbeite?

In "C++" hätte ich in der Klasse Comm noch eine "void* myInterface" und 
wenn der User sein USB-Interface gewählt hat: myInterface = 
(void*)myUSB;

und dann auf den Funktionen mit myInterface->Init() zum Beispiel.

von Karl H. (kbuchegg)


Lesenswert?

Steve schrieb:

> In "C++" hätte ich in der Klasse Comm noch eine "void* myInterface"

Sobald du in C++ irgendwo einen void-Pointer hast, solltest du wenn du 
mit mir zusammenarbeitest, besser einen extrem guten Grund dafür haben 
oder aber ganz schnell laufen können :-)

Und dasselbe gilt auch für C#


Kannst du deine Klassen mal etwas konkreter zeigen?
Dein Comm-Klasse kommt wir ein wenig Spanisch vor. Ich denke momentan, 
die Ableitung eines Comm Objektes von I ist nicht das was du willst. Im 
Moment bin ich noch nicht mal davon überzeugt, dass es diese COMM Klasse 
überhaupt braucht.

von Thomas B. (escamoteur)


Lesenswert?

Ähm, COM erbst auch von I und enthält zusätzlich zwei Instanzen? Wozu 
ist das gut?

Im prinzip kannst Du es genau wie in C++ machen, einfach eine Factory 
Methode die Object mit Interface I zurückgibt.


Gruß
Tom

von Karl H. (kbuchegg)


Lesenswert?

Ein guter Anhaltspunkt ist folgender

Du willst von einer Klasse A eine Klasse B ableiten, wenn logisch 
gesehen einer der beiden Sätze Sinn macht

    B  ist-ein  A

oder

    B  implementiert  A


Wenn dein logischer Zusammenhang aber lautet:

    b hat-ein A

dann ist Ableitung nicht das Mittel der Wahl, sondern das bedeutet im 
Regelfall, dass die Klasse B eine Instanz der Klasse A als Member hat.

Beispiele:
Es gibt KFZ (Kraftfahrzeuge), PKW, LKW. Weiters gibt es Motoren, Beziner 
und Diesel.

Ein PKW ist-ein KFZ. Die Klasse PKW wird daher von KFZ abgeleitet 
sein.
Aber: Ein KFZ hat-einen Motor. Die Klasse KFZ wird daher nicht von der 
Klasse MOTOR hergeleitet, sondern enthält eine Instanz davon als Member.

von Steve (Gast)


Lesenswert?

Ups! stimmt, SUB und RS232 sind nicht von I geerbt.
1
public interface I
2
{
3
    int Init();
4
    void Close();
5
    int WriteData();
6
    int ReadData();
7
}
8
9
public class USB
10
{
11
    int Vid = 0;
12
    int Pid = 0;
13
    .
14
    .
15
    .
16
    public USB(int vid, int pid)
17
    {
18
       .
19
       .
20
    }
21
    .
22
    .
23
    .
24
}
25
26
public class RS232
27
{
28
    .
29
    .
30
    .
31
    .
32
}  
33
 public class COM : I 
34
 {
35
        USB myUSB;
36
        RS232 myRS232
37
        // etc...
38
39
      public int init()
40
      {
41
         .
42
         .
43
         .
44
       }
45
       .
46
       .
47
       .
48
 
49
}

von Karl H. (kbuchegg)


Lesenswert?

Steve schrieb:
> Ups! stimmt, SUB und RS232 sind nicht von I geerbt.

Sollten sie aber

I ist die abstrakte Beschreibung dessen, was ein Kommunikationsobjekt 
alles können muss, damit man darüber eine Kommunikation aufbauen kann.

USB ist eine konkrete Implementierung davon
RS232 ist eine konkrete Implementierung davon


Nur was der Zweck der COM Klasse sein soll, ist mir noch nicht ganz 
klar.

von Steve (Gast)


Lesenswert?

das Ziel ist das jedes Mal wenn der User den Interface wechselt alles 
neu initalisiere und die richtigen Funktionen aufrufe, ich muss 
irgendwie dynamisch zwischen die Interfaces wechsele ohne jedes Mal den 
Interface zu prüfe und ohne mit:
1
if(interface == USB)
2
        USB.Init();
3
else if(interface == RS232)
4
        RS232.Init();

von Karl H. (kbuchegg)


Lesenswert?

Edit: Es könnte natürlich auch noch sein, dass dir die gemeinsame 
Basisklasse für USB und RS232 noch fehlt, bzw. das diese eben nicht I 
ist. Kommt ganz darauf an, auf welcher logischen Ebene das Interface I 
selbst angesiedelt ist. Und daher sind solche Namen wie I ziemlich 
schlechte Namen, weil sie nichts darüber verraten, was die Absicht des 
Programmierers war. Ist I eher auf der Seite der abstrakten 
Kommunikationsgeräte angesiedelt oder sollte man bei I eher in Richtung 
Device-Treiber denken?

von Karl H. (kbuchegg)


Lesenswert?

Steve schrieb:
> das Ziel ist das jedes Mal wenn der User den Interface wechselt alles
> neu initalisiere und die richtigen Funktionen aufrufe, ich muss
> irgendwie dynamisch zwischen die Interfaces wechsele ohne jedes Mal den
> Interface zu prüfe und ohne mit:
>
1
> if(interface == USB)
2
>         USB.Init();
3
> else if(interface == RS232)
4
>         RS232.Init();
5
>



Ich denke dir fehlt ganz eindeutig die gemeinsame Basisklasse für USB 
und RS232.

Und nope. So wie du das hier gezeigt hast, macht man das nicht.
Immer wenn du in einer OOP Sprache dazu tendierst, anhand eines Typs 
eine von mehreren Funktionen auszuwählen, solltest du sofort 
'Inheritance' bzw in C++ 'virtuelle Funktion' denken, und den if gleich 
wieder weglöschen.

von Karl H. (kbuchegg)


Lesenswert?

1
public interface DeviceInterface
2
{
3
  int Init();
4
  void Close();
5
  int WriteByte();
6
  int WriteString();
7
  int WriteData();
8
9
  ...
10
}
11
12
public class USB : DeviceInterface
13
{
14
 ...
15
}
16
17
public class RS232 : DeviceInterface
18
{
19
 ...
20
}
21
22
public interface I
23
{
24
    int Init();
25
    void Close();
26
    int WriteData();
27
    int ReadData();
28
}
29
30
public class COM : I 
31
{
32
  DeviceInterface currentDevice;
33
34
  public int init()
35
  {
36
    if( user_auswahl ist USB )
37
      currentDevice = new USB;
38
    else
39
      currentDevice = new RS232;
40
41
    currentDevice.Init();
42
  }
43
44
  public void Close()
45
  {
46
    currentDevice.Close();
47
  }
48
49
  ....
50
}

von Steve (Gast)


Lesenswert?

Ok vielen Dank schon mal.

ist die Struktur unten die richtige Richtung:

                -->  USB Klasse
Basis Klasse -->
                -->   RS232 Klasse

Comm Klasse:
           USB  myUSB
           RS232 myRS232
           Basis myCom

und je nach Interface: myCom = myUSB oder myCom = myRS232?
.
.
.
myCom.Init();

von Steve (Gast)


Lesenswert?

@ Karl heinz Buchegger
ich war langsammer

vielen Dank nochmal, jetzt ist deutlicher.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.