web-dev-qa-db-fra.com

Quelle est la différence entre une classe abstraite et une classe statique?

Ni l'un ni l'autre n'est instanciable. Quelles sont les différences et dans quelles situations pourriez-vous utiliser l'un ou l'autre?

34
stannius

static indique que la classe ne peut avoir que des membres statiques et que vous ne pouvez pas en créer d'instance. Ceci est utilisé pour la fonctionnalité sans état (par exemple un type qui définit simplement les méthodes d'extension ou les méthodes utilitaires). Vous pouvez également déclarer un membre static sur une classe non statique. Cela vous permet d'attacher des fonctionnalités à un type sans avoir à l'instancier.

Voici plus de détails sur l'utilisation des membres et des classes statiques .

abstracts définissent la structure et les fonctionnalités de base partagées par tous les types de dérivés, mais ne peuvent pas être utilisées par eux-mêmes. Considérez-les comme, je suppose, un imprimé bleu et un contrat. Il s'agit d'un concept central pour la POO.

Voici plus de détails sur l'utilisation des résumés .

31
moribvndvs

Voici un bref résumé:

  • Une classe statique ne peut contenir que des membres static (c'est juste un conteneur pour des méthodes qui n'appartiennent logiquement à une instance d'aucune classe standard)
  • Une classe abstraite peut contenir tous les types habituels de membres (statiques, abstraits et aussi des instances)

La principale différence est que vous pouvez hériter d'une classe abstract, mais vous ne pouvez pas hériter d'une classe static. Techniquement parlant, le runtime .NET n'a aucune notion de classes static, donc le compilateur C # les compile comme des classes qui sont à la fois abstract et sealed (ce qui signifie que vous ne peut en hériter).

Ainsi, les classes static sont des classes abstract qui sont également sealed (bien que ce ne soit pas la manière habituelle de regarder le problème si vous êtes programmeur C #) et ne contiennent que static membres (qui est appliqué par le compilateur C #).

24
Tomas Petricek

Une classe abstraite est destinée à être utilisée comme base d'une hiérarchie d'héritage de classe. Une classe statique ne peut pas être la base d'une hiérarchie d'héritage de classe.

Une classe statique est destinée aux fonctionnalités à état singleton ou sans état. Une classe abstraite n'est pas adaptée à la fonctionnalité singleton, car, même si elle peut contenir des méthodes et des champs statiques comme le fait une classe statique, elle ne peut pas interdire l'héritage, de sorte que l'utilisation du singleton peut être vaincue par des sous-classes. Ou, à tout le moins, ce serait déroutant pour d'autres programmeurs, car sa définition communiquerait une intention différente de son utilisation réelle.

La similitude superficielle entre les classes abstraites et statiques réside uniquement dans le fait qu'aucune des deux ne peut être instanciée. Au-delà, ce sont des animaux complètement différents avec des cas d'utilisation complètement différents.

8

Le CLR n'a aucune notion de classes statiques, il est spécifique au C #. Le compilateur l'implémente par une utilisation astucieuse des attributs CLR pour une classe: il le déclare abstrait et scellé. Cela empêche toute langue d'instancier une telle classe. Voici à quoi cela ressemble lorsque vous exécutez Ildasm:

.class public abstract auto ansi sealed beforefieldinit ConsoleApplication1.Test
       extends [mscorlib]System.Object
{
}

Le rendre scellé est vraiment l'intérêt d'une classe statique, il est utilisé comme conteneur pour les méthodes et les champs statiques. Ce qui les fait agir comme des variables globales et des fonctions comme vous en avez dans des langages comme C ou Pascal.

Une classe abstraite est tout le contraire, elle est conçue pour être dérivée. Une classe abstraite qui a tous de ses membres abstraits agit comme une interface. C # a un mot-clé pour cela, faisant de la classe statique et de l'interface les opposés exacts.

7
Hans Passant

Les classes abstraites sont instanciées indirectement via des classes dérivées. Ils fournissent un comportement et un état d'instance communs, mais signalent que davantage est requis et doit être fourni par des classes concrètes dérivées. Par exemple, Transform peut être une classe abstraite: elle déclare une méthode Apply(Shape) commune, mais aucune implémentation de cette méthode. Les classes dérivées concrètes comme Rotation ou Translation implémenteront cette méthode, et ces classes can seront instanciées.

Les classes statiques ne peuvent pas être instanciées et tout état se situe au niveau de la classe plutôt qu'au niveau de l'instance. Ils sont généralement utilisés pour définir des méthodes utilitaires dans lesquelles aucun état n'est associé aux méthodes. Transform ne peut pas être une classe statique, parce que les classes dérivées concrètes ont besoin d'un état par instance (par exemple Rotation a besoin d'un par instance Angle, car différents Rotation les transformations peuvent avoir différents angles).

2
itowlson

Les classes abstraites sont destinées à être utilisées comme classes de base; ils ne peuvent pas avoir d'instances directes. Au lieu de cela, vous devez dériver des sous-classes, qui fournissent ce qui a été (généralement intentionnellement) laissé de côté dans la classe de base abstraite.

Exemple: considérez que vous avez une application complexe, sur laquelle les utilisateurs peuvent se connecter. Divers mécanismes d'authentification devraient être utilisables, par exemple, LDAP, NTLM, vous l'appelez. Une façon de modéliser un "utilisateur" ou un "principal" dans un tel contexte serait de collecter ce qui est commun à tous ces mécanismes dans une classe de base abstraite et de laisser des "lacunes" (méthodes abstraites) où les implémentations réelles entrent en jeu. jouer:

abstract class Authenticator {

   protected Dictionary<string,User> userCache;

   ...

   public User LoadUser(string name) {
        User user;
        if( userCache.TryGet(name, out user) ) return user;
        else {
            user = LoadFromStore(name);
            userCache.Add(name, user);
            return user;
        }
   }

   protected abstract User LoadFromStore(string name);
}

Ici, la mise en cache des utilisateurs est une préoccupation courante, modélisée dans le cas de base, tandis que la récupération réelle est laissée à une sous-classe à fournir.

Les classes statiques sont un tout autre sujet. Ils sont essentiellement un endroit pour garder vos fonctions utilitaires:

static class StrUtil {

    public static string TrimWhitespace(string str) {
        ...
    }
}

Considérez-les comme une sorte d'espace de noms spécial, qui ne peut contenir que des membres statiques. Fondamentalement, un endroit pour mettre des fonctions.

2
Dirk

Classe abstraite (classe de base): Permet aux autres classes d'hériter de cette classe ( une classe acquiert les propriétés (méthodes et champs) d'une autre), mais interdit de instancier c'est-à-dire que nous ne pouvons pas avoir d'objets de cette classe.http://csharp.net-tutorials.com/classes/classes-abstraites

Classe statique: Cette classe ne peut pas être instanciée. Aussi la classe ne peut pas être héritée. Pour accéder aux méthodes de cette classe, vous pouvez directement utiliser classname.method. https://social.technet.Microsoft.com/wiki/contents/articles/21028.difference-between-static-class-sealed-class-and-abstract-class-in-c.aspx

1
Rabin Naga

Le but principal de la classe abstraite est de définir une ou plusieurs méthodes abstraites. Toute classe qui étend la classe Abstract implémentera la méthode abstraite, sinon elle devra également être déclarée "Abstract".

Mais, il est également possible de déclarer une classe comme "abstraite" sans implémenter aucune méthode abstraite. Voir l'exemple ci-dessous.

classe abstraite publique AbstractTest {

public void abcd(){}

public static void main(String[] args) {

      System.out.print("hi...");

}

}

Seule la classe interne peut être déclarée "statique", voir le code ci-dessous. La classe supérieure/encapsulante ne peut pas être déclarée comme "statique". Il est accessible à l'aide de la variable de classe supérieure/encapsulante, nom de classe statique-interne, c'est-à-dire comme tout appel de méthode statique utilisant le nom de classe.

classe public class StaticTest {

public static void main(String ag[]){
    System.out.println("hello...1");
    StaticTest.StaticTest2.meth2();
}

public static class StaticTest2 {
    public static void meth2(){
        System.out.print("hello...2");
    }
}

}

1