Ohne weitere Details zu wissen, was die Condition-Funktion tut, haben Sie zwei Möglichkeiten.
One, können Sie so etwas wie
if (f.GetType() == typeof(FireBall))
{
fireBall = (FireBall)f;
fireBall.FireTheFireBall();
}
else if (f.GetType() == typeof(Heal))
...
Oder Ihre Fähigkeit tun eine abstrakte Activate-Methode haben, die alle abgeleiteten Klassen zu überlasten sind erforderlich:
class Fireball
{
public override void Activate()
{
//do fireball specific things
this.FireTheFireBall();
}
public void FireTheFireBall() {...}
}
class Heal
{
public override void Activate()
{
//do healing specific things
this.ApplyTheBandage();
}
...
}
abstract class Ability
{
public abstract void Activate();
}
void condition(Ability f){
f.Activate(); //runs the version of Activate of the derived class
}
Dann jede Sache, die funktioniert mit einer Fähigkeit kann someAbility.Activate() aufrufen und die von der abgeleiteten Klasse bereitgestellte Implementierung wird ausgeführt.
Sie sollten auch auf Schnittstellen studieren, die wie abstrakte Klassen sind. Der Vorteil von Schnittstellen besteht darin, dass Sie mehrere davon implementieren können, während Sie nur von einer abstrakten Basisklasse geerbt werden. Denken Sie an eine IKnob-Schnittstelle mit Turn- und Pull-Funktionen. Möglicherweise haben Sie eine Drawerklasse, die IKnob, eine Door-Klasse, eine TrappedDoor-Klasse implementiert, die Turn implementiert und einen Trap aktiviert. Ein Spieler geht zu einer Tür auf und trifft auf die Verwendung Taste darauf, und Sie passieren in die offene Funktion das Objekt, Open (IKnob Knopf)
void Open(IKnob knob)
{
knob.Turn();
knob.Pull();
}
class TrappedDoor:IKnob,IMaterial,ISomethingElse,IHaveTheseOtherCapabilitiesAsWell
{
private bool TrapAlreadySprung{get;set;}
//more complex properties would allow traps to be attached either to the knob, or the door, such that in one case turning the knob activates the trap, and in the other, Pull activates the trap
public Turn() {
if(! TrapAlreadySprung)
{
MessageBox("You hit your head, now you're dead");
}
}
}
Es gibt Möglichkeiten, zu überprüfen, ob etwas eine Schnittstelle hat, also wenn Wenn ein Spieler auf ein Objekt zugeht und versucht, mit ihm zu sprechen, können Sie überprüfen, ob das Objekt die ICanTalk-Schnittstelle hat. Wenn dies der Fall ist, wird object.GetReply ("Hello") aufgerufen und das Objekt kann antworten. So können Sie sprechen Türen und Felsen, wenn Sie es wünschen. Sie erhalten all Ihren Code, der das Sprechen mit Dingen/das Anzeigen von Antworten usw. behandelt, die mit ICanTalk-Schnittstellenmethoden arbeiten, und dann können andere Klassen ICanTalk implementieren und sie entscheiden jeweils, wie sie reagieren, um mit ihnen gesprochen zu werden. Dieses Konzept wird als "Trennung von Problemen" bezeichnet und hilft Ihnen, mehr wiederverwendbaren Code zu erstellen.
Die wichtige Sache ist, dass Sie ein Stück Code, einen Algorithmus, eine Funktion usw. schreiben können, die nur mit dieser Schnittstelle funktionieren, und auf diese Weise können Sie diese Schnittstelle dann verwenden, sobald Sie den Code mit der Schnittstelle arbeiten jede Klasse, und diese Klasse kann den bestehenden Code nutzen.
I.e. Ihre condition
-Funktion, wenn es in einer IAbility-Schnittstelle dauerte, sobald Sie diesen Code arbeiten, dann kann jede Klasse, die Sie erstellen, die IAlability implementiert, an die Bedingungsfunktion übergeben werden. Die Bedingungsfunktion ist dafür verantwortlich, das zu tun, was auch immer sie tun soll, und die Klasse, die die Flugfähigkeit implementiert, kümmert sich innerhalb der implementierten Methoden um alles, was für sie spezifisch ist.
Natürlich müssen die Klassen, die die abstrakte Klasse oder Schnittstelle implementieren, die erforderlichen Methoden implementieren, sodass Sie manchmal das Gefühl haben, dass Sie Code duplizieren. Wenn Sie beispielsweise ähnliche Klassen wie TrappedDoor und Door haben, verhält sich TrappedDoor möglicherweise genauso wie eine normale Tür, wenn die Falle nicht gesetzt ist. Sie können also in diesem Fall entweder von Door erben oder eine private Door-Eigenschaft haben (bekannt als "Komposition"). Wenn der Trap bereits gefedert ist, können Sie die Basis-Door-Klasse oder die private Door-Eigenschaft aufrufen und Call. Turn, so dass Sie einfach das Standardverhalten einer regulären Tür wiederverwenden, falls der Trap nicht aktiv ist.
Test if object implements interface
Ich persönlich verwende meist Schnittstellen und Zusammensetzung, anstelle der Vererbung. Nicht diese Vererbung ist schrecklich, aber Vererbungshierarchien können schnell sehr kompliziert werden.
Klassisches OOP-Polymorphie/Vererbungs-Problem :) Es ist schwer und macht Spaß, an eine Lösung zu denken, die entweder die Kapselung bewahrt und Komfort nutzt. +1. – dreamzor
Was hat das mit Objective C zu tun? –
Entschuldigung, ich schätze, ich habe es falsch markiert. –