C#: Frage zu geerbte Klassen

Gast #1797893
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.
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.
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.
Gast
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
}
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.
Gast
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();
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?
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.
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
}
Gast
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();

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 16 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.