OOP Terminologie: classe, attribut, propriété, champ, membre de données
Je commence à étudier OOP et je veux savoir ce qui constitue une classe. Je suis un peu confus à quel point certains éléments de base sont lâchement utilisés et donc ajoute à ma confusion.
J'ai regardé la classe C++, la classe Java et je veux en savoir assez pour écrire ma propre pseudo classe pour m'aider à comprendre.
Par exemple dans cet article je lis ceci (.. attribut de classe (ou propriété de classe, champ ou membre de données)
J'ai vu des questions assez bien découpées qui montrent qu'il y a une différence entre la propriété de classe et le champ de classe par exemple Quelle est la différence entre un champ et une propriété en C #?
Selon la langue que j'étudie, la définition de
- Propriété
- Des champs
- Variables de classe
- Les attributs
différent d'une langue à l'autre?
Les "champs", les "variables de classe" et les "attributs" sont plus ou moins identiques - un niveau inférieur emplacement de stockage attaché à un objet. La documentation de chaque langue peut utiliser un terme différent de manière cohérente, mais la plupart des programmeurs réels les utilisent de manière interchangeable. (Cependant, cela signifie également que certains termes peuvent être ambigus, comme "variable de classe" - qui peut être interprété comme "une variable d'une instance d'une classe donnée", ou "une variable de l'objet de classe lui-même" dans un langage où les objets de classe sont quelque chose que vous pouvez manipuler directement.)
Les "propriétés" sont, dans la plupart des langues que j'utilise, quelque chose de complètement différent - elles sont un moyen d'attacher un comportement personnalisé à la lecture/écriture d'un champ. (Ou pour le remplacer.)
Donc en Java, l'exemple canonique serait:
class Circle {
// The radius field
private double radius;
public Circle(double radius) {
this.radius = radius;
}
// The radius property
public double getRadius() {
return radius;
}
public double setRadius(double radius) {
// We're doing something else besides setting the field value in the
// property setter
System.out.println("Setting radius to "+radius);
this.radius = radius;
}
// The circumference property, which is read-only
public double getCircumference() {
// We're not even reading a field here.
return 2 * Math.PI * radius;
}
}
(Notez qu'en Java, une propriété foo
est une paire de méthodes d'accesseur appelées getFoo()
et setFoo()
- ou simplement le getter si la propriété est en lecture seule.)
Une autre façon de voir les choses est que les "propriétés" sont une abstraction - une promesse d'un objet pour permettre aux appelants d'obtenir ou de définir un élément de données. Alors que les "champs" etc. sont un possible implémentation de cette abstraction. Les valeurs de getRadius()
ou getCircumference()
dans l'exemple ci-dessus peuvent être stockées directement, ou elles peuvent être calculées, cela n'a pas d'importance pour l'appelant; les poseurs peuvent ou non avoir des effets secondaires; cela n'a pas d'importance pour l'appelant.
Je suis d'accord avec vous, il y a beaucoup de confusion inutile en raison des définitions approximatives et de l'utilisation incohérente de nombreux termes OO. Les termes dont vous parlez sont utilisés de manière quelque peu interchangeable, mais on pourrait dire certains sont plus généraux que les autres (ordre décroissant): Propriété -> Attributs -> Variables de classe -> Champs.
Les passages suivants, extraits de "Analyse et conception orientées objet" par Grady Booch aident à clarifier le sujet. Tout d'abord, il est important de comprendre le concept d'État:
état d'un objet englobe toutes les propriétés (généralement statiques) de l'objet plus les valeurs actuelles (généralement dynamiques) de chacune de ces propriétés . Par propriétés, nous entendons la totalité des attributs de l'objet et les relations avec d'autres objets.
La POO est assez générique en ce qui concerne certaines nomenclatures, car elle varie énormément d'une langue à l'autre:
Les termes champ (Object Pascal), variable d'instance (Smalltalk), objet membre (C++) et slot (CLOS) sont interchangeables , ce qui signifie un référentiel pour une partie de l'état d'un objet. Collectivement, ils constituent la structure de l'objet.
Mais la notation introduite par l'auteur est précise:
Un attribut désigne une partie d'un objet agrégé, et est donc utilisé pendant l'analyse ainsi que la conception pour exprimer une propriété singulière de la classe . En utilisant la syntaxe indépendante du langage, un attribut peut avoir un nom, une classe ou les deux, et éventuellement une expression par défaut:
A:C=E
.Variable de classe: Partie de l'état d'une classe . Collectivement, les variables de classe d'une classe constituent sa structure. Une variable de classe est partagée par toutes les instances de la même classe. En C++, une variable de classe est déclarée comme membre statique.
En résumé:
Propriété est un concept large utilisé pour désigner une caractéristique particulière d'une classe , englobant à la fois ses attributs et ses relations avec d'autres classes .
Attribut désigne une partie d'un objet agrégé , et est donc utilisé pendant l'analyse ainsi que la conception pour exprimer une propriété singulière de la classe.
Variable de classe est un attribut défini dans une classe dont une seule copie existe , quel que soit le nombre d'instances de la classe . Ainsi, toutes les instances de cette classe partagent sa valeur ainsi que sa déclaration.
Field est un terme spécifique au langage pour variable d'instance, c'est-à-dire un attribut dont la valeur est spécifique à chaque objet .
Je fais du oop depuis plus de 20 ans, et je trouve que les gens utilisent souvent des mots différents pour les mêmes choses. Ma compréhension est que les champs, les variables de classe et les attributs signifient tous la même chose. Cependant, la propriété est mieux décrite par le lien stackoverflow que vous avez inclus dans votre question.
J'ai découvert dans ma question que les propriétés telles que définies dans .Net ne sont qu'une syntaxe de commodité pour le code, et elles ne sont pas du tout liées aux variables sous-jacentes (sauf pour les propriétés implémentées automatiquement, bien sûr). Donc, dire "quelle est la différence entre la propriété de classe et le champ de classe" revient à dire: quelle est la différence entre une méthode et un attribut. Aucune différence, l'un est le code et l'autre les données. Et, ils n'ont rien à voir les uns avec les autres.
Il est vraiment dommage que les mêmes mots, comme "attribut" et "propriété", soient réutilisés dans différentes langues et idéologies pour avoir des significations radicalement différentes. Peut-être que quelqu'un a besoin de définir un langage orienté objet pour parler des concepts en POO? UML?
Tout d'abord, vous devez sélectionner une langue. Par exemple, je vous recommande de sélectionner la langue et la communauté Ruby. Jusqu'à ce que vous sélectionniez une langue, vous ne pouvez pas échapper à la confusion, car différentes communautés utilisent des termes différents pour les mêmes choses.
Par exemple, ce qu'on appelle Module
dans Ruby, Java dit classe abstraite. Ce qu'on appelle attributs dans certaines langues, est appelé instance variables
en Ruby. Je recommande Ruby surtout pour son système logique et bien conçu OOP.
Écrivez ce qui suit dans un fichier * .rb ou sur la ligne de commande dans irb (interactif Ruby):
class Dog # <-- Here you define a class representing all dogs.
def breathe # <-- Here you teach your class a method: #breathe
puts "I'm breathing."
end
def speak # <-- Here you teach your class another method: #speak
puts "Bow wow!"
end
end
Maintenant que vous avez une classe, vous pouvez en créer une instance:
Seamus = Dog.new
Vous venez de créer une instance, un chien particulier de la classe Dog, et vous l'avez stocké dans la constante Seamus
. Vous pouvez maintenant jouer avec:
Seamus.breathe # <-- Invoking #breathe instance method of Seamus
#=> I'm breathing.
Seamus.speak # <-- Invoking #speak instance method of Seamus
#=> Bow wow!
Quant à vos questions terminologiques restantes, "propriété" ou "attribut" est compris comme "variable" dans Ruby, presque toujours une variable d'instance. Et quant au terme "membre de données", oubliez-le. Le terme "champ" n'est pas vraiment utilisé dans Ruby, et "variable de classe" dans Ruby signifie quelque chose de très rarement utilisé, que vous n'avez certainement pas besoin de savoir pour le moment.
Donc, pour garder le monde agréable et vous montrer que OOP est vraiment simple et indolore dans Ruby, créons un attribut ou, dans Ruby, une variable d'instance de la classe Dog
. Comme nous le savons, chaque chien a un certain poids, et différents chiens peuvent avoir des poids différents. Ainsi, lors de la création d'un nouveau chien, nous demanderons à l'utilisateur de nous indiquer le poids du chien:
class Dog
def initialize( weight ) # <-- Defining initialization method with one argument 'weight'
@weight = weight # <-- Setting the dog's attribute (instance variable)
end
attr_reader :weight # <-- Making the dog's weight attribute visible to the world.
end
Drooly = Dog.new( 16 ) # <-- Weight now must provide weight upon initialization.
Drooly.weight # <-- Now we can ask Drooly about his weight.
#=> 16
Rappelez-vous qu'avec Ruby (ou Python), les choses sont simples.
Généralement, les champs, les méthodes, les méthodes statiques, les propriétés, les attributs et la classe (ou les variables statiques) ne changent pas en fonction de la langue ... Bien que la syntaxe changera probablement en fonction de la langue, ils fonctionneront de la manière attendue dans toutes les langues (attendez-vous à ce que des termes tels que les champs/membres de données soient interchangeables dans toutes les langues)
En C # ....
Un champ est une variable qui existe pour une instance donnée d'une classe.
par exemple.
public class BaseClass
{
// This is a field that might be different in each instance of a class
private int _field;
// This is a property that accesses a field
protected int GetField
{
get
{
return _field;
}
}
}
Les champs ont une "visibilité" qui détermine ce que les autres classes peuvent voir le champ, donc dans l'exemple ci-dessus un champ privé ne peut être utilisé que par la classe qui le contient, mais l'accesseur de propriété fournit un accès en lecture seule au champ par sous-classes.
Une propriété vous permet d'obtenir (parfois appelé un accesseur) ou de définir (parfois appelé un mutateur) la valeur du champ ... Les propriétés vous permettent de faire quelques choses, d'empêcher l'écriture d'un champ par exemple de l'extérieur de la classe, de changer la visibilité de domaine (par exemple privé/protégé/public). Un mutateur vous permet de fournir une logique personnalisée avant de définir la valeur d'un champ
Les propriétés ressemblent donc plus à des méthodes pour obtenir/définir la valeur d'un champ mais offrent plus de fonctionnalités
par exemple.
public class BaseClass
{
// This is a field that might be different in each instance of a class
private int _field;
// This is a property that accesses a field, but since it's visibility
// is protected only subclasses will know about this property
// (and through it the field) - The field and property in this case
// will be hidden from other classes.
protected int GetField
{
// This is an accessor
get
{
return _field;
}
// This is a mutator
set
{
// This can perform some more logic
if (_field != value)
{
Console.WriteLine("The value of _field changed");
_field = value;
OnChanged; // Call some imaginary OnChange method
} else {
Console.WriteLine("The value of _field was not changed");
}
}
}
}
Une classe ou une variable statique est une variable qui est la même pour toutes les instances d'une classe. Ainsi, par exemple, si vous vouliez une description pour une classe, cette description serait la même pour toutes les instances de la classe et serait accessible par en utilisant la classe par exemple.
public class BaseClass
{
// A static (or class variable) can be accessed from anywhere by writing
// BaseClass.DESCRIPTION
public static string DESCRIPTION = "BaseClass";
}
public class TestClass
{
public void Test()
{
string BaseClassDescription = BaseClass.DESCRIPTION;
}
}
Je serais prudent lors de l'utilisation de la terminologie relative à un attribut. En C #, c'est une classe qui peut être appliquée à d'autres classes ou méthodes en "décorant" la classe ou la méthode, dans d'autres contextes, elle peut simplement se référer à un champ qu'une classe contient.
// The functionality of this attribute will be documented somewhere
[Test]
public class TestClass
{
[TestMethod]
public void TestMethod()
{
}
}
Certains langages n'ont pas "d'attributs" comme C # (voir ci-dessus)
Espérons que tout ait du sens ... Je ne veux pas vous surcharger!