OVH Cloud OVH Cloud

Méthode static virtuelle

20 réponses
Avatar
ShadowFil
Bonjour,

Est-il possible de rendre une méthode statique "virtuelle" pour qu'elle
puisse être surchargée dans les classes dérivée ?

Merci pour votre aide.

10 réponses

1 2
Avatar
Ambassadeur Kosh
"ShadowFil" a écrit dans le message de
news:
"Arnaud Debaene" a écrit :
Avec les méthodes virtuelles, ce qui définit la fonction réellement
appelée,
c'est le type concret (type le plus dérivé) de *l'instance* (càd l'objet,
créé avec new) sur laquelle la méthode appelée. Avec une foncrtion
statique,
il n'y a pas d'instance sur laquelle la fonction est appelée, donc la
noion
de fonction virtuelle n'a plus de sens.



Oui. Donc, tu peux appeler une méthode statique du type d'une classe
dérivée, qui aurait pu (si c'était possible) surcharger la méthode
statique
du type de sa classe de base. En fonction du type utiliser, on aurait pu
accéder à la méthode statique du type le plus dérivé.




class A
{
static virtual void f()
{
...0...
}

static void g()
{
f() ;
}
}

class A1 : A
{
static virtual void f()
{
...1...
}
}

class A2 :
{
static virtual void f()
{
...2...
}
}

maintenant, du point de vue de la coherence, regarde ce que fait A1.f(),
A2.f() et A.f(), vue par un tiers exterieur, vu de l'interieur par A1,A2 et
A, appellée explicitement ou implicitement.
Avatar
ShadowFil
A1.g() appelle A.f(), c'est normal.
Mais si on converti A2 ou A1 en A, et si on pouvait rendre une méthode
statique virtuelle, on porrait faire ça :
A = A;
A.f(); // appelle A.f()

A = A1;
A.f(); // appelle A1.f()

A = A2;
A.f(); // appelle A2.f()
Avatar
Ambassadeur Kosh
> A1.g() appelle A.f(), c'est normal.
Mais si on converti A2 ou A1 en A, et si on pouvait rendre une méthode
statique virtuelle, on porrait faire ça :
A = A;
A.f(); // appelle A.f()
A = A1;
A.f(); // appelle A1.f()
A = A2;
A.f(); // appelle A2.f()



j'essaie d'attirer ton attention sur la résolution. pour moi, il va y'avoir
des ambiguités. en admettant qu'on les leve sous certaines hypoteses, le
modele avec les singletons offre les memes avantages en matiere de detection
à la compilation que ce que tu proposes. et il a l'avantage de pouvoir
facilement permettre l'instanciation multiple si besoin. pourquoi alors
utiliser un formalisme pénalisant ? qu'est il sensé apporter ?
Avatar
adebaene
ShadowFil a écrit :

"Arnaud Debaene" a écrit :
> Avec les méthodes virtuelles, ce qui définit la fonction réelleme nt appelée,
> c'est le type concret (type le plus dérivé) de *l'instance* (càd l'objet,
> créé avec new) sur laquelle la méthode appelée. Avec une foncrt ion statique,
> il n'y a pas d'instance sur laquelle la fonction est appelée, donc la noion
> de fonction virtuelle n'a plus de sens.

Oui. Donc, tu peux appeler une méthode statique du type d'une classe
dérivée, qui aurait pu (si c'était possible) surcharger la méthod e statique
du type de sa classe de base. En fonction du type utiliser


En fonction tu type utiliser *par qui*, du type *de quoi*, c'est çà
la question!!!

, on aurait pu
accéder à la méthode statique du type le plus dérivé.



Qu'est ce qui ne te va pas là dedans ? :
class Base
{
static public void f()
{
}
}

class Derivee : Base
{
new static public void f() //utilise new pour éviter un warning
CS0108
{
}
}

static void main()
{
Base.f();
Derivee.f();
}

Notes qu'il n'y a pas création d'un seul objet, ni Base ni Derivee
(tout le principe d'une fonction statique, c'est qu'on peut l'appeler
sans instance!)

Arnaud
MVP - VC
Avatar
ShadowFil
L'utilisation du new permet de s'en sortir dans certaines situation. Ok.
J'essai juste de comprendre pourquoi il n'a pas été prévu dans le language
C#, la possibilité de créer des méthodes statiques virtuelles. Et j'avoue
que, malgré toutes vos réponses, je n'ai pas encore compris pourquoi.
Avatar
Ambassadeur Kosh
> L'utilisation du new permet de s'en sortir dans certaines situation. Ok.
J'essai juste de comprendre pourquoi il n'a pas été prévu dans le language
C#, la possibilité de créer des méthodes statiques virtuelles. Et j'avoue
que, malgré toutes vos réponses, je n'ai pas encore compris pourquoi.



pour la meme raison qui a poussé à choisir de ne pas pouvoir écrire des
fonctions et des variables globales façon C. on pousse à utiliser des
objets
Avatar
Arnaud Debaene
ShadowFil wrote:
L'utilisation du new permet de s'en sortir dans certaines situation.


Dans *toutes* les situations, pour autant que je puisse voire...

Ok. J'essai juste de comprendre pourquoi il n'a pas été prévu dans le
language C#, la possibilité de créer des méthodes statiques
virtuelles. Et j'avoue que, malgré toutes vos réponses, je n'ai pas
encore compris pourquoi.



Parce que, dans le code suivant :
class Base
{
public virtual void f()
{}
}
class Derivee : Base
{
public override void f()
{}
}
Base MonObj = //quelquechose;
MonObj.f();

Ce qui détermine la fonction appelée (Base.f() ou Derivee.f()), c'est le
type réel de l'objet référencé par MonObj (type Base ou Derivee). Comme je
peux appeler une fonction statique *sans* créer d'instance, il n'y a alors
aucun moyen de déterminer quelle méhode doit être appelée.
Ce n'est pas simplement un "choix" de simplification du langage pour nous
"encourager" à utiliser des objets, c'est une donnée fondamentale du modèle
objet et des méthodes statiques (c'est la même chose dans *tous* les
langages avec un modèle de polymorphisme à l'exécution : C++, Java, C#,
etc....).

C'est plus clair comme çà?

Sinon, si tu veux vraiement émuler ce fonctionnement, rien ne t'empêche
d'écrire :

class Base
{
public virtual void f()
{
Base.f_static();
}

public static void f_static()
{//....}
}

class Derivee : Base
{
public override void f()
{
Derivee.f_static();
}

public new static void f_static()
{//....}
}

De cette manière, tu peux appeler f de manière polymorphe sur une instance
de Base ou de Derivee, et la fonction réelle qui fait tout le boulot est
toujours statique, et appelable directement (sans instance d'objet).

Arnaud
MVP - VC
Avatar
Ambassadeur Kosh
> Ce qui détermine la fonction appelée (Base.f() ou Derivee.f()), c'est le
type réel de l'objet référencé par MonObj (type Base ou Derivee). Comme je
peux appeler une fonction statique *sans* créer d'instance, il n'y a alors
aucun moyen de déterminer quelle méhode doit être appelée.
Ce n'est pas simplement un "choix" de simplification du langage pour nous
"encourager" à utiliser des objets, c'est une donnée fondamentale du
modèle objet et des méthodes statiques (c'est la même chose dans *tous*
les langages avec un modèle de polymorphisme à l'exécution : C++, Java,
C#, etc....).



si j'ai bien compris ce qu'il veut, tout comme le this implicite, lors q'un
appel à un membre statique, on aurait un "current" implicite qui se balade
le long de la chaine des appels.
sur Dummy.f, il vaut Dummy, et quand il est appellé implicitement par le
truchement d'une fonction non statique, il vaudrait this.GetType()...

meme si ça tient la route, c'est l'interet qui m'echappe...
Avatar
Faust
pas exactement: tant que ton code ne connait pas "l'existence" de
Derivee il n'exécutera jamais son f_static

si tu veux appeler f_static de Derivee, il faut impérativement écrire:
Derivee.f_static() (ou eventuelement une dérivée de Derivee qui ne
recode pas f_static)

maintenant, ecrire ce que veux faire shadowfill, simplement l'appel
(sans tenir compte du "override") ça ne peux pas se faire puisque C# ne
connait pas de déclaration "class of" qui correspondrait à

class BaseClass = class of Base;
qui permettrait d'écrire:

BaseClass uneclassedetypeBase = Derivee;
uneclassedetypeBase.f_static();


pour ceux qui cherche l'intérêt d'une telle fonctionnalité, ça peut
servir dans un Factory... sans cette façon faire, il faut créer une
instance du Factory pour remplir la classe associée du factory... c'est
un peu ridicule quand la durée de vie du Factory est rarement supérieur
à la durée du remplissage de l'instance de l'objet = construction
inutile

/Après mure réflexion, _Arnaud Debaene_ a écrit/ :
De cette manière, tu peux appeler f de manière polymorphe sur une instance de
Base ou de Derivee, et la fonction réelle qui fait tout le boulot est
toujours statique, et appelable directement (sans instance d'objet).




--
*/Teträm/*
http://www.tetram.org

"Le monde est rond comme le cul d'une pucelle. On ne peut pas s'y
perdre"
Chevalier Or-Azur
Avatar
ShadowFil
Ok. Ca y est. J'ai compris !
C'est tellement évident que je me demande pourquoi je n'ai pas compris plus
tôt !

Effectivement, l'intérêt du polymorphisme est de pouvoir utiliser une
instance d'un d'un type dérivé dans un type de base. Mais si on apelle une
méthode statique à partir d'un type de base, ce sera toujours la méthode
statique du type de base qui sera utilisée. Le type réel de l'instance ne
sera pas utilisé.

Merci à tous pour avoir insister et tenter de me faire comprendre.
1 2