笨办法学Python 习题 42: 对象、类、以及从属关系

笨办法学Python 习题 42: 对象、类、以及从属关系,第1张

概述笨办法学Python 习题 42: 对象、类、以及从属关系

有一个重要的概念你需要弄明白,那就是“类(class)”和“对象(object)”的区别。问题在于,class 和 object 并没有真正的不同。它们其实是同样的东西,只是在不同的时间名字不同罢了。我用禅语来解释一下吧:

鱼和三文鱼有什么区别?

这个问题有没有让你有点晕呢?说真的,坐下来想一分钟。我的意思是说,鱼和三文鱼是不一样,不过它们其实也是一样的是不是?三文鱼是鱼的一种,所以说没什么不同,不过三文鱼又有些特别,它和别的种类的鱼的确不一样,比如三文鱼和大比目鱼就不一样。所以三文鱼和鱼既相同又不同。怪了。

这个问题让人晕的原因是大部分人不会这样去思考问题,其实每个人都懂这一点,你无须去思考鱼和三文鱼的区别,因为你知道它们之间的关系。你知道三文鱼是鱼的一种,而且鱼还有别的种类,根本就没必要去思考这类问题。

让我们更进一步,假设你有一只水桶,里边有三条三文鱼。假设你的好人卡多到没地方用,于是你给它们分别取名叫Frank,Joe,和Mary。现在想想这个问题:

Mary和三文鱼有什么区别?

这个问题一样的奇怪,但比起鱼和三文鱼的问题来还好点。你知道Mary是一条三文鱼,所以他并没什么不同,他只是三文鱼的一个“实例(instance)”。Frank和Joe一样也是三文鱼的实例。我的意思是说,它们是由三文鱼创建出来的,而且代表着和三文鱼一样的属性。

所以我们的思维方式是(你可能会有点不习惯):鱼是一个“类(class)”,三文鱼是一个“类(class)”,而Mary是一个“对象(object)”。仔细想想,然后我再一点一点慢慢解释给你。

鱼是一个“类”,表示它不是一个真正的东西,而是一个用来描述具有同类属性的实例的概括性词汇。 你有鳍?你有鳔?你住在水里?好吧那你就是一条鱼。

后来河蟹养殖专家路过,看到你的水桶,于是告诉你:“小伙子,你这些鱼是三文鱼。” 并且专家还定义了一个新的叫做“三文鱼”的“类”,而这个“类”又有它特定的属性。长鼻子?浅红色的肉?生活在海洋里?吃起来味道还可以?那你就是一条三文鱼。

最后一个厨师过来了,他跟专家说:“非也非也,你看到的是三文鱼,我看到的是Mary,而且我要把Mary和剁椒配一起做一道小菜。”于是你就有了一只叫做Mary的三文鱼的“实例(instance)”(三文鱼也是鱼的一个“实例”),并且你使用了它,这样它就是一个“对象(object)”。

这会你应该了解了:Mary是三文鱼的成员,而三文鱼又是鱼的成员。这里的关系式:对象属于某个类,而某个类又属于另一个类。

写成代码是什么样子

这个概念有点绕,不过实话说,你只要在创建和使用 class 的时候 *** 心一下就可以了。我来给你两个区分 Class 和 Object 的小技巧。

首先针对类和对象,你需要学会两个说法,“is-a(是啥)”和“has-a(有啥)”。“是啥”要用在谈论“两者以类的关系互相关联”的时候,而“有啥”要用在“两者无共同点,仅是互为参照”的时候。

接下来,通读这段代码,将每一个注释为##?? 的位置标明他是“is-a”还是“has-a”的关系,并讲明白这个关系是什么。在代码的开始我还举了几个例子,所以你只要写剩下的就可以了。

记住,“是啥”指的是鱼和三文鱼的关系,而“有啥”指的是三文鱼和鳃的关系。

# -*- Coding:utf-8 -*-## Animal is-a object (yes, sort of confusing) look at the extra creditclass Animal(object):    pass## ??class Dog(Animal):    def __init__(self, name):        ## ??        self.name = name## ??class Cat(Animal):    def __init__(self, name):        ## ??        self.name = name## ??class Person(object):    def __init__(self, name):        ## ??        self.name = name        ## Person has-a pet of some kind        self.pet = None## ??class Employee(Person):    def __init__(self, name, salary):        ## ?? hmm what is this strange magic?        super(Employee, self).__init__(name)        ## ??        self.salary = salary## ??class Fish(object):    pass## ??class Salmon(Fish):    pass## ??class Halibut(Fish):    pass## rover is-a Dogrover = Dog("Rover")## ??satan = Cat("Satan")## ??mary = Person("Mary")## ??mary.pet = satan## ??frank = Employee("Frank", 120000)## ??frank.pet = rover## ??flipper = Fish()## ??crouse = Salmon()## ??harry = Halibut()关于 class name(object)

记得我曾经强迫让你使用class name(object) 却没告诉你为什么吧,现在你已经知道了“类”和“对象”的区别,我就可以告诉你原因了。如果我早告诉你的话,你可能会晕掉,也学不会这门技术了。

真正的原因是在 Python 早期,它对于class 的定义在很多方面都是严重有问题的。当他们承认这一点的时候已经太迟了,所以逼不得已,他们需要支持这种有问题的 class。为了解决已有的问题,他们需要引入一种“新类”,这样的话“旧类”还能继续使用,而你也有一个新的正确的类可以使用了。

这就用到了“类即是对象”的概念。他们决定用小写的“object”这个词作为一个类,让你在创建新类时从它继承下来。有点晕了吧?一个类从另一个类继承,而后者虽然是个类,但名字却叫“object”……不过在定义类的时候,别忘记要从 object 继承就好了。

的确如此。一个词的不同就让这个概念变得更难理解,让我不得不现在才讲给你。现在你可以试着去理解“一个是对象的类”这个概念了,如果你感兴趣的话。

不过我还是建议你别去理解了,干脆完全忘记旧格式和新格式类的区别吧,就假设 Python 的 class 永远都要求你加上 (object) 好了,你的脑力要留着思考更重要的问题。

附加题

1.研究一下为什么Python添加了这个奇怪的叫做object的类,它究竟有什么含义呢?

2.有没有办法把Class当作Object使用呢?

3.在习题中为 animals、fish、还有 people 添加一些函数,让它们做一些事情。看看当函数在 Animal 这样的“基类(base class)”里和在 Dog 里有什么区别。

4.找些别人的代码,理清里边的“是啥”和“有啥”的关系。

5.使用列表和字典创建一些新的一对应多的“has-many”的关系。

6.你认为会有一种“has-many”的关系吗?阅读一下关于“多重继承(multiple inheritance)”的资料,然后尽量避免这种用法。

常见问题

Q: 这些注释符## ??是干什么的?

这些是你需要完成的“填空”,你需要填上 "is-a"或者 "has-a"。再读一遍本节练习,看看其他的注释,弄明白我再说什么。

Q: self.pet = None是什么意思?

确保给self.pet设置了一个默认值None

Q: super(Employee,self).__init__(name)实现了什么?

这是用来执行父类的__init__方法的,上网搜索一下“python super”相关文档,阅读文档的各种建议。


总结

以上是内存溢出为你收集整理的笨办法学Python 习题 42: 对象、类、以及从属关系全部内容,希望文章能够帮你解决笨办法学Python 习题 42: 对象、类、以及从属关系所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1198394.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-03
下一篇 2022-06-03

发表评论

登录后才能评论

评论列表(0条)

保存