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.
Ä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
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.
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.
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 | }
|
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();
@ 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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.