命名空间、类、对象和实例之间有什么区别?

28

我正在阅读《Head First C#》(它非常有趣和用户友好),但我想知道是否有任何有用的比喻来描述命名空间、类、方法、属性等如何“相互配合”?

类是父类,方法是子类等等,还是更加复杂?

可以把名称空间看作房子,把类看作房间(卫生间),方法是在房间里所能做的事情(洗漱等),属性是在进行该活动时能够做的事情,如使用肥皂,热水……

......我要拿我的外套了。

10个回答

70

我会这么说:

  • 命名空间:汽车的类别或品牌。注意,品牌并不一定决定汽车如何建造。你不能说本田总是有四个门,或者它总是有四轮驱动。这样的细节由类来规定。Rich.Carpenter的帖子很好地解释了命名空间的目的。

  • :构建特定汽车的蓝图。

  • 对象:从汽车蓝图(即类)创建的实际汽车(实例)。

  • 方法:用户可以让汽车执行的操作。例如:Start()IncreaseThrottle()Brake()OpenDoor()等。

  • 属性:汽车包含的属性、信息和构建块。例如:总行驶里程、颜色、方向盘尺寸、音响系统等等。

下面是可能对您来说更高级的概念。也许现在对您来说有点过头了,但如果您感兴趣,可以阅读:

  • 继承:当一个类基于另一个类并添加了一些更具体的细节时。继承关系通常从最常见和普遍的方面开始,一直到达到不再更具体的点。例如,在动物的语境下,这个关系可以是:Animal->Mamal->Rodent->Rat->RattusNorvegicus

  • 聚合:构建对象的属性。例如:"这辆车由四个轮子、底盘、发动机等组成"。

  • 属性: 描述对象的特性,通常不是其物理结构的一部分。例如颜色、最高速度、引擎容量等。

  • 封装: 将某些属性隐藏或保护其免受错误使用(从而损坏对象)。例如,您不会自由地公开汽车类的齿轮属性。您需要对其进行封装,并确保在调用SetGear()之前调用Clutch()

  • 重写: 如果一个类继承另一个类,则它也会继承该类的方法。重写是指继承类用其自己所需的行为替换此类方法的实现。下一点中使用示例。

  • 多态: 在开始实际使用之前,很难掌握的概念。它意味着通过使用通用引用来引用一种非常具体的对象,从而使您可以忽略特定类型(当您不需要知道它时)。例如,如果您想要"读取"停车场中每辆车的车牌号码属性,则您并不真正关心品牌,甚至不知道它是拖车、摩托车还是其他什么车辆。为了能够这样做,我们确保车牌号是继承线中最普遍的类(可能是Vehicle类)中的属性。因此,您只需通过将它们作为Vehicle类引用来处理列表中的所有对象,然后调用Vehicle::GetLicensePlateNumber()。任何需要特殊处理以检索号码的车辆都可以通过重写方法并使其以所需方式运行来实现此行为。因此,广泛范围的对象类型可以像相同类型的对象一样使用,但可以表现出不同的行为。


  • 1
    命名空间仅提供了一种更具体地引用内容的方式,因此它们不一定与公司或其他实体有必然联系。你可以想象在美国存在着同名的运动队,比如足球和棒球中的“巨人”,这是另一个隐喻。尽管有些队伍可能会搬迁或解散,但所创建的品牌仍然存在,例如NHL的魁北克雪崩队、温尼伯喷气机队或哈特福德捕鲸者队已经不存在了,但他们所做的记录仍然存在。 - JB King
    @jcollum:它是怎么坏的? - sharkin
    你搞混了重载和重写。 - Trillian
    @Trillian:确实,我不敢相信之前没有人注意到那个错误。已经更新了帖子。 - sharkin
    由于汽车蓝图可能非常复杂,我们应该将所有类放在一个命名空间下,使用嵌套类或将命名空间分为特定的汽车部件,例如carnamespace.body、carnamespece.engine等? - mko
    显示剩余5条评论

    29

    把类看作对象的描述,方法看作这些对象可以执行的操作。

    例如,我设计了一辆新车。用于创建实际物理车辆(对象)的是该车的计划或蓝图(类)。这些计划表明,汽车应具有功能性的喇叭。因此,我在车里设计了鸣笛功能(一个方法)。这些计划还表明,车子必须有四个轮子。轮子将成为车子的属性,并被实例化(在创建对象时分配给该属性)为4。颜色可能是另一个属性。属性描述对象的质量或特征(颜色、高度、宽度等)。

    现在,我在丰田工作(并非真的,但请忍耐)。丰田将包括我的汽车蓝图的命名空间。由于福特、通用等公司也可以拥有自己的汽车设计(类)以及完全相同的名称(car)和方法(honk),所以丰田、福特和通用的命名空间将保持这些蓝图(类)的独特性和区别,因此在应用程序中可以有多个具有相同名称的类和方法,当它们具有不同的命名空间时。

    希望这能有所帮助。


    怎么样建立一个 ..Car 命名空间,用于存放所有实际对应于汽车类型的车辆的基类? - mko

    13
    在一句话中:一个对象是一个实例

    2
    pew 伸出冒烟的手指 ;) - z -
    1
    并非所有的对象都是类的实例。在某些语言中,所有的对象都必须是类的实例。然而,允许对象字面量或通过其他方式构造对象的语言,可以允许不属于任何类的对象存在。例如,Javascript 对象从来不是类的实例——在 Javascript 中没有类的概念。它们可能与另一个对象具有原型链接。 - thomasrutter
    我不会投反对票,但也不确定是否能投赞成票。这完全正确,但对提问者毫无帮助。如果我问“foo”,“bar”和“blarg”的区别,有人说“foo是blarg的一种bar”,这对我来说没有任何意义。我需要上下文。(当然,回答这个问题可能需要写一整章的书,所以我不确定什么样的答案才是好的……也许这已经是最好的答案了。) - Beska
    另一方面,一个拥有3000+声望值的人怎么会问这个问题呢?看起来像是在刷声望值……或者这个人生活在一个非常不同的编程世界里。 - Beska
    @Beska:「foo是blarg的一种bar」至少有足够的用处来梳理它们之间的关系。 - Tomalak

    3

    通过使用房屋蓝图的比喻。

    蓝图是一个类。它指定了许多细节,但也留下了很多属性,例如房子的颜色、前门的颜色和样式等。你可以通过检查蓝图知道门会在哪里,而且会有一扇门。

    对象是你从那个蓝图建造的房子。你可以从同一蓝图建造许多房子。它们都具有相同的外观和布局,但属性可能会有所不同,例如外部油漆的颜色、前门的样式等。然而,所有房子的前门位置都相同。

    你可以将每个房子称为从特定蓝图中生成的房子实例。

    因此,正如@yx所说,对象是类的实例。


    2

    类通常用于表示某种对象。它可能类似于发票这样的物理对象,但也可能是更抽象的东西。

    有时会使用动物作为类的示例,因为我们熟悉动物的工作方式。所以,让我们用一些动物来举例:

    类可以是某种动物,比如CatDog。当您创建类的一个实例时,它就变成了一个特定的对象,比如Fido the dog。

    命名空间用于逻辑上分组类,因此CatDog类可以放置在命名空间Animals.Pets中。虽然命名空间是分层的,但这并不意味着其中的类是分层的。它们只是不同的组,因此Animals命名空间中的类不自动成为Animals.Pets命名空间中的类的父级。

    方法是对象执行的操作,例如Eat()Sleep()

    属性是描述对象某个方面的内容,例如NumberOfLegsIsSleeping


    2
    我认为你的类可能是工作职位,执行不同的操作(换句话说,这些操作是方法)。您可能有各种个人执行操作(对象的各种实例)。
    这些工作职位的集合将驻留在一个部门中。财务部拥有其自己的工作/类别(会计师、簿记员等),但他们需要与销售部门一起工作,后者拥有自己的工作/类别。
    从这个意义上讲,各个部门就是命名空间。在销售部门工作的人最终需要与财务部门合作。多个部门(或命名空间)共同努力实现目标。
    现在,这些部门可能是公司的一部分;该公司将是所有这些部门的根命名空间。以这种方式,命名空间可以存在并嵌套在一起。
    简而言之,命名空间几乎完全隔离了责任。
    想象一下多家公司共同合作(Microsoft .net命名空间与您自己的命名空间),您就能得到更大的画面。

    2
    一个对象可以是一个类的实例吗?

    1
    一个类定义了一个对象的外观 - 它包含哪些数据,有哪些方法,以及与哪些其他类相关。
    一个实例是该类的单个创建实体 - 它是通过使用类定义作为参考创建的对象。

    1

    类是一种对象类型。例如,您可以拥有任意数量的同一类对象。

    实例是一个对象,有时这两个术语可以互换使用,因为在许多编程语言中,所有对象也都是类的实例。人们使用“实例”一词来明确表示他们不是在谈论类,而是该类的一个对象。


    1
    一个是一个对象的模板。它是源代码,告诉编译器哪些成员变量和方法放入该类型的类的对象中。
    一个对象和一个实例其实是一样的。从类模板中,您可以创建许多类的实例(或对象)。每个实例都有类中定义的所有成员和方法,在其自己的内存中(尽管您可以有共享成员,并且方法几乎总是在实例之间共享)。

    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接