Class真的只是创建对象的蓝图吗?

时间:2017-01-03 13:29:40

标签: oop

据说在OOP中 - 类是创建对象的蓝图。

但是,如果没有实例,“静态”工作的事实又如何呢?

“蓝图”只是过分简化了什么类?

如果是这样的话 - 我们如何修复我们的心理模型来理解同一个类中的静态和非静态?

6 个答案:

答案 0 :(得分:0)

是的:这是一种过度简化。您还可以使用没有创建实例的实用程序类。

答案 1 :(得分:0)

  

“蓝图”只是过分简化了什么类?

是。但是不要误解我的意思,蓝图类比也不错,因为大部分时间你都在处理非静态成员。我无法想到用这个类比来解释静态成员的好方法。但我有一个不那么好的方式。

使用蓝图创建的对象具有所有非静态成员。因此,非静态成员描述了将由此蓝图创建的对象。相比之下,静态成员描述了蓝图本身。

这是一个不好的解释,不是吗?

静态成员不属于每个单独的对象,而属于类本身。它与类有关,但该成员在每个类的实例中都没有意义。

你可能会想,我什么时候会用这样的东西?一个例子是单例模式。这是Java中的一个简单实现,但它在C#中编译得很好:

class Earth {
    private static Earth instance = new Singleton();
    public static Earth getInstance() { return instance; }
    private Earth() {}
    // non-static members...
}

instancegetInstance不存在于每个单独的对象上,而是存在于类本身上。为什么?因为只有这些Earth对象之一才有意义。

此外,如果您需要实用程序方法,静态成员也很有用。您可以在不创建类实例的情况下调用它们。 .NET和JDK中的Math类是一个充满了各种方法的类的示例。

答案 2 :(得分:0)

一开始就是:OOP是一个概念或范例,而编程语言可能完全或部分地实现这些概念(并提供除OOP之外的其他概念)。例如,C ++和C#仍然支持原始数据类型,它们不是对象。另一方面,在Smalltalk中,偶数整数值是可以向其发送消息的对象。而且我认为甚至定义了什么" OOP"概念是不清楚的(谈论OOP需要多重继承吗?)

蓝图和static实际上并不矛盾,因为static成员可以被视为在类的所有实例之间共享的值/方法。因此,每个对象都是" blueprint"一个类也有这些静态成员可用,但不是自己的。此外,可以看到具有静态成员声明的类也作为单例class元对象的蓝图。

例如,在C ++中使用以下代码:

class TestClass {
public:
    int instanceMember;
    static int classMember;
};

int TestClass::classMember;

int main(int argc, char * argv[])
{

    TestClass c1;
    c1.instanceMember = 5;
    c1.classMember = 3;

    TestClass c2;
    c2.instanceMember = 2;
    std::cout << "classMember of c2: " << c2.classMember;

    int accessMetaObject = TestClass::classMember;
    std::cout << "classMember accessed through metaobject: " << accessMetaObject;

    // Output:
    // classMember of c2: 3
    // classMember accessed through metaobject: 3
    return 0;
}

您可以像其他任何成员一样访问静态成员c2.classMember,因此它是&#34;蓝图&#34;的一部分。但是,该值在所有实例之间共享,因此在创建实例时已设置c2.classMember的值。希望这个对你有帮助。此外,它表明 - 由于所有实例共享相同的静态成员 - 您可以访问这些成员而无需任何&#34;真实&#34;实例通过(虚构)类元对象,即TestClass::classMember

请注意,某些编程语言(例如,Smalltalk)明确区分实例和类,而static成员实际上被视为类成员,即相应class的成员-metaobject。

答案 3 :(得分:0)

更好的措辞可能是

  

类是包含对象蓝图的结构,以及创建此类对象的能力

静态方法是该结构的扩展,它们确实与蓝图无关。你可以说静态方法是类对象本身的方法(&#34;类方法&#34;),甚至可以说创建函数(&#34;构造函数&#34;)本质上是静态方法。

根据您使用的特定语言,蓝图和类对象之间的区别可以非常明确。

答案 4 :(得分:0)

我不会太担心这件事。通过使用大量的例子,人们倾向于更好地理解,而不是阅读明确的定义(大多数概念都不能归结为确切的定义)

您似乎已经理解了基本概念:类可以是对象的蓝图,但也可以包含不与任何特定对象绑定的静态成员(但可能被实例化该类的所有对象使用)< / p>

更多提示:

OO语言中的所有代码都需要在一个类中(除非您将其键入调试器或其他非常临时的内容)。因此&#34; class&#34;将是一个非常通用的术语,涵盖了可以用代码完成的任何事情。

请注意,类也可以是创建其他的蓝图。或者它可以是一个方便的地方,以保留可能在应用程序中的任何地方使用的静态方法的集合。

答案 5 :(得分:0)

在我看来,我不会将类称为蓝图而是原型

取自Oxford dictionary

  

1.1被模仿的原件;原型。

此外,取自WordReference

  

原始图案或模型,所有相同类型的东西   被复制或以他们为基础;模型或第一种形式;   原型。

关于类静态成员,我会说它们在面向对象的设计或体系结构中只是陌生人。正如您已经指出的那样,静态成员不是类实例的一部分(即一个对象),但它们仍然有用

所以,关于你的问题:

  

如果是这样 - 我们如何修复我们的心理模型以理解静态   和同一类中的非静态?

......我会说没有心理修复。类是对象的原型,静态成员是无对象的一部分。

静态类成员将类视为过程模块:将类转换为标识符以对一个或多个静态成员进行分组。

事实上,检查现代设计模式和范例是如何或多或少地避免静态成员的:如果你想采用依赖注入方式,你会使用静态吗? 我怀疑

总结......

确切地说,静态类成员支持是一个实现细节,它不是面向对象的编程功能。有一种众所周知的语言没有实现实际静态:

class A {
   static doStuff() {}
}

// is
function A() {}
A.doStuff = function() {};

是的,它是JavaScript! static修饰符只是向函数添加属性的语法糖,而函数又是一个对象......