Introduction

Les attributs et méthodes définis dans une classe sont généralement à portée objet : ils décrivent les caractéristiques et le comportement des objets de la classe

Le concept de portée classe permet de définir des attributs communs à l’ensemble des objets (constantes globales, compteurs d’instances…) ou des méthodes utilitaires qui ne dépendant pas d’une d’une instance (objet) spécifique.

Java

Syntaxe

En java, c’est le qualificateur static qui permet d’indiquer qu’un attribut ou une méthode est à portée classe.

public class NomClasse {
    protected static Type _nomAttrPortéeClasse;
    protected Type _nomAttrPortéeObjet;public static … nomMéthodePortéeClasse() {}
    
    public … nomMéthodePortéeObjet() {}
}

Exemple

Dans cet exemple, la classe dispose d’un attribut nextId servant à initialiser l’attribut id des instances.

public class Transport {
    protected static int nextId = 1;        //static → portée classe
    protected int id;                   //portée objet
    protected String type;

    public Transport(String type) {
        this.id = Transport.nextId;
        Transport.nextId++;
        this.type = type;
    }

    public int getId() {                //portée objet
        return id;
    }

    public String getType() {
        return type;
    }

    public String setType(String type) {
        this.type = type;
        return this.type;
    }

    public static int getNextId() {     //portée classe
        return nextId;
    }
}


public class App {
    public static void main(String[] args) {
        java.util.List<Transport> transports = new java.util.ArrayList<>();
        transports.add(new Transport("Avion"));
        transports.add(new Transport("Navire"));
        for (Transport t : transports) {
            System.out.println(t.getId() + " " + t.getType());  // objet.méthode()
        }
        System.out.println(Transport.getNextId());              // classe.méthode()
    }
}

Python

Remarques préliminaire

La syntaxe du langage doit permettre de distinguer la portée classe de la portée objets. Le choix retenu est d’utiliser ClassVar pour distinguer les attributs à portée classe. Pour les méthodes, l’absence de self indique une méthode à portée classe (même s’il existe un décorateur@classmethod).

L’hésitation concernant la syntaxe retenue pour le langage Python vient de son manque de spécification ; par exemple, alors que la première version du langage datede 1991, la version 3 de 2008, ce n’est qu’en 2016 que ClassVar a été introduit (PEP-526), avec, en conséquence, des ressources documentaires parfois contradictoires.

Syntaxe

from typing import ClassVar

class NomClasse
    _nomAttrPortéeClasse: ClassVar[type]
    _nomAttrPortéeObjet: typedef nomMéthodePortéeClasse(): #pas de "self"def nomMéthodePortéeObjet(self,):

Exemple

Dans cet exemple, la classe dispose d’un attribut _nextId servant à initialiser l’attribut _id des instances.

from typing import ClassVar

class Transport:
    _nextId: ClassVar[int] = 1  #ClassVar → portée classe
    _id: str                    #portée objet
    _type: str

    def __init__(self, type: str):
        self._id = Transport._nextId
        Transport._nextId += 1
        self._type = type

    def getId(self) -> str:     #portée objet
        return self._id

    def getType(self) -> str:
        return self._type

    def setType(self, type: str) -> str:
        self._type = type
        return self._type
    
    def getNextId() -> int:     #pas de self → portée classe
        return Transport._nextId

if __name__ == "__main__":
    transports = []
    transports.append(Transport(type = 'Avion'))
    transports.append(Transport(type = 'Navire'))
    for t in transports:
        print(t.getId(), t.getType())    #objet.méthode()
    print(Transport.getNextId())         #classe.méthode()