OVH Cloud OVH Cloud

method static et surchage à l'héritage

5 réponses
Avatar
# Cyrille37 #
Bonjour,

Il semble impossible de surcharger une m=E9thode static lors de l'h=E9rit=
age.
C# interdit l'usage de abstract, virtual et override.

Du coup je suis obliger d'instancier un objet pour avoir acc=E8s =E0 une =
donn=E9es que j'aurais souhait=E9 static.

Voil=E0 ce que j'aurais voulu faire, =E9crit d'une fa=E7on qui n'est pas =
autoris=E9e :

class A
{
public virtual string GetTopic()
{
return 'unknow' ;
}
}
class B
: A
{
public virtual string GetTopic()
{
return 'TopicABCD' ;
}
}

Pouvez vous m'indiquer comment vous feriez ?
Comment dois-je repenser la chose ?

J'imagine qu'il n'y a qu'un moyen : faire un constructeur sans param=E8tr=
e et instancier un objet pour acc=E8der =E0 la donn=E9e.

Merci beaucoup pour vos retours, j'ais du mal modeler mes r=E9flexions av=
ec les r=E8gles d'h=E9ritages de C#.

cyrille

5 réponses

Avatar
Christophe Gricourt
Les membres statiques sont un concept qui s'appliquent aux classes.
La surcharge est un concept qui s'applique aux instances.
Je ne vois pas bien l'utilité de vouloir combiner les deux...

EN tout cas, rien ne t'empêche de redéfinir la méthode GetTopic dans la classe
B (ce qui a pour effet de masquer la méthode GetTopic héritée de A, bien sûr)

Tu peux également initialiser un membre statique dans un constructeur statique,
mais là encore tu auras un problème car un constructeur statique ne peut
pas appeler le constructeur de sa classe parente (fût-il statique)

hth
- Christophe




Bonjour,

Il semble impossible de surcharger une méthode static lors de l'hérit
age.
C# interdit l'usage de abstract, virtual et override.
Du coup je suis obliger d'instancier un objet pour avoir accès à une
données que j'aurais souhaité static.

Voilà ce que j'aurais voulu faire, écrit d'une façon qui n'est pas
autorisée :

class A
{
public virtual string GetTopic()
{
return 'unknow' ;
}
}
class B
: A
{
public virtual string GetTopic()
{
return 'TopicABCD' ;
}
}
Pouvez vous m'indiquer comment vous feriez ?
Comment dois-je repenser la chose ?
J'imagine qu'il n'y a qu'un moyen : faire un constructeur sans
paramètr e et instancier un objet pour accèder à la donnée.

Merci beaucoup pour vos retours, j'ais du mal modeler mes réflexions
av ec les règles d'héritages de C#.

cyrille



Avatar
# Cyrille37 #
Christophe Gricourt wrote:

EN tout cas, rien ne t'empêche de redéfinir la méthode GetTopic d ans la
classe B (ce qui a pour effet de masquer la méthode GetTopic hérité e de
A, bien sûr)



C'est justement ce que je n'arrivait pas à faire.
Mais après lecture de ton message j'ais essayé à nouveau et réuss i.

En fait j'utilisait 'override' pour redéfinir la méthode dans les cla sses héritières, et le compilateur faisait 'pouët'.
Erreur: "Un membre static 'B.GetTopic()' ne peut pas être marqué comm e override, virtual ni abstract"

J'avais oublié 'new'. avec 'new' ça fonctionne, le compilateur est co ntent.

Merci pour ton aide qui m'a forcé à reprendre les choses.
bye
cyrille.
Avatar
# Cyrille37 #
Christophe Gricourt wrote:

Les membres statiques sont un concept qui s'appliquent aux classes.
La surcharge est un concept qui s'applique aux instances.
Je ne vois pas bien l'utilité de vouloir combiner les deux...




Je reviens sur le sujet, pour montrer l'utilité que je trouve à l'app lication de 'virtual' sur des méthodes de classe
(static).

<code>
class A
{
public static virtual string GetTopicDomain()
{
return "unknow" ;
}
public static string Topic
{
// C'est ici que serait appelé la bonne méthode correspondant à la classe grâce à 'virtual'
return GetTopicDomain();
}
}
class B : A
{
public static virtual string GetTopicDomain()
{
return "TopicB" ;
}
}
class C : B
{
public static virtual string GetTopicDomain()
{
return "TopicBC" ;
}
}
...
unObjectX.SubscribeTopic( B.Topic );
unObjectY.SubscribeTopic( C.Topic );
...
void MsgArrived( A a )
{
if( a is B ){
...
}else if( a is C ){
...
}
}
</code>

Avec les limitations actuelles je suis obligé de faire de la façon su ivante :
<code>
unObjectX.SubscribeTopic( (new B()).Topic );
</code>

Et donc de réserver le constructeur sans paramètre pour cette forme d 'usage.

Mon argumentation est-elle plus clair ?

cyrille.
Avatar
Paul Bacelar
Vous n'avez pas encore l'habitude de la conception objet.
Les méthodes statics sont comme des fonctions dans un namespace
correspondant à la classe et étant déclaré comme ami(friend fu C++) de la
classe.
Le sens de "virtual" n'est pas un hack pour écrire moins de code mais toute
autre chose.
Un méthode est dite virtuelle si sa définition précise ne peux être connu au
moment de la compilation mais uniquement quand le code utilisera un objet de
type de la classe définissant la méthode ou un objet de la classe dérivée.
Dans ce cas, le code ne connait pas le type( la classe) de l'objet mais sait
que l'objet est d'une classe donné ou donne de ces classes dérivées.

Dans ton cas d'utilisation, cela ne sert qu'à rendre ton code encore plus
illisible, car lors de l'appel de Topic, la classe effective est connue, ne
néssécitant aucunnnement le concept de méthode virtuelle.

<CODE>
class A
{
public static string GetTopicDomain()
{
return "unknow" ;
}

public virtual bool ProcessMessageArrived()
{
...
}
}
class B : A
{
public static string GetTopicDomain()
{
return "TopicB" ;
}
}
class C : B
{
public static string GetTopicDomain()
{
return "TopicBC" ;
}
public override bool ProcessMessageArrived()
{
...
}
}
...
unObjectX.SubscribeTopic( B.GetTopicDomain());
unObjectY.SubscribeTopic( C.GetTopicDomain());
...
void MsgArrived( A a )
{
A.ProcessMessageArrived();
}
</CODE>
--
Paul Bacelar
MVP VC++

"# Cyrille37 #" wrote in message
news:
Christophe Gricourt wrote:

Les membres statiques sont un concept qui s'appliquent aux classes.
La surcharge est un concept qui s'applique aux instances.
Je ne vois pas bien l'utilité de vouloir combiner les deux...




Je reviens sur le sujet, pour montrer l'utilité que je trouve à
l'application de 'virtual' sur des méthodes de classe
(static).

<code>
class A
{
public static virtual string GetTopicDomain()
{
return "unknow" ;
}
public static string Topic
{
// C'est ici que serait appelé la bonne méthode correspondant à la
classe grâce à 'virtual'
return GetTopicDomain();
}
}
class B : A
{
public static virtual string GetTopicDomain()
{
return "TopicB" ;
}
}
class C : B
{
public static virtual string GetTopicDomain()
{
return "TopicBC" ;
}
}
...
unObjectX.SubscribeTopic( B.Topic );
unObjectY.SubscribeTopic( C.Topic );
...
void MsgArrived( A a )
{
if( a is B ){
...
}else if( a is C ){
...
}
}
</code>

Avec les limitations actuelles je suis obligé de faire de la façon suivante
:
<code>
unObjectX.SubscribeTopic( (new B()).Topic );
</code>

Et donc de réserver le constructeur sans paramètre pour cette forme d'usage.

Mon argumentation est-elle plus clair ?

cyrille.
Avatar
Bruno Jouhier
"Paul Bacelar" a écrit dans le message
de news: %
Vous n'avez pas encore l'habitude de la conception objet.



Il se pourrait aussi que l'OP ait une trop grande habitude de la
programmation orientéé objet!

En SmallTalk (et dans quelques autres langages OO), les méthodes statiques
sont des méthodes de la métaclass. Et comme les métaclasses héritent les
unes des autres de la même manière que les instances, on peut faire du
polymorphisme sur les méthodes de classe (l'équivalent des méthodes
statiques dans ces langages).

De mon point de vue, SmallTalk est dans l'erreur sur ce point, car le fait
que les instances soient liées par une relation d'héritage (une relation "is
a") n'implique pas que leurs classes soient liées par une relation
d'héritage (au niveau classe, la relation est plutôt "inherits from" que "is
a"). Le choix de .NET, qui consiste à limiter l'héritage et le polymorphisme
aux instances me semble donc préférable. Mais un programmeur SmallTalk va
naturellement se trouver frustré de ne pas pouvoir utiliser override sur des
méthodes statiques.

Bruno.


Les méthodes statics sont comme des fonctions dans un namespace
correspondant à la classe et étant déclaré comme ami(friend fu C++) de la
classe.
Le sens de "virtual" n'est pas un hack pour écrire moins de code mais
toute autre chose.
Un méthode est dite virtuelle si sa définition précise ne peux être connu
au moment de la compilation mais uniquement quand le code utilisera un
objet de type de la classe définissant la méthode ou un objet de la classe
dérivée. Dans ce cas, le code ne connait pas le type( la classe) de
l'objet mais sait que l'objet est d'une classe donné ou donne de ces
classes dérivées.

Dans ton cas d'utilisation, cela ne sert qu'à rendre ton code encore plus
illisible, car lors de l'appel de Topic, la classe effective est connue,
ne néssécitant aucunnnement le concept de méthode virtuelle.

<CODE>
class A
{
public static string GetTopicDomain()
{
return "unknow" ;
}

public virtual bool ProcessMessageArrived()
{
...
}
}
class B : A
{
public static string GetTopicDomain()
{
return "TopicB" ;
}
}
class C : B
{
public static string GetTopicDomain()
{
return "TopicBC" ;
}
public override bool ProcessMessageArrived()
{
...
}
}
...
unObjectX.SubscribeTopic( B.GetTopicDomain());
unObjectY.SubscribeTopic( C.GetTopicDomain());
...
void MsgArrived( A a )
{
A.ProcessMessageArrived();
}
</CODE>
--
Paul Bacelar
MVP VC++

"# Cyrille37 #" wrote in message
news:
Christophe Gricourt wrote:

Les membres statiques sont un concept qui s'appliquent aux classes.
La surcharge est un concept qui s'applique aux instances.
Je ne vois pas bien l'utilité de vouloir combiner les deux...




Je reviens sur le sujet, pour montrer l'utilité que je trouve à
l'application de 'virtual' sur des méthodes de classe
(static).

<code>
class A
{
public static virtual string GetTopicDomain()
{
return "unknow" ;
}
public static string Topic
{
// C'est ici que serait appelé la bonne méthode correspondant à la
classe grâce à 'virtual'
return GetTopicDomain();
}
}
class B : A
{
public static virtual string GetTopicDomain()
{
return "TopicB" ;
}
}
class C : B
{
public static virtual string GetTopicDomain()
{
return "TopicBC" ;
}
}
...
unObjectX.SubscribeTopic( B.Topic );
unObjectY.SubscribeTopic( C.Topic );
...
void MsgArrived( A a )
{
if( a is B ){
...
}else if( a is C ){
...
}
}
</code>

Avec les limitations actuelles je suis obligé de faire de la façon
suivante :
<code>
unObjectX.SubscribeTopic( (new B()).Topic );
</code>

Et donc de réserver le constructeur sans paramètre pour cette forme
d'usage.

Mon argumentation est-elle plus clair ?

cyrille.