Question

J'ai travaillé avec fournisseurs pas mal ces derniers temps, et je suis tombé sur une situation intéressante dans laquelle je voulais avoir une classe abstraite dotée d'une méthode statique abstraite.J'ai lu quelques articles sur le sujet, et cela avait du sens, mais existe-t-il une explication claire et intéressante ?

Était-ce utile?

La solution

Les méthodes statiques ne sont pas instancié en tant que tels, ils sont simplement disponibles sans référence d'objet.

Un appel à une méthode statique se fait via le nom de la classe, et non via une référence d'objet, et le code IL (Intermediate Language) pour l'appeler appellera la méthode abstraite via le nom de la classe qui l'a définie, pas nécessairement le nom de la classe que vous avez utilisée.

Laissez-moi vous montrer un exemple.

Avec le code suivant :

public class A
{
    public static void Test()
    {
    }
}

public class B : A
{
}

Si vous appelez B.Test, comme ceci :

class Program
{
    static void Main(string[] args)
    {
        B.Test();
    }
}

Ensuite, le code réel à l’intérieur de la méthode Main est le suivant :

.entrypoint
.maxstack 8
L0000: nop 
L0001: call void ConsoleApplication1.A::Test()
L0006: nop 
L0007: ret 

Comme vous pouvez le voir, l'appel est fait à A.Test, car c'est la classe A qui l'a défini, et non à B.Test, même si vous pouvez écrire le code de cette façon.

Si tu avais types de classe, comme dans Delphi, où vous pouvez créer une variable faisant référence à un type et non à un objet, vous auriez davantage besoin de méthodes statiques virtuelles et donc abstraites (et aussi de constructeurs), mais elles ne sont pas disponibles et donc les appels statiques ne sont pas -virtuel en .NET.

Je me rends compte que les concepteurs IL pourraient permettre au code d'être compilé pour appeler B.Test et résoudre l'appel au moment de l'exécution, mais il ne serait toujours pas virtuel, car vous devrez toujours y écrire une sorte de nom de classe.

Les méthodes virtuelles, et donc abstraites, ne sont utiles que lorsque vous utilisez une variable qui, au moment de l'exécution, peut contenir de nombreux types d'objets différents, et que vous souhaitez donc appeler la bonne méthode pour l'objet actuel que vous avez dans la variable.Avec les méthodes statiques, vous devez de toute façon passer par un nom de classe, donc la méthode exacte à appeler est connue au moment de la compilation car elle ne peut pas et ne changera pas.

Ainsi, les méthodes statiques virtuelles/abstraites ne sont pas disponibles dans .NET.

Autres conseils

Les méthodes statiques ne peuvent pas être héritées ou remplacées, et c’est pourquoi elles ne peuvent pas être abstraites.Puisque les méthodes statiques sont définies sur le type, et non sur l’instance, d’une classe, elles doivent être appelées explicitement sur ce type.Ainsi, lorsque vous souhaitez appeler une méthode sur une classe enfant, vous devez utiliser son nom pour l'appeler.Cela rend l’héritage sans importance.

Supposons que vous puissiez, pendant un instant, hériter de méthodes statiques.Imaginez ce scénario :

public static class Base
{
    public static virtual int GetNumber() { return 5; }
}

public static class Child1 : Base
{
    public static override int GetNumber() { return 1; }
}

public static class Child2 : Base
{
    public static override int GetNumber() { return 2; }
}

Si vous appelez Base.GetNumber(), quelle méthode serait appelée ?Quelle valeur renvoyée ?Il est assez facile de voir que sans créer d’instances d’objets, l’héritage est plutôt difficile.Les méthodes abstraites sans héritage ne sont que des méthodes qui n'ont pas de corps et ne peuvent donc pas être appelées.

Un autre répondant (McDowell) a déclaré que le polymorphisme ne fonctionne que pour les instances d'objets.Cela devrait être nuancé ;il existe des langages qui traitent les classes comme des instances d'un type "Classe" ou "Métaclasse".Ces langages prennent en charge le polymorphisme pour les méthodes d'instance et de classe (statiques).

C#, comme Java et C++ avant lui, n’est pas un tel langage ;le static Le mot clé est utilisé explicitement pour indiquer que la méthode est liée statiquement plutôt que dynamique/virtuelle.

Pour compléter les explications précédentes, les appels de méthode statique sont liés à une méthode spécifique à moment de la compilation, ce qui exclut plutôt un comportement polymorphe.

Voici une situation dans laquelle il est absolument nécessaire d'hériter des champs et des méthodes statiques :

abstract class Animal
{
  protected static string[] legs;

  static Animal() {
    legs=new string[0];
  }

  public static void printLegs()
  {
    foreach (string leg in legs) {
      print(leg);
    }
  }
}


class Human: Animal
{
  static Human() {
    legs=new string[] {"left leg", "right leg"};
  }
}


class Dog: Animal
{
  static Dog() {
    legs=new string[] {"left foreleg", "right foreleg", "left hindleg", "right hindleg"};
  }
}


public static void main() {
  Dog.printLegs();
  Human.printLegs();
}


//what is the output?
//does each subclass get its own copy of the array "legs"?

En fait, nous remplaçons les méthodes statiques (sous Delphi), c'est un peu moche, mais cela fonctionne très bien pour nos besoins.

Nous l'utilisons pour que les classes puissent avoir une liste de leurs objets disponibles sans l'instance de classe, par exemple, nous avons une méthode qui ressemble à ceci :

class function AvailableObjects: string; override;
begin
  Result := 'Object1, Object2';
end; 

C'est moche mais nécessaire, de cette façon nous pouvons instancier exactement ce qui est nécessaire, au lieu d'avoir toutes les classes instanciées juste pour rechercher les objets disponibles.

Il s'agissait d'un exemple simple, mais l'application elle-même est une application client-serveur qui possède toutes les classes disponibles sur un seul serveur et plusieurs clients différents qui n'auront peut-être pas besoin de tout ce que le serveur possède et n'auront jamais besoin d'une instance d'objet.

C'est donc beaucoup plus facile à maintenir que d'avoir une application serveur différente pour chaque client.

J'espère que l'exemple était clair.

Les méthodes abstraites sont implicitement virtuelles.Les méthodes abstraites nécessitent une instance, mais les méthodes statiques n'en ont pas.Ainsi, vous pouvez avoir une méthode statique dans une classe abstraite, elle ne peut tout simplement pas être statique abstraite (ou statique abstraite).

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top