【问题标题】:OOP Terminology: class, attribute, property, field, data memberOOP 术语:类、属性、属性、字段、数据成员
【发布时间】:2013-05-25 15:51:13
【问题描述】:

我开始学习 OOP,我想了解什么是类。我对某些核心元素的使用松散程度感到有些困惑,从而增加了我的困惑。

我看过C++类,java类,想知道的足够写自己的伪类来帮助理解。

例如在this article 我读到这个(..类属性(或类属性、字段或数据成员)

我已经看到了一些很好的问题,这些问题表明类属性和类字段之间存在差异,例如What is the difference between a Field and a Property in C#?

根据我所学的语言,定义是什么

  • 财产
  • 字段
  • 类变量
  • 属性

因语言而异?

【问题讨论】:

    标签: class oop attributes


    【解决方案1】:

    “字段”、“类变量”和“属性”或多或少相同 - 附加到对象的低级存储槽。每种语言的文档可能始终使用不同的术语,但大多数实际程序员可以互换使用它们。 (但是,这也意味着某些术语可能是模棱两可的,例如“类变量” - 它可以解释为“给定类的实例的变量”,或“类对象本身的变量”其中类对象是您可以直接操作的东西。)

    在我使用的大多数语言中,“属性”是完全不同的东西——它们是一种将自定义行为附加到读/写字段的方法。 (或替换它。)

    所以在 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 void 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 中,属性 foo 是一对访问器方法,称为 getFoo()setFoo() - 如果属性是只读的,则只是 getter。)


    另一种看待这一点的方式是,“属性”是一个抽象 - 一个对象承诺允许调用者获取或设置一段数据。而“字段”等是这种抽象的一种可能的实现。上例中getRadius()getCircumference()的值可以直接存储,也可以计算出来,调用者无所谓;二传手可能有也可能没有副作用;调用者无所谓。

    【讨论】:

    • 一个例外:在 Python 中,“类变量”是指类对象的成员(其他语言称为静态变量/成员/字段)。
    • @delnan 补充说,对于将类型作为一等对象的任何语言,歧义可能是一个警告。 (“类型是一流的对象”也可能是必须向 OOP 新手解释的最令人困惑的句子。)
    【解决方案2】:

    我同意你的观点,由于定义松散和许多 OO 术语的使用不一致,存在很多不必要的混淆。您所询问的术语在某种程度上可以互换使用,但可以说有些术语比其他术语更通用(降序):属性 -> 属性 -> 类变量 -> 字段。

    以下段落摘自 Grady Booch“面向对象的分析与设计”,有助于阐明主题。首先,了解状态的概念很重要:

    对象的状态包含对象的所有(通常是静态的)属性以及每个属性的当前(通常是动态的)值。属性是指对象的属性以及与其他对象的关系的总和。

    OOP 在某些术语方面非常通用,因为它因语言而异:

    field (Object Pascal)、instance variable (Smalltalk)、member object (C++) 和 slot (CLOS) 可以互换,表示对象部分状态的存储库。它们共同构成了对象的结构。

    但是作者介绍的符号是准确的:

    属性表示聚合对象的一部分,因此在分析和设计期间用于表达类的单一属性。使用与语言无关的语法,一个属性可以有一个名称、一个类或两者兼有,还可以有一个默认表达式:A:C=E

    类变量:状态的一部分。一个类的类变量共同构成了它的结构。 类变量由同一个类的所有实例共享。在 C++ 中,类变量被声明为静态成员。

    总结:

    • 属性是一个宽泛的概念,用于表示一个类的特定特征,包括它的属性以及它与其他类的关系。

    • 属性 表示聚合对象的一部分,因此在分析和设计期间用于表达类的单一属性。

    • 类变量是一个在一个存在单个副本的类中定义的属性,无论该类的实例存在多少。所以该类的所有实例共享它的值以及它的声明。

    • 字段实例变量的语言特定术语,即,其值特定于每个对象的属性

    【讨论】:

      【解决方案3】:

      我从事 oop 已有 20 多年了,我发现人们经常对相同的事情使用不同的词。我的理解是字段、类变量和属性都意味着同样的事情。但是,最好用您在问题中包含的 the stackoverflow link 来描述属性。

      【讨论】:

        【解决方案4】:

        一般来说,字段、方法、静态方法、属性、属性和类(或静态变量)不会因语言而改变...虽然语法可能会因每种语言而改变,但它们的功能会有所不同您会期望跨语言(期望字段/数据成员等术语可以跨语言互换使用)

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

        字段具有“可见性”,这决定了其他类可以看到该字段,因此在上面的示例中,私有字段只能由包含它的类使用,但属性访问器提供子类对该字段的只读访问.

        属性可以让您获取(有时称为访问器)或设置(有时称为修改器)字段的值...属性可以让您做一些事情,例如防止从类外部写入字段,更改字段的可见性(例如私有/受保护/公共)。 mutator 允许您在设置字段的值之前提供一些自定义逻辑

        所以属性更像是获取/设置字段值但提供更多功能的方法

        例如。

        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# 那样的“属性”(见上文)

        希望这一切都有意义......不想让你超负荷!

        【讨论】:

          【解决方案5】:

          首先,您需要选择一种语言。例如,我建议您选择 Ruby 语言和社区。在您选择一种语言之前,您无法避免混淆,因为不同的社区对相同的事物使用不同的术语。

          例如,Ruby 中称为Module,Java 称为抽象类。在某些语言中称为 attributes,在 Ruby 中称为 instance variables。我特别推荐 Ruby,因为它具有逻辑性和设计良好的 OOP 系统。

          将以下内容写入 *.rb 文件,或在 irb(交互式 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
          

          现在你有了一个类,你可以为它创建一个实例

          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 中的意思是很少使用的东西,你现在绝对不需要知道。

          所以,为了让世界保持美好并向您展示 OOP 在 Ruby 中非常简单和轻松,让我们创建一个属性,或者用 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),事情很简单。

          【讨论】:

          • 我的例子有什么问题吗?
          【解决方案6】:

          我在my question 中发现,.Net 中定义的属性只是代码的一种方便语法,它们根本不依赖于底层变量(当然,自动实现的属性除外)。所以,说“类属性和类字段有什么区别”就像说:方法和属性有什么区别。没有区别,一个是代码,一个是数据。而且,它们之间不需要有任何关系。

          如果在不同的语言和意识形态中重复使用相同的词,例如“属性”和“财产”,从而具有截然不同的含义,这真是太糟糕了。也许有人需要定义一种面向对象的语言来谈论 OOP 中的概念? UML?

          【讨论】:

            【解决方案7】:

            在课堂上

            public class ClassSample
            {
                private int ClassAttribute;
            
                public int Property
                {
                    get { return ClassAttribute; }
                    set { ClassAttribute = value; }
                }
            }
            

            在节目中

                class Program
                {
                    static void Main(string[] args)
                    {
                        var objectSample = new ClassSample();
                        //Get Object Property
                        var GetProperty = objectSample.Property;
                    }
                }
            

            【讨论】:

              猜你喜欢
              • 2011-02-12
              • 2012-07-06
              • 2011-08-27
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多