>Salve a tutti ragazzi.
>
>Avrei una domanda da porvi.
>
>Sto creando una piccola applicazione e siccome devo creare alcuni
>oggetti che hanno proprietà e metodi comuni volevo creare una
>superclasse (astratta) all'interno della quale scrivevo proprietà
>e metodi che poi andavo a compilare per ogni oggetto derivato
>da questa classe.
>
>Mi sorge però un dubbio.... La mia scelta era caduta in una classe
>astratta - mustInherits,ma non posso creare anche una Interfaccia??
>
>Sostanzialmente che differenza passa tra una interfaccia ed una
>classe astratta? Non servono entrambe a "dichiarare" uno scheletro
>per delle classi?
>
>Sapete darmi alcune delucidazioni?
>Grazie in anticipo
Ciao,
la scelta tra usare una classe o un interfaccia dipende da molti fattori, ricorda che con la classe non potrai far ereditare nessun altro tipo, mentre con l'interfaccia si. In sostanza dipende molto da cosa devi fare esattamente.
Se vuoi fornire implementazione di una funzione di base, allora è necessaria una classe astratta, ma se ad esempio ti serve per riconoscere il tipo o richiamare i suoi membri allora sarebbe sufficiente una interfaccia.
Osserva il seguente esempio :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
List<Essere_Vivente> EsseriViventi = new List<Essere_Vivente>();
EsseriViventi.Add(new Uomo());
EsseriViventi.Add(new Gatto());
foreach (Essere_Vivente EssereVivente in EsseriViventi)
{
EssereVivente.EmettiSuono();
EssereVivente.Muovi();
}
List<Oggetto> Oggetti = new List<Oggetto>();
Oggetti.Add(new Radio());
Oggetti.Add(new Auto());
foreach (Oggetto Oggetto in Oggetti)
{
Oggetto.Muovi();
}
List<INominabile> ListaNominabili = new List<INominabile>();
ListaNominabili.Add(new Radio());
ListaNominabili.Add(new Auto());
ListaNominabili.Add(new Uomo());
ListaNominabili.Add(new Gatto());
foreach (INominabile Nominabile in ListaNominabili)
{
string nome = Nominabile.Nome;
Nominabile.Nome = "Attribuisco un nome";
}
List<IMobile> ListaMobili = new List<IMobile>();
ListaMobili.Add(new Radio());
ListaMobili.Add(new Auto());
ListaMobili.Add(new Uomo());
ListaMobili.Add(new Gatto());
foreach (IMobile Mobile in ListaMobili)
{
Mobile.Muovi();
}
List<IIMobileENominabile> ListaMobiliENominabili = new List<IIMobileENominabile>();
ListaMobiliENominabili.Add(new Radio());
ListaMobiliENominabili.Add(new Auto());
ListaMobiliENominabili.Add(new Uomo());
ListaMobiliENominabili.Add(new Gatto());
foreach (IIMobileENominabile MobileENominabile in ListaMobiliENominabili)
{
string nome = MobileENominabile.Nome;
MobileENominabile.Nome = "Attribuisco un nome";
MobileENominabile.Muovi();
}
Console.Read();
}
}
public abstract class Essere_Vivente : IMobile, INominabile, IIMobileENominabile
{
public string Nome { get; set; }
public string Verso { get; set; }
public abstract void Muovi();
public void EmettiSuono()
{
Console.WriteLine(Verso);
}
}
public class Uomo : Essere_Vivente
{
public Uomo()
{
this.Verso = "Emetto il mio verso!";
this.Nome = "Antonio";
}
public override void Muovi()
{
Console.WriteLine("Mosso!");
}
}
public class Gatto : Essere_Vivente
{
public Gatto()
{
this.Verso = "Miao";
this.Nome = "Fuffi";
}
public override void Muovi()
{
Console.WriteLine("jump!");
}
public void AffilaUnghie()
{
Console.WriteLine("Grat!");
}
}
public abstract class Oggetto : IMobile, INominabile, IIMobileENominabile
{
public string Nome { get; set; }
public string Materiale { get; set; }
public abstract void Muovi();
public void Accendi()
{
Console.WriteLine("Acceso");
}
public void Spegni()
{
Console.WriteLine("Spento");
}
}
public class Radio : Oggetto
{
public Radio()
{
this.Materiale = "Plastica";
this.Nome = "Radio";
}
public override void Muovi()
{
Console.WriteLine("Mosso indietro");
}
}
public class Auto : Oggetto
{
public Auto()
{
this.Materiale = "Ferro";
this.Nome = "Auto";
}
public override void Muovi()
{
Console.WriteLine("Mosso indietro");
}
}
public interface INominabile
{
string Nome { get; set; }
}
public interface IMobile
{
void Muovi();
}
public interface IIMobileENominabile : INominabile, IMobile { }
}
Come vedi faccio uso di classi astratte, questo perché ipoteticamente il metodo "EmettiSuono" ha un implementazione uguale per tutti gli esseri viventi (in questo caso una semplice scritta a video), quindi è comodo implementarla nella classe base. Ho utilizzato volutamente un metodo muovi in entrambe le classi astratte per attirare la tua attenzione anche su un utilizzo delle interfacce, ovvero, Radio e Uomo (così come Auto e Gatto) pur ereditando da classi astratte di base differenti hanno delle proprietà e metodi in alcuni casi Uguali, quindi potrebbe essere comodo trattarle come tipo che espone quei membri in comune (Muovi() e Nome). Ecco che entrano in gioco le interfacce! Infatti entrambe le classi di base ereditano dalle interfacce (INominabile, IMobile, ed IMobileENominabile), quindi potrei trattarle tranquillamente come uno di quei tipi, in questo modo potrei accedere ai membri in comune utilizzando il tipo interfaccia (INominabile per il solo nome, IMobile per il solo metodo muovi, e IMobileENominabile per entrambi) per qualsiasi tipo sottostante che espone quei membri.
Tutto questo grazie al fatto che di interfacce se ne possono ereditare molteplici, mentre di classe una sola. Quindi la scelta dipende dal lavoro che pensi debbano svolgere.