繁体   English   中英

面向对象编程,无需初始化

[英]Object oriented programming without initializing

我已经阅读了许多类似的问题,但我仍然不明白这一点。

看这个例子:

class Cat:
    pass

a_cat = Cat
a_cat.name = "hs"
a_cat.name
'hs' #returns this

上面我已经创建了一个cat class的实例, name是关于那只猫的。 没有使用__init __

这是一个类似的示例,但带有__init__

class Dog:
    def __init__(self,name):
        self.name = name

doggo = Dog("ad")
doggo.name
'ad' #returns this

问题:如果两个版本都允许将方法传递给每个类的单个实例,那么为什么还要使用第二种方法呢? 他们看起来是一样的结果。

不同之处在于 init 方法是在对象初始化时调用的,例如,这意味着您需要传递参数。 假设你有一个有颜色的类狗,你不能使用没有颜色的狗,所以你需要传递一个颜色,否则依赖于这个颜色的函数将无法运行。 这里也是一个很好的链接解释它: https://micropyramid.com/blog/understand-self-and-初始化-方法-在- python的类/

对于 Dog 的示例,假设您有一个函数

print(self.color)

如果您不使用颜色初始化类,则该函数将不会运行。 __init__函数始终在初始化时运行,您可以指定必须从对象初始化时传递的参数。 参考狗 --> 颜色。

第一种方法和第二种方法之间的区别在于,在第二种方法的帮助下,您可以在调用任何方法之前强制新创建的对象具有一些默认值。

这样,我们可以避免在调用处理无值属性的方法时出错。

第一种方法的问题是a_cat没有name属性,除非您分配它。 在实用的 OOP(它是更多的范式而不是任何特定的语言实现,并且绝对可以在 Python 中“正确”完成)中,您希望同一类的对象具有相同的“协议”-一组属性和方法-这在编写时有很大帮助使用这些类的代码。 例如,如果您有一流的兽医使用类兽医的程序员不需要检查的每个实例,看看是否做它的东西,因为名字是协议的一部分,并且是永远存在之前就有的名字。

在 Python 中__init__()通常用于确保您的类的所有实例在实例化时都具有所有必需的属性,因此当他们的Vet类中的某个人执行if cat.name.startswith('A'):他们不会当在Cat 的特定实例中未设置name属性时,最终会出现AttributeError异常。

面向对象编程就是封装 当你定义一个对象时,你一些关于现实世界的知识封装到这个对象中。

封装就是禁止直接从外部世界操纵对象的内部状态。 并且通过“内部状态的操作”我的意思是直接修改对象属性,就像你的例子一样:

dog = Dog()
dog.name = 'Spot'

这与 OOP 试图实现的完全相反。

相反,OOP 建立了一个定义良好的模式:在创建对象时用初始状态初始化它。 所以,这就是构造函数的来源。 并且为了在创建对象时对其进行初始化,您需要将一些参数传递给构造函数。

这就是为什么“带参数的构造函数”方法总是优于“创建,然后分配属性”方法的原因。 更重要的是,在理想的世界中,每个对象在创建后都应该是不可变的,并且具有初始状态,并且只允许查询其状态并禁止更改它。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM