Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

héritage en C#

5 réponses
Avatar
BR
bonjour,

Conception de classes. J'aurais aimé connaitre la différence entre une
méthode virtuelle que l'on redéfinit dans une sous classe (avec override) par
rapport à une méthode non virtuelle que l'on redéfinit avec new dans la sous
classe.
Question qui va bien avec ..... quel est l'intérêt de déclarer une méthode
virtuelle.... est un moyen de faire de l'abstract dans une classe non
abstraite?
Merci pour les réponses avisées
Bonne journée

5 réponses

Avatar
Jérémy Jeanson
Salut,

J'espère que ma réponse va te sembler claire.
override et new s'utilisent dans deux cas totalement différents.

il faut comprendre que virtual et un mot clé qui te permet d'indiqué qu'une
méthode peut être override (on pourrait dire réécrite) dans une classe.

quand on ne peut pas ajouter virtual (dans le cas où l'on utilise une dll
externe, ou dans le cas où le developpeur qui te fourni sa dll ne veut pas
te permettre un override)
on ne peut pas utiliser l'override. C'est alors que le new entre en scène et
te permet de remplacer la méthode par une "nouvelle".

ne cherche pas new sur d'autres plateforme que .net, c'est juste un mot clé
qui a été ajouté pour nous simplifier la vie.

De tête je crois qu'il est écrit dan la msdn que new n'est à utiliser que
lorsque l'on n'a pas le chois... en plus je crois qu'il existe quelques
incovéniants qui font que dans des cas très précis, on ne peut être certain
que s'est bien la méthode remplacée par le new qui est appelée et non pas la
méthode de base.

En espérant t'avoir été utile.
--
Jérémy JEANSON
MCP
http://jeremy.blogdns.net

"BR" a écrit dans le message de groupe de discussion :

bonjour,

Conception de classes. J'aurais aimé connaitre la différence entre une
méthode virtuelle que l'on redéfinit dans une sous classe (avec override)
par
rapport à une méthode non virtuelle que l'on redéfinit avec new dans la
sous
classe.
Question qui va bien avec ..... quel est l'intérêt de déclarer une méthode
virtuelle.... est un moyen de faire de l'abstract dans une classe non
abstraite?
Merci pour les réponses avisées
Bonne journée


Avatar
BR
Bonjour,

Merci pour ta réponse..... ça me rassure.....je ne suis pas le seul à ne pas
tout bien comprendre....

Effectivement le new masque la méthode de la classe mère, mais il n'est pas
obligatoire...... là ou je ne comprends plus .... c'est à quoi sert le
virtual, si on peut redéfinir toutes les méthodes dans une sous classe......

que se soit en virtual ou non, on peut toujours appeler la méthode de la
classe mère dans la méthode redéfinie dans la classe fille !
ce prog marche très bien!
namespace test_heritage
{
public class mere
{
public virtual void vprocedure()
{
Console.WriteLine("virtuelle dans la classe mère");
}
public void vnormale()
{
Console.WriteLine("normale dans la classe mère");
}
}
public class fille : mere
{
public override void vprocedure()
{
Console.WriteLine("virtuelle dans la classe fille");
base.vprocedure();
}
public void vnormale()
{
Console.WriteLine("normale dans la classe fille");
base.vnormale();
}
}
class Program
{
static void Main(string[] args)
{
fille unefille = new fille();
unefille.vprocedure();
unefille.vnormale();
Console.ReadKey();
}
}
}

merci pour tes réponses éclairées!
Avatar
paulpasdespam.bacelar
new n'est qu'un pis aller. Seul virtual est correct.

Après cette entrée en matière, voici une explication.

En spécifiant qu'une méthode est virtuelle, on indique au compilateur
que cette méthode est redéfinissable. OK, tout le mode à saisis le
principe.
Le compilateur implémente cela par une entré dans une table lié à l a
classe. Il y a une entré par méthode virtuelle dans la classe ET dans
les classes mères. Cette table est en charge de donner une référence à
la méthode virtuelle de la classe quand le compilateur en a besoin
lors de la compilation d'un appel à une méthode virtuelle.
Quand on override une méthode virtuelle ont change l'entré dans cette
table, "hérité" de la classe mère, pour la classe courant.
Si TOTO est la Xème méthode virtuelle de la classe mère, une réfé rence
vers cette méthode est stocké dans la table des méthodes virtuelles d e
la classe mère, en position X si elle ne dérive de personne (c'est une
simplification car on dérive toujours d'Object qui a des méthodes
virtuelles).
Si la classe fille override cette méthode TOTO, la Xème entré de la
table des méthodes virtuelles de la classe fille référencera la
nouvelle méthode. Chaque classe à sa propre table des méthodes
virtuelles mais quand une classe fille hérite de classe mère, la table
des méthodes virtuelles de la classe fille est pré-remplie avec la
table de la classe mère.

Avec ce mécanisme, le compilateur saura qu'un appel à la méthode TOTO
sur un objet de la classe mère ou de la classe fille se résoudra par
un appel à la méthode en Xème position dans leur table.

Ce mécanisme oblige à réserver une place dans la table des méthodes
virtuelles de la classe mère, d'où l'utilisation du mot clé virtual.

Avec new, on utilise pas du tout la même mécanique, on demande au
compilateur de savoir que la méthode TOTO de la classe fille est
différente de la classe mère. Cela marche bien t'en que le compilateur
sait que c'est une classe fille. Mais si, par exemple, une méthode
prend en paramètre un objet de type la classe mère, le compilateur
utilisera l'implémentation de la classe mère de la méthode TOTO, et
cela quelque soit le type d'objet passé en paramètre à la méthode.
Dans le même cas de figure avec une méthode virtuelle, le compilateur
aurait utilisé la table des méthodes virtuelles du type de l'objet
passé en paramètre (une instance d'objet a toujours une référence a ux
méthodes virtuelles de CA classe). En fonction du type d'objet à la
méthode, la méthode sera donc différente.

J'espère qu'avec cette explication vous serait de mon avis pour dire
que "new" c'est mal et virtual c'est bien.

Mais bon, comme toujours, quelques fois, on n'a pas le choix.
Avatar
Jérémy Jeanson
Salut paul, au moins ton avis sur le news est très clair... tu n'aime pas :)

je suis tout a fait d'accord avec toi, je pense cependant qu'il faut que
chacun se fasse son avis sur une syntaxe en fonction de ses besoins.

Personnellement je te rejoins parfaitement mais avec un argumentaire un
peu plus court.
-> Je ne vois pas pourquoi utiliser ailleur quelque chose qui est prévu
pour un cas particulier.

Principe que je m'efforce d'appliquer et qui évite d'utiliser "en
général" un marteau piqueur à la place d'une tapette ... je journal
faisant l'affaire... je parle bien entendu plus de code mais de chasse
au moustiques,

@+

Jérémy JEANSON
MCP
http://jeremy.blogdns.net
Avatar
Christophe Lephay
"BR" a écrit dans le message de groupe de discussion :

bonjour,

Conception de classes. J'aurais aimé connaitre la différence entre une
méthode virtuelle que l'on redéfinit dans une sous classe (avec override)
par
rapport à une méthode non virtuelle que l'on redéfinit avec new dans la
sous
classe.
Question qui va bien avec ..... quel est l'intérêt de déclarer une méthode
virtuelle.... est un moyen de faire de l'abstract dans une classe non
abstraite?
Merci pour les réponses avisées
Bonne journée



Une fonction qui serait déclarée comme étant virtuelle dans la classe de
base permet d'écrire du code qui va fonctionner pour toute classe dérivée
alors même que seule cette classe de base est écrite.

En passant par une fonction new, tu perds toute possibilité de réutilisation
du code qui avait été conçu pour la classe de base. C'est généralement le
signe d'un problème de conception, mais il se peut que ce soit nécessaire si
tu réutilises des classes qui ont été mal conçues et/ou dont tu ne disposes
pas du code source (comme le soulignait Jeremy).

Quant à ta deuxième question, la différence entre une fonction virtuelle et
une fonction abstraite est que la virtuelle peut fournir une implémentation
par défaut. En clair, la première rend la surcharge optionnelle tandis que
la seconde la rend obligatoire. Décider si une méthode doit être virtuelle
ou abstraite n'a rien à voir avec le fait qu'une classe soit elle-même
abstraite ou non, même si une classe ayant une méthode abstraite ne peut
être qu'abstraite.

Tu as un exemple d'une telle implémentation par défaut avec la méthode
ToString() d'object qui, par défaut donc, renvoie le type de l'objet.