| Autor |
Beitrag |
delphijanka
      
Beiträge: 151
WinXP
D 2009 Arc., Java, C
|
Verfasst: Fr 17.09.10 16:13
Hallo. Habe ein Problem. Gegeben:
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34:
| type ILaufer = Interface procedure laufe; end;
type ISpringer = Interface procedure springe; end;
type TTier = class(TInterfacedObject) procedure esse; end;
type TElefant = class(TTier , ILaufer) procedure laufe; end;
type TKenguru = class(TTier, TSpringer) procedure springe; end;
type TLeopard = class(TTier, TLaufer, TSpringer) procedure laufe; procedure springe; end; |
So verwalte ich meine Tiere:
Delphi-Quelltext 1: 2:
| var Tiere = array of TTier; |
Nun möchte ich die Fähigkeiten der Tiere ausnutzen, was in Pseudo so aussieht:
wenn Tier[i] ist ein ISpringer
dann (Tier[i] als ISpringer).springe;
Ich weiß allerdings nicht, wie es geht. Kann mir einer helfen? Danke.
Moderiert von Narses: Code- durch Delphi-Tags ersetzt
|
|
Martok
      
Beiträge: 3661
Erhaltene Danke: 604
Win 8.1, Win 10 x64
Pascal: Lazarus Snapshot, Delphi 7,2007; PHP, JS: WebStorm
|
Verfasst: Fr 17.09.10 16:40
_________________ "The phoenix's price isn't inevitable. It's not part of some deep balance built into the universe. It's just the parts of the game where you haven't figured out yet how to cheat."
|
|
delphijanka 
      
Beiträge: 151
WinXP
D 2009 Arc., Java, C
|
Verfasst: Fr 17.09.10 16:51
@Martok
Lösung (a):
- geht schon mal nicht: "Operator not applicable to this operand type"
Lösung (b):
- die Methode QueryInterface ist nicht bekannt.
- Was schreibe ich an der {...} - Stelle? Wie erzeuge ich ein Objekt von ISpringer?
|
|
Martok
      
Beiträge: 3661
Erhaltene Danke: 604
Win 8.1, Win 10 x64
Pascal: Lazarus Snapshot, Delphi 7,2007; PHP, JS: WebStorm
|
Verfasst: Fr 17.09.10 17:12
(a) Könnte sogar stimmen, damit man sowas tun kann, braucht das Interface eine GUID. Steht irgendwo in der Delphi-Hilfe welche Tastenkombination das war und was genau man damit tun soll.
(b) Faszinierend. Das ist in TInterfacedObject wirklich protected. Dann eben anders und noch schöner
Delphi-Quelltext 1: 2: 3: 4:
| var Springtier: ISpringer;
if Supports(Tier[i], ISpringer, Springtier) then SpringTier.springe; |
Anstelle der Auslassung dürfte wohl mindestens ein begin und ein for kommen. Aber das musst du schon wissen...
_________________ "The phoenix's price isn't inevitable. It's not part of some deep balance built into the universe. It's just the parts of the game where you haven't figured out yet how to cheat."
|
|
delphijanka 
      
Beiträge: 151
WinXP
D 2009 Arc., Java, C
|
Verfasst: Fr 17.09.10 17:15
@Martok
Wie ich erstelle ich ein Objekt vom Interface-Typ. In diesem Fall vom ISpringer?
|
|
mkinzler
      
Beiträge: 4106
Erhaltene Danke: 13
Delphi 2010 Pro; Delphi.Prism 2011 pro
|
Verfasst: Fr 17.09.10 19:05
Man kann kleine Instanzen von Interfacen erzeugen. Du musst eine Klasse von dem Interface ableiten und diese dann instantiieren
_________________ Markus Kinzler.
|
|
delphijanka 
      
Beiträge: 151
WinXP
D 2009 Arc., Java, C
|
Verfasst: Mo 20.09.10 00:55
@Martok und mkinzler:
Die Prozeduren QueryInterface oder Supports erwarten Interface-Parameter vom Typ TGuid, wogegen ISpringer nicht von diesem Typ ist.
Daher kommt die Fehlermeldung. Gibt es denn keine Lösung für mein Problem in Delphi? Muss ich unbedingt die Deklaration mit TGuid machen?
(Warum ist das in Delphi nur so kompliziert?...  ). Wäre sehr dankbar für eine funktionierende Lösung.
|
|
Martok
      
Beiträge: 3661
Erhaltene Danke: 604
Win 8.1, Win 10 x64
Pascal: Lazarus Snapshot, Delphi 7,2007; PHP, JS: WebStorm
|
Verfasst: Mo 20.09.10 01:11
Martok hat folgendes geschrieben : | | (a) Könnte sogar stimmen, damit man sowas tun kann, braucht das Interface eine GUID. Steht irgendwo in der Delphi-Hilfe welche Tastenkombination das war und was genau man damit tun soll. |
Hilfeseiten dazu: "Schnittstellentypen" (kriegt man bei F1 auf "interface") und "Identifikation einer Schnittstelle" von da aus.
Sobald du das Interface identifizierbar gemacht hast durch Vergabe eine GUID kannst du es anstelle von GUIDs verwenden.
_________________ "The phoenix's price isn't inevitable. It's not part of some deep balance built into the universe. It's just the parts of the game where you haven't figured out yet how to cheat."
|
|
delfiphan
      
Beiträge: 2684
Erhaltene Danke: 32
|
Verfasst: Mo 20.09.10 12:22
Wenn du innerhalb der Hierarchie bleibst und nicht irgendwie quer oder hoch castest, dann kannst du einfach ILaufer(...) schreiben und brauchst auch keine GUIDs.
Also von TTier auf ISpringer brauchst du GUIDs, von TLeopard nicht. Hängt ein wenig vom Anwendungsfall ab.
|
|
delphijanka 
      
Beiträge: 151
WinXP
D 2009 Arc., Java, C
|
Verfasst: Fr 24.09.10 15:08
zu der Lösung, wie Martok sie vorgeschlagen hat, eine kleine Abwandlung, die
ich in meinem Prog benutze:
Delphi-Quelltext 1: 2: 3: 4: 5: 6:
| var SpringTier: IPDFErzeuger; Unk: IUnknown; begin if Tier[i].GetInterface(IUnknown, Unk) and Supports(Unk, ISpringer, SpringTier) then SpringTier.springe; |
Und dabei habe ich ein Problem: das Objekt Tier[i] wird nach diesem Code automatisch freigegeben. Liegt es an Referenzzählung? Wie kann ich erreichen, dass es nicht freigegeben wird (ich muss Tier[i] ja weiter benutzen...)
|
|
bummi
      
Beiträge: 1248
Erhaltene Danke: 187
XP - Server 2008R2
D2 - Delphi XE
|
Verfasst: Fr 24.09.10 15:42
Hat mich auch schon viele Nerven gekostet...
nimm TinterFacedPersistent, dann tickt es so wie wir es wollen.
|
|
delphijanka 
      
Beiträge: 151
WinXP
D 2009 Arc., Java, C
|
Verfasst: So 26.09.10 17:51
@bummi
Bei der Nutzung von TInterfacedPersistent kommt der Fehler, der Bezeichner sei undefiniert.
(benutze zur Zeit Delphi 5)
|
|