2010-11-18 14 views
0

J'ai quelque chose qui devrait être facile de répondre à la plupart de votre Je pense:C# héritage (débutant)

Je les classes suivantes:

class One 
{ 
string first; 
} 
class Two : One 
{ 
string second; 
} 

Maintenant, je voulais remplacer tous les One valeurs de une valeur deux. J'ai donc essayé ce qui suit:

One one = new One(); 
Two two = new Two(); 
two = (Two) one; // <= this seems to not work 

Alors est-ce que je dois vraiment implémenter une méthode qui copie tous les membres de un à deux?

+0

Puisque deux étend un (aime ce nom;)), la deuxième chaîne n'existe que dans deux et non un. Si vous deviez définir first = "blah" dans Two, cela pourrait fonctionner mais je n'ai pas essayé de faire quelque chose comme ça depuis un moment. – clifgriffin

Répondre

1

En bref: Oui

Comme ce qui a été déjà dit, on ne possèdes pas de deux, donc il n'y a pas d'action par défaut « logique » de prendre ici. Vous devriez regarder dans Conversion Operators. Cela va vous permettre d'utiliser encore les deux = (deux) une syntaxe après avoir défini un opérateur, comme celui-ci (dans la définition de la classe):

public static explicit operator Two(One o) 
    { 
     var t=new Two(); 
     t.first=o.first; 
     t.second="default";//or whatever kind of default value you want 
     return t; 
    } 
2

One n'hérite pas de Two, et c'est ce qui ne fonctionne pas très bien.

L'héritage de classes ne signifie pas cacher ou remplacer la valeur de la propriété d'une classe, mais que la classe dérivée est une spécialisation de la classe de base dont elle hérite.

Par exemple:

public class Cat { 
} 

public class Dog { 
} 

Qu'est-ce que ces deux ont en commun?

  1. Ils ont quatre pieds;
  2. Ce sont tous des animaux;
  3. Ils ont des poils;

Qu'est-ce qu'ils n'ont pas en commun?

  1. Un chat miaule;
  2. Un chien aux aboiements;

Révisons notre modèle en le mettant dans l'ordre.

public class Cat { 
    public bool HasHair { get { return true; } } 
    public int Legs { get { return 4; } } 
    public string Speaks { get { return "Meows"; } } 
} 

public class Dog { 
    public bool HasHair { get {return true; } } 
    public int Legs { get { return 4; } } 
    public string Speaks { get { return "Barkles"; } } 
} 

Maintenant, pour gagner du temps et coder, que pourrions-nous faire? Généraliser ce que les deux classes ont en commun? Bien! Mais comment le faire ainsi?

public class Animal { 
    public bool HasHair { get { return true; } } 
    public int Legs { get { return 4; } } 
    public virtual string Speaks { get { return "Does a sound"; } }   
} 

// We can now inherit from Animal to write our Cat and Dog classes. 
public class Cat : Animal { 
    public overrides string Speaks { get { return "Meows"; } } 
} 

public class Dog : Animal { 
    public overrides string Speaks { get { return "Barkles"; } } 
} 

Et vous pouvez faire:

Dog dog = new Dog(); 
dog.Legs; // Because Legs is an Animal property, and a Dog inherits from Animal, then Dog has a property called Legs, since it got it from his base class. 

Maintenant, nous pouvons faire:

Animal pet = (Animal)(new Cat()); 

Cela dit, vous pouvez typer un Cat à un Animal, parce qu'il est une Animal! Maintenant, vous devez considérer que votre Cat typecasted va "faire un bruit", au lieu de "meowling", car en tapant Cat à Animal, vous dites que vous voulez travailler avec Animal, tant qu'il est un. Donc, les deux Cat et Dog sont des animaux.

Nous pourrions pousser notre exemple encore plus loin en disant que tous les animaux n'ont pas quatre pattes, certains n'en ont pas et d'autres n'en ont que deux. Ensuite, il faudrait généraliser et se spécialiser en conséquence.

+0

Même si c'est le cas, il n'y a aucun moyen d'utiliser cette syntaxe (ou quelque chose comme ça) pour copier uniquement les membres de la classe de base. – sblom

+0

@sblom: D'accord.Mais ce n'était pas mon point ici. Je voulais juste montrer quelques notions de base sur l'héritage de classe. De plus, ce que l'OP avait l'intention de faire comme écrit dans son exemple de code de question, c'est de classer son instance de classe 'One' en type' Two', tout en essayant de faire autre chose (copier les valeurs des membres). Évidemment, il y a quelque chose d'incompris à propos du typage et de l'héritage, donc je l'ai simplement expliqué avec un exemple simple. =) –

+0

Cela ne répond pas à ma question mais donne un bon aperçu de l'héritage. Je vous remercie. – fpdragon

0

Vous ne pouvez pas diffuser un One en tant que Two car One n'hérite pas de Two. L'autre façon serait autour du travail bien que (Two two = new One();)

Afin d'obtenir un Two d'un One vous devrez créer une nouvelle Two. Vous pourriez avoir une méthode qui copie tous les membres de One à Two ou vous pourriez avoir un constructeur pour Two qui prend un One et définit les propriétés à partir de là.

0

Oui, vous devez mettre en œuvre une méthode qui copie tous les membres one à two. Normalement, vous faites un constructeur:

public Two(One one) { 
    this.first = one.first; 
} 

// Elsewhere ... 
Two two = new Two(one); 

Ou si vous voulez copier sur les valeurs d'une instance existante, vous pouvez le faire avec une méthode d'instance:

public void CopyValuesFrom(One one) { 
    this.first = one.first; 
} 

// Elsewhere ... 
Two two = new Two(); 
two.CopyValuesFrom(one); 
0

Il est important se rappeler que les uns et les deux ne sont que des pointeurs en mémoire d'une instance d'un objet.

Si nous devions écrire ceci en anglais simple, il lisait quelque chose comme ceci:

One one = new One(); 

Créer un pointeur dans la mémoire qui fait référence à un objet de type One et étiquetez une, puis créez un objet de type One et placez-le à l'emplacement de mémoire indiqué par un.

two = (Two) one; 

Remplacer l'objet référencé par deux avec l'objet référencé par un et traitent comme si elle était un objet de type Two

En plus à partir du problème de frappe évident que vous avez, cela ne fera que remplacer l'objet référencé en mémoire, ne pas copier les valeurs en om un à l'autre.