2012-11-23 17 views
11

Nuovo a OOP e sono confuso da come i costruttori di classe derivata funzionano quando ereditano da una classe base in C#.Costruttore Parametri ed Eredità

prima della classe base:

class BaseClass 
{ 
    private string BaseOutput = null; 

    public BaseClass(string BaseString) 
    { 
     BaseOutput = BaseString; 
    } 

    public virtual void PrintLine() 
    { 
     Console.WriteLine(BaseOutput); 
    } 
} 

Ecco la classe derivata:

class SubClass : BaseClass 
{ 
    private string SubOutput = null; 

    public SubClass(string BaseString, string SubString) : base(BaseString) 
    { 
     SubOutput = SubString; 
    } 

    public override void PrintLine() 
    { 
     Console.WriteLine(SubOutput); 
    } 
} 

Infine, la parte principale del programma:

class Program 
{ 
    static void Main(string[] args) 
    { 
     BaseClass theBase = new BaseClass("Text for BaseClass"); 
     SubClass theSub = new SubClass("2nd param", "Text for SubClass"); 

     theBase.PrintLine(); 
     theSub.PrintLine(); 

     Console.ReadKey(); 
    } 
} 

Quello che non mi è perché, quando si chiama il costruttore per la classe derivata, devo anche passare il parametro di cui ha bisogno la classe base. Il campo BaseOutput nella classe derivata non dovrebbe rimanere impostato su null se non viene assegnato alcun valore? Perché non è possibile una cosa del genere di lavoro:

public SubClass(string SubString) : base(BaseString) 

Inoltre, quando si chiama il costruttore in questa classe derivata, il primo parametro deve essere nominato lo stesso di quello nella classe base oppure si genera un errore. Se dovessi definire una nuova variabile stringa chiamata AnotherString nella classe derivata, perché non sarebbe questo lavoro:

public SubClass(string AnotherString, string SubString) : base(BaseString) 

Infine, quando si esegue questa operazione nel modo giusto e digita questo ...

public SubClass(string BaseString, string SubString) : base(BaseString) 

... qual è il primo parametro utilizzato nel costruttore SubClass? Non viene assegnato o utilizzato in alcun metodo per la mia classe derivata. Perché devo persino metterlo lì?

+0

Viene memorizzato per una frazione di secondo finché non si chiama il costruttore delle sottoclassi. Quindi lo si sovrascrive con la stringa del parametro "2nd param". –

risposta

14

Per quanto riguarda il motivo per cui non si può fare:

public SubClass(string SubString) : base(BaseString) 

Che cosa sarebbe BaseString?

Si potrebbe fare:

public SubClass(string SubString) : base("SomeFixedString") 

o

public SubClass(string SubString) : base(SubString) 

Ma se si vuole passare una stringa il parametro del costruttore della classe base e hanno uno supplementare, avrete bisogno di accettare due parametri.

Come per mantenere lo stesso nome, è non. Si potrebbe fare:

public SubClass(string AnotherString, string SubString) : base(AnotherString) 

Per quanto riguarda l'ultima domanda, il primo parametro non sta facendo nulla, è stato passato al costruttore della classe base. Potresti usarlo per qualcos'altro se lo volessi.

+0

Questo ha molto più senso per me ora, grazie. Il 'BaseClass' ha bisogno di informazioni da passare al suo costruttore e lo estrae da ciò che viene inserito nel costruttore derivato. – Frank

1

Se si desidera inizializzare BaseString con valore di default, quindi passare tale valore alla base di costruttore di classe (e quindi non si deve passare il parametro al costruttore della classe derivata)

public SubClass(string SubString) : base(null) 

Oppure stabilire costruttore senza parametri in classe base.

Informazioni sulla denominazione dei parametri: non importa quale sia il nome del parametro, che si sta passando al costruttore derivato. L'unica cosa che importa è un valore che stai passando al costruttore base.

public SubClass(string AnotherString, string SubString) : base(AnotherString) 
1
public SubClass(string BaseString, string SubString) : base(BaseString) 

Questo costruttore nella classe derivata dice che quando si riceve due argomenti BaseString e SubString, chiamare il costruttore della classe base con BaseString.

Così, facendo

public SubClass(string a, string b) : base(BaseString) 

non funziona, perché si sta dicendo per chiamare il costruttore della classe base con BaseString ma non v'è alcun argomento chiamato BaseString.

Se si desidera creare un'istanza della classe derivata senza passare una stringa al costruttore della classe base, la classe di base ha bisogno di un costruttore di default:

public BaseClass() { } 
1

Se si desidera fornire l'opportunità per la classe derivata non impostare il basestring, allora avete bisogno di fornire un costruttore di default nella classe base in questo modo:

public BaseClass() 
{ 

} 

Ora nella classe derivata, si può chiamare il costruttore senza argomenti nella classe base in questo modo:

public SubClass(string AnotherString) 
    : base() 
{ 
    // base() => explicit call to default construct in the base class. 
    // Do something else 
} 

questo fornisce le buone pratiche di ingegneria del software: se si desidera fornire l'opportunità di non impostare stringa della classe base, poi farlo nella classe base . Altri "hack" come passare null come argomento al costruttore base servono solo a armeggiare con gli interni della classe base in modi che non dovrebbero essere fatti da sottoclassi.

+0

Dopo aver letto alcune delle altre risposte, posso sicuramente vedere il valore di avere un costruttore predefinito. Lo farò d'ora in poi, invece di passare i valori fittizi, grazie! – Frank