7
votes

Y a-t-il une langue avec des niveaux d'accès basés sur des objets?

Une idée fausse commune sur le niveau d'accès en Java, C #, C ++ et PHP est qu'elle s'applique aux objets plutôt qu'aux classes. C'est-à-dire que (disons) un objet de classe X ne peut pas voir les membres privés d'un autre X. En fait, bien sûr, le niveau d'accès est basé sur la classe et un objet X peut également faire référence aux membres privés d'un autre.

existe-t-il une langue avec des niveaux d'accès basés sur des objets? Sont-ils au lieu de, ou en plus de l'accès basé sur la classe? Quel impact cette fonctionnalité a-t-elle sur la conception du programme?


1 commentaires

J'ai pris la liberté d'ajouter PHP à la liste des langues mettant en œuvre le niveau d'accès basé sur la classe.


3 Réponses :


6
votes

Ruby a un niveau d'accès basé sur des objets. Voici une citation de la programmation Ruby:

la différence entre "protégé" et "privé" est assez subtile, et est différent dans Ruby que dans la plupart des des langues communes OO. Si une méthode est protégé, on peut appeler par n'importe quel cas de la classe définition ou de son sous-classes. Si une méthode est privée, elle peut être appelé seulement dans le contexte de l'objet appelant --- il n'est jamais possible d'accéder à un autre objet méthodes privées directement, même si la objet est de la même classe que le appelant.

Et voici la source: http: // whtheluckyst. NET / RUBY / PICKAXE / HTML / TUT_CLASSES.HTML # S4

Exemple de différence entre Java et Ruby

Java < Pré> xxx

rubis xxx


6 commentaires

"Private" dans ce sens semble plus modulaire. J'espère que d'autres langues récupèrent des fonctionnalités similaires.


1. C'est la même chose en Java. 2. Je parie que cela "ne signifie jamais" "" jamais, à moins que vous n'utilisiez une API interne pouvant contourner cela ".


@Aaron, j'ai peut-être compris le problème, mais ce n'est pas la même chose en Java. Je posterai un exemple de comparaison.


Ionut, pouvez-vous dire quoi que ce soit sur la manière dont la conception de programme change de rubis à cause de cette propriété? Je suis heureux de savoir qu'il y a une langue traditionnelle avec la fonctionnalité, mais je suis le plus curieux de l'impact de ce choix de langue sur la façon dont nous écrivons des logiciels.


@Carl, honnêtement, je n'ai pas trop d'expérience dans Ruby, je ne peux donc pas vraiment donner une bonne idée. La seule chose à laquelle je puisse penser, c'est que cette fonctionnalité permet de contrôler beaucoup plus de contrôle grainé de la source des effets secondaires. Une structure interne d'objet n'est pas à la merci d'un autre objet, même s'ils sont des cas de même classe, ce qui est une bonne chose. Je ne connais pas d'idiomes ou de motifs supportés par cette fonctionnalité.


C'est la meilleure réponse donnée, alors je l'accepte, même si je suis toujours vraiment curieux de l'impact sur la conception du programme et je souhaite que quelqu'un ait eu une réponse à cette partie de la question.



-1
votes

Vous pouvez implémenter cela en C # en ayant une méthode capable de marcher sur la pile et de vérifier quel objet l'appelant est et jetant une exception si ce n'est pas la classe actuelle. Je ne sais pas pourquoi tu voudrais, mais je pensais que je le jeter là-bas.


2 commentaires

Clarification: Cette chose devrait être faite au moment de la compilation. Il est inutile au moment de l'exécution.


Non, c'est une perversion. Encourageant des frais généraux terribles d'exécution, et en utilisant une méthode absolument incorrecte.



0
votes

La principale raison pour laquelle aucune langue n'a de soutien à cela au niveau sémantique est que les divers besoins sont trop différents pour trouver un dénominateur commun suffisant pour une telle caractéristique. La cache de données est suffisamment mauvaise, et elle ne s'aggrave que lorsque vous avez besoin d'un contrôle de grain encore plus fin.

Il y aurait des avantages à une telle langue, par exemple, vous pouvez marquer certaines données comme privées pour quiconque, mais l'objet qui l'a créé (les mots de passe constitueraient un excellent exemple: même pas le code exécuté dans la même application pourrait les lire) .

Malheureusement, cette "protection" serait superficielle depuis au niveau de l'assembleur, la protection n'existerait pas. Pour être efficace, le matériel devra le soutenir. Dans ce cas, probablement au niveau d'un seul octet en RAM. Cela rendrait une telle application extrêmement sécurisée et douloureusement lente.

Dans le monde réel, vous trouverez ceci dans le Chip TPM sur votre carte mère et, d'une forme très grossière, avec les tables MMU de la CPU. Mais c'est à un niveau de page 4K, pas à un niveau d'octet. Il existe des bibliothèques pour gérer les deux mais qui ne comptent pas comme "support de langue" imo.

Java a quelque chose comme celui-ci sous la forme du API de sécurité . Vous devez envelopper le code en question dans un tuteur qui demande à la section actuelle SecuitManager si l'accès est autorisé ou non.

en Python, vous pouvez obtenir quelque chose de similaire avec des décorateurs (pour des méthodes et des fonctions) ou en implémentant __ setattr __ et __ getattr __ pour l'accès au champ.


2 commentaires

Votre analyse est valable dans un sens, mais vous semblez confusion «encapsulation de données» avec «Sécurité des données». Les modificateurs publics, protégés et privés dans les langues de l'OOP ne sont pas conçus de "sécuriser" les données, mais plutôt d'encapsuler des données dans une classe et de "protéger" de l'altération par d'autres classes. Les modificateurs ne sont pas destinés à "protéger" les données dans le sens de la sécurité des informations.


Quel serait le point d'une telle fonctionnalité sinon la sécurité? Pour l'encapsulation de données, "Private" suffit parce que vous pouvez toujours envelopper un seul champ dans une classe pour protéger l'accès à celui des autres instances de la même classe.