web-dev-qa-db-ja.com

OOP用語:クラス、属性、プロパティ、フィールド、データメンバー

私はOOPを勉強し始めています。クラスを構成するものを学びたいと思います。いくつかのコア要素がどの程度緩く使用されているのか少し混乱しています。

私はC++クラスのJavaクラスを見てきましたが、理解を助けるために自分の疑似クラスを書くのに十分な知識が必要です。

たとえば この記事 私はこれを読みました(..クラス属性(またはクラスプロパティ、フィールド、またはデータメンバー)

たとえば、クラスプロパティとクラスフィールドの間に違いがあることを示す質問をかなりよくカットしました C#のフィールドとプロパティの違いは何ですか?

私が勉強している言語に応じて、の定義は

  • 物件
  • 田畑
  • クラス変数
  • 属性

言語ごとに違う?

「フィールド」、「クラス変数」、および「属性」は、多かれ少なかれ同じ-オブジェクトに付加された低レベルストレージスロットです。各言語のドキュメントでは一貫して異なる用語が使用される場合がありますが、実際のプログラマーのほとんどは同じ用語を使用しています。 (ただし、これは、「クラス変数」のように一部の用語が曖昧になる可能性があることも意味します。これは、言語の「特定のクラスのインスタンスの変数」または「クラスオブジェクト自体の変数」クラスオブジェクトは、直接操作できるものです。)

「プロパティ」は、私が使用するほとんどの言語で完全に別のものです-フィールドの読み取り/書き込みにカスタム動作を付加する方法です。 (またはそれを交換します。)

したがって、Javaでは、標準的な例は次のようになります。

_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;
    }

}
_

(Javaでは、プロパティfoogetFoo()およびsetFoo()と呼ばれるアクセサメソッドのペアであることに注意してください。または、プロパティが読み取り専用の場合は単なるゲッターです。)


これを見るもう1つの方法は、「プロパティ」がabstraction-呼び出し側がデータの一部を取得または設定できるようにするオブジェクトによる約束です。 「フィールド」などは、1つの可能性ですが、この抽象化の実装です。上記の例のgetRadius()またはgetCircumference()の値は、直接保存することも、計算することもできますが、呼び出し側にとっては問題ではありません。セッターには副作用がある場合とない場合があります。呼び出し側には関係ありません。

25
millimoose

私はあなたに同意します。定義が緩く、多くのOO用語が使用されているため、不必要な混乱がたくさんあります。あなたが尋ねている用語は多少交換可能ですが、他よりも一般的です(降順):プロパティ->属性->クラス変数->フィールド。

"Object-Oriented Analysis and Design" byGrady Boochから抽出した次の文章は、主題を明確にするのに役立ちます。まず、状態の概念を理解することが重要です。

オブジェクトの状態は、オブジェクトのすべての(通常は静的な)プロパティに加えて、これらの各プロパティの現在の(通常は動的な)値を含みます。プロパティとは、オブジェクトの属性と他のオブジェクトとの関係の全体を意味します。

OOPは、言語によって大きく異なるため、特定の命名法に関しては非常に一般的です。

フィールド(Object Pascal)、インスタンス変数(Smalltalk)、メンバーオブジェクト(C++)、およびスロット(CLOS)という用語は交換可能です、オブジェクトの状態の一部のリポジトリを意味します。集合的に、それらはオブジェクトの構造を構成します。

しかし、著者によって紹介された表記は正確です:

属性は集合オブジェクトの一部を示すため、分析中およびクラスの特異なプロパティを表現する設計時に使用されます。言語に依存しない構文を使用すると、属性に名前、クラス、またはその両方、およびオプションでデフォルト式を含めることができます:A:C=E

クラス変数:クラスの状態の一部。集合的に、クラスのクラス変数はその構造を構成します。 クラス変数は、同じクラスのすべてのインスタンスで共有されます。C++では、クラス変数は静的メンバーとして宣言されます。

要約すれば:

  • プロパティは、クラスの特定の特性を示すために使用される広い概念です、属性と他のクラスとの関係の両方を含みます。

  • 属性は集合オブジェクトの一部を表します。そのため、分析中およびデザインの特異な特性を表現するために使用されますクラス。

  • クラス変数は、クラスのインスタンスの数に関係なく、単一のコピーが存在するクラスで定義された属性です 。したがって、そのクラスのすべてのインスタンスは、その値と宣言を共有します。

  • フィールドインスタンス変数の言語固有の用語です。つまり、値が各オブジェクトに固有の属性です

6
saza

私は20年以上にわたってoopを行ってきましたが、同じことをするために人々はしばしば異なる言葉を使うことがわかりました。私の理解では、フィールド、クラス変数、属性はすべて同じことを意味します。ただし、プロパティは、質問に含めた stackoverflowリンク で説明するのが最適です。

2
Stochastically

私の質問 で、.Netで定義されているプロパティはコードの便利な構文であり、基礎となる変数にまったく結び付けられていないことを発見しました(もちろん、自動実装プロパティを除きます)。したがって、「クラスプロパティとクラスフィールドの違いは何であるか」と言うのは、メソッドと属性の違いは何であるかを言うことに似ています。違いはありません。1つはコードで、もう1つはデータです。そして、彼らはお互いに関係する必要はありません。

「属性」や「プロパティ」などの同じ単語が、異なる言語やイデオロギーで再利用されてまったく異なる意味を持つのは本当に残念です。誰かがオブジェクト指向言語を定義してOOPの概念について話す必要があるのでしょうか? UML?

1
user4624979

まず、言語を選択する必要があります。たとえば、Ruby言語とコミュニティを選択することをお勧めします。言語を選択するまでは、同じものに対して異なるコミュニティが異なる用語を使用するため、混乱を免れません。

たとえば、RubyでModuleとして知られているもの、Javaは抽象クラ​​スとして知られています。attributesとして知られています一部の言語では、instance variables Rubyで。 Ruby特にその論理的で適切に設計されたOOPシステムに対して。

以下を* .rbファイルに書き込むか、コマンドラインでirb(interactive 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

クラスができたので、instanceを作成できます:

Seamus = Dog.new

インスタンス、クラスDogの特定の犬を作成し、定数Seamusに保存しました。今、あなたはそれで遊ぶことができます:

Seamus.breathe                   # <-- Invoking #breathe instance method of Seamus
#=> I'm breathing.
Seamus.speak                     # <-- Invoking #speak instance method of Seamus
#=> Bow wow!

残りの用語の質問に関しては、「プロパティ」または「属性」はRubyでは「変数」として理解されます。ほとんどの場合、インスタンス変数です。 「データメンバー」という用語については、忘れてください。 Rubyでは「フィールド」という用語は実際には使用されません。また、Rubyの「クラス変数」は、非常にまれに使用されるものを意味します。

だから、世界を素敵に保ち、RubyでOOPが本当にシンプルで無痛であることを示すために、属性を作成しましょう。または、Ruby Dogクラスのインスタンス変数私たちが知っているように、すべての犬にはある程度の体重があり、異なる犬は異なる体重を持っている可能性があります。

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

Ruby(またはPython)を使用すると、物事は簡単です。

1
Boris Stitnicky

一般に、フィールド、メソッド、静的メソッド、プロパティ、属性、およびクラス(または静的変数)は言語ごとに変化しません...構文はおそらく言語ごとに変化しますが、期待どおりに機能します言語間(フィールド/データメンバなどの用語は、言語間で交換可能に使用されると予想されます)

C#で...

フィールドは、クラスの特定のインスタンスに存在する変数です。

例えば。

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;
        }
    }
}

フィールドには「可視性」があるため、他のクラスがフィールドを表示できるかどうかを決定します。したがって、上記の例ではプライベートフィールドはそれを含むクラスでのみ使用できますが、プロパティアクセサーはサブクラスによるフィールドへの読み取り専用アクセスを提供します。

プロパティを使用すると、フィールドの値を取得(アクセサと呼ばれることもあります)または設定(ミューテータと呼ばれることもあります)することができます...フィールド(プライベート/保護/パブリックなど)。ミューテーターを使用すると、フィールドの値を設定する前にカスタムロジックを提供できます。

したがって、プロパティはフィールドの値を取得/設定するメソッドに似ていますが、より多くの機能を提供します

例えば。

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");
            }
        }
    }
}

クラスまたは静的変数は、クラスのすべてのインスタンスで同じ変数です。したがって、たとえば、クラスの説明が必要な場合、その説明はクラスのすべてのインスタンスで同じであり、アクセスできますクラスを使用します。

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;
    }
}

属性に関連する用語を使用するときには注意が必要です。 C#では、クラスまたはメソッドを「装飾」することで他のクラスまたはメソッドに適用できるクラスです。他のコンテキストでは、クラスに含まれるフィールドを単に参照する場合があります。

// The functionality of this attribute will be documented somewhere
[Test]
public class TestClass
{
    [TestMethod]
    public void TestMethod()
    {
    }
}

一部の言語には、C#のように「属性」がありません(上記を参照)

すべてが理にかなっていることを願っています...過負荷になりたくない!

1
0909EM