web-dev-qa-db-fra.com

Pouvez-vous implémenter une programmation "orientée objet" sans le mot-clé class?

Disons que nous voulons fournir une abstraction d'un "compte" dans une banque. Voici une approche, en utilisant un objet function en Python:

def account():
    """Return a dispatch dictionary representing a bank account.

    >>> a = account()
    >>> a['deposit'](100)
    100
    >>> a['withdraw'](90)
    10
    >>> a['withdraw'](90)
    'Insufficient funds'
    >>> a['balance']
    10
    """
    def withdraw(amount):
        if amount > dispatch['balance']:
            return 'Insufficient funds'
        dispatch['balance'] -= amount
        return dispatch['balance']
    def deposit(amount):
        dispatch['balance'] += amount
        return dispatch['balance']
    dispatch = {'balance': 0,
                'withdraw': withdraw,
                'deposit': deposit}
    return dispatch

Voici une autre approche utilisant l'abstraction de type (c'est-à-dire le mot clé class en Python):

class Account(object):
    """A bank account has a balance and an account holder.

    >>> a = Account('John')
    >>> a.deposit(100)
    100
    >>> a.withdraw(90)
    10
    >>> a.withdraw(90)
    'Insufficient funds'
    >>> a.balance
    10
    """



    def __init__(self, account_holder):
        self.balance = 0
        self.holder = account_holder

    def deposit(self, amount):
        """Add amount to balance."""
        self.balance = self.balance + amount
        return self.balance

    def withdraw(self, amount):
        """Subtract amount from balance if funds are available."""
        if amount > self.balance:
            return 'Insufficient funds'
        self.balance = self.balance - amount
        return self.balance

Mon professeur a commencé le sujet "Programmation orientée objet" en introduisant le mot-clé class et en nous montrant ces puces:

Programmation orientée objet

Une méthode pour organiser des programmes modulaires:

  • Barrières d'abstraction
  • Passage de message
  • Regrouper les informations et les comportements associés

Pensez-vous que la première approche suffirait pour satisfaire la définition ci-dessus? Si oui, pourquoi avons-nous besoin du mot clé class pour faire une programmation orientée objet?

29
overexchange

Toutes nos félicitations! Vous avez redécouvert le fait bien connu que l'orientation d'objet peut se faire sans prise en charge spécifique du langage de programmation. C'est fondamentalement la même manière dont les objets sont introduits dans Scheme dans ce manuel classique . Notez que Scheme n'a pas de mot clé class ou une sorte d'équivalent, et les objets peuvent être créés sans avoir même des classes.

Cependant, le paradigme orienté objet a connu un tel succès que de nombreux langages - et Python ne fait pas exception - fournissent un support intégré pour cela. Ceci est simplement pour faciliter l'utilisation du paradigme par les développeurs. et pour fournir une forme standard d'orientation d'objet pour ce langage. C'est essentiellement la même raison pour laquelle de nombreux langages fournissent une boucle for, bien qu'elle puisse être émulée en utilisant une boucle while avec un seul ou deux lignes de code supplémentaires - simplement facilité d'utilisation .

66
Doc Brown

Je conviens que la première définition satisfait les trois points soulevés par votre professeur. Je ne pense pas que nous ayons besoin du mot-clé class pour quoi que ce soit. Sous les couvertures, qu'est-ce qu'un objet, sinon une structure de données avec différents types de données et fonctions pour travailler avec les données? Bien sûr, les fonctions sont également des données.

J'irais même plus loin et dirais que faire de la programmation orientée objet ne dépend pas tant des mots-clés que votre langage fournit, vous pouvez faire de la programmation orientée objet en C si vous le souhaitez! En fait, le noyau Linux utilise de telles techniques.

Ce que vous pouvez déduire du mot-clé class ici, c'est que le langage prend en charge ce type de construction hors de la boîte, et vous n'avez pas besoin de parcourir tous les cerceaux pour réimplémenter vous-même la fonctionnalité (ce qui est une tâche assez amusante dans lui-même!). Sans parler de tout le sucre syntaxique que vous pourriez également obtenir.

13
Zavior

Bien sûr vous pouvez!

Le langage d'auto-programmation est un langage orienté objet basé sur un prototype dynamique dans lequel tout est un objet et il n'y a aucun sens des classes ou quoi que ce soit. Il est axé sur l'idée des objets prototypiques et l'idée de les cloner au lieu d'avoir des classes comme modèles de création d'objets.

Vous devriez vérifier http://www.selflanguage.org/ pour plus d'informations. Je pense que c'est très intéressant et si vous aimez OOP c'est une bonne idée de vérifier quelque chose qui n'est pas si courant.

9
DraQ

Pas toujours: cela dépend de la langue. Vous avez démontré la capacité de le faire dans Python mais (si votre question est destinée à être indépendante de la langue malgré la balise Python) toutes les langues ne peuvent pas le faire) Java, par exemple, ne peut généralement pas. En ignorant la classe qui contient main, il n'y a aucun moyen de définir des méthodes/champs arbitraires sur un objet défini dans main sans le mot-clé class. Bien que les classes anonymes existent, elles nécessitent une interface et ils ne peuvent pas avoir de membres publics à l'exception de ceux définis dans l'interface. Bien qu'il soit possible de définir des interfaces personnalisées puis de créer des classes anonymes pour eux, c'est effectivement la même chose (mais moins pratique) que d'utiliser simplement une classe.

Doc Brown a une excellente réponse mais le point que j'essaie de faire est que je suis sûr qu'il y a au moins une langue qui ne permettra pas du tout votre solution.

0
SkySpiral7

La définition de votre professeur manque complètement le point le plus important de la programmation orientée objet, la seule chose qui la rend utile et unique. "Message passant" est un tas de bêtises imaginé par les gens de Smalltalk, et c'est un échec partout où il a été essayé. La véritable puissance de OOP est quelque chose connu sous le nom de substitution Liskov, et bien que le concept soit assez simple à décrire et à comprendre, l'implémentation sous-jacente est suffisamment complexe pour qu'elle soit essentiellement impossible faire le bien sans prise en charge au niveau de la langue.

L'idée de la substitution Liskov est que partout où votre code attend une variable d'un certain type, il devrait pouvoir accepter n'importe quel type dérivé de ce type et fonctionner correctement sans avoir à connaître les détails du type dérivé.

Par exemple, les frameworks GUI utilisent la substitution Liskov partout. Ils ont tendance à avoir une classe de base Control qui peut représenter "n'importe quel contrôle", qui définit une interface qui connaît les actions de base comme le dessin, le redimensionnement et la réponse aux entrées de l'utilisateur. Si vous cliquez sur un contrôle, le framework d'interface utilisateur appellera une méthode Click sur le contrôle sans avoir à se soucier de quel type de contrôle il s'agit, puis laissera le contrôle gérer le clic de la manière appropriée pour la sienne. classe. Un contrôle Button doit faire quelque chose de complètement différent lorsque vous cliquez dessus qu'un contrôle TextBox, pour ne donner qu'un exemple.

Donc oui, vous pouvez créer quelque chose de similaire aux objets en utilisant l'astuce des fonctions imbriquées décrite ci-dessus, mais comme vous ne pouvez pas obtenir l'héritage et la substitution Liskov de cette façon, c'est un substitut extrêmement limité pour la vraie POO.

0
Mason Wheeler