In C#, si può definire una gerarchia di classi usando l'ereditarietà, che permette a una classe derivata (Car) di ereditare il comportamento e i dati della sua classe genitore (Vehicle). Se non viene specificato alcun genitore, la classe eredita dalla classe object.
Le classi genitore possono fornire funzionalità alle classi derivate in tre modi:
virtual, che è come un metodo normale ma che le classi derivate possono modificare.abstract, cioè un metodo senza implementazione che le classi derivate devono implementare. Una classe con metodi abstract deve essere contrassegnata come abstract a sua volta. Le classi astratte non possono essere istanziate.Il modificatore di accesso protected permette di accedere a un membro di una classe genitore all'interno di una classe derivata, ma blocca l'accesso dalle altre classi.
Le classi derivate possono accedere ai membri della classe genitore tramite la parola chiave base.
// Inherits from the 'object' class
abstract class Vehicle
{
// Can be overridden
public virtual void Drive()
{
}
// Must be overridden
protected abstract int Speed();
}
class Car : Vehicle
{
public override void Drive()
{
// Override virtual method
// Call parent implementation
base.Drive();
}
protected override int Speed()
{
// Implement abstract method
}
}
Il costruttore di una classe derivata chiama automaticamente il costruttore della sua classe genitore prima di eseguire la logica del proprio costruttore. Gli argomenti possono essere passati al costruttore di una classe genitore usando la parola chiave base:
abstract class Vehicle
{
protected Vehicle(int wheels)
{
Console.WriteLine("Called first");
}
}
class Car : Vehicle
{
public Car() : base(4)
{
Console.WriteLine("Called second");
}
}
Quando più classi derivano da una classe base, spesso queste due (o più) classi implementano versioni diverse di un metodo della classe base. Questo è un principio molto importante chiamato polimorfismo. Per esempio, in una variazione dell'esempio precedente mostriamo come il codice che usa Vehicle possa cambiare comportamento a seconda del tipo di veicolo che è stato istanziato.
abstract class Vehicle
{
public abstract string GetDescription();
}
class Car : Vehicle
{
public Car()
{
}
public override string GetDescription()
{
return "Runabout";
}
}
class Rig : Vehicle
{
public Rig()
{
}
public override string GetDescription()
{
return "Big Rig";
}
}
Vehicle v1 = new Car();
Vehicle v2 = new Rig();
v1.GetDescription();
// => Runabout
v2.GetDescription();
// => Big Rig
In questo esercizio giocherai a un gioco di ruolo chiamato "Wizard and Warriors", che ti permette di interpretare un Wizard o un Warrior.
Ci sono regole diverse per i Warrior e i Wizard per determinare quanti punti di danno infliggono.
Per un Warrior, le regole sono queste:
Per un Wizard, le regole sono queste:
In generale, i personaggi non sono mai vulnerabili. Tuttavia, i Wizard sono vulnerabili se non hanno preparato un incantesimo.
Hai sei compiti che lavorano con i personaggi Warrior e Wizard.
Sovrascrivi il metodo ToString() della classe Character per restituire una descrizione del personaggio, formattata come "Character is a <CHARACTER_TYPE>".
var warrior = new Warrior();
warrior.ToString();
// => "Character is a Warrior"
Assicurati che il metodo Character.Vulnerable() restituisca sempre false.
var warrior = new Warrior();
warrior.Vulnerable();
// => false
Implementa il metodo Wizard.PrepareSpell() per permettere a un Wizard di preparare un incantesimo in anticipo.
var wizard = new Wizard();
wizard.PrepareSpell();
Assicurati che il metodo Vulnerable() restituisca true se il wizard non ha preparato un incantesimo; altrimenti, restituisci false.
var wizard = new Wizard();
wizard.Vulnerable();
// => true
Implementa il metodo Wizard.DamagePoints() per restituire i punti di danno inflitti: 12 punti di danno quando è stato preparato un incantesimo, 3 punti di danno quando non lo è.
var wizard = new Wizard();
var warrior = new Warrior();
wizard.PrepareSpell();
wizard.DamagePoints(warrior);
// => 12
Implementa il metodo Warrior.DamagePoints() per restituire i punti di danno inflitti: 10 punti di danno quando l'obiettivo è vulnerabile, 6 punti di danno quando non lo è.
var warrior = new Warrior();
var wizard = new Wizard();
warrior.DamagePoints(wizard);
// => 10
Iscriviti a Exercism per imparare e padroneggiare C# con 62 concetti178 esercizi e il mentoring di persone reali, tutto gratis.