Exercise 42: is-a ,has-a ,对象和类

本文通过生动的例子解释了Python中Class与Object的概念及其关系,帮助读者理解如何使用Class创建Object,以及它们之间的is-a和has-a关系。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

原文链接:http://learnpythonthehardway.org/book/ex42.html

       区别class和object的一个你需要理解的重要概念。但是问题是,在 class和 object之间并没有什么真正的“不同“ .它们在不同的时间点上实际是一样的东西。 我记得一句禅语是这样说的:鱼和泥鳅有什么区别呢?

        这个问题是不是让你有点迷惑了?坐下来好好思考一会儿。我的意思是说泥鳅和鱼是不同的,但是,它们其实也是一样的东西,不对吗?泥鳅是鱼的一种 ,从这点上来说它们没有不同。但是与此同时,因为泥鳅是鱼类中一种特殊的种类,它实际上和其他鱼是不同的。就是说泥鳅不能说成是黄鳝。所以泥鳅和鱼既相同也不相同。这真是太别扭了。

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

        让我们更进一步,假设你有一只水桶,里边有三条泥鳅。假设你好到你决定给它们分别取名叫弗兰克 ,乔伊,玛丽。现在想想这个问题:玛丽和泥鳅之间有什么不同?

        这又是一个奇怪的问题,但是还是比鱼和泥鳅的比较问题简单一些。你知道玛丽就是一条泥鳅,所以并没有什么真正的不同,她只是泥鳅的一个特殊“实例”。乔伊和弗兰克也一样是泥鳅的实例。我的意思是说,它们是由泥鳅创建出来的,而且代表着泥鳅一样的属性。

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

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

        后来河蟹养殖专家路过,看到你的水桶,于是告诉你:“小伙子,你这些鱼是泥鳅。” 专家一出,真相即现。并且专家还定义了一个新的叫做“泥鳅”的“类”,而这个“类”又有它特定的属性。细长条?有胡须?爱钻泥巴?吃起来味道还可以?那你就是一条泥鳅。

        最后家庭煮父过来了,他跟河蟹专家说:“非也非也,你看到的是泥鳅,我看到的是玛丽,而且我要把小方和剁椒配一起做一道小菜。”于是你就有了一只叫做玛丽的泥鳅的“实例(instance)”(泥鳅也是鱼的一个“实例”),并且你使用了它(把它塞到你的胃里了),这样它就是一个“对象(object)”。

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

写成代码是什么样子

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

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

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

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

## Animal is-a object (yes ,sort of confusing) look at the extra credit
class Animal(object):
	pass


## is-a
class Dog(Animal):
	def __init__self(self ,name):
		## has-a
		self.name = name
	


## is-a
class Cat(Animal):
	def __init__(self ,name):
		## has-a
		self.name = name
	


## is-a
class Person(object):
	def __init__(self ,name):
		## has-a
		self.name = name


		## Person has-a pet of some kind
		self.pet = None


## is-a
class Employee(Person):
	def __init__(self ,name ,salary):
		##  hmm what is this strange magic
		supper(Employ ,self).__init___(name)
		## has-a
		self.salary = salary


## is-a
class Fish(object):
	pass


## is-a
class Salmon(Fish):
	pass


## is-a
class Halibut(Fish):
	pass


## rover is-a Dog
rover = Dog("Rover")


## satan is-a Cat
satan = Cat("Satan")


##marry is-a Person
mary = Person("Mary")


## mary has-a pet
mary.pet = satan


## is-a
frank = Empolyee("Frank" ,120000)


## has-a
frank.pet = rover


## is-a
flipper = Fish()


## is-a
crouse = Salmon()

关于 class Name(object)

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

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

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

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

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


研究训练:

1、研究一下为什么 Python 添加了这个奇怪的叫做 object 的 class,它究竟有什么含义呢?
2、有没有办法把 Class 当作 Object 使用呢?
3、在习题中为 animals、fish、还有 people 添加一些函数,让它们做一些事情。看看当函数在 Animal 这样的“基类(base class)”里和在 Dog 里有什么区别。
4、找些别人的代码,理清里边的“是啥”和“有啥”的关系。
5、使用列表和字典创建一些新的一对应多的“has-many”的关系。
6、你认为会有一种“has-many”的关系吗?阅读一下关于“多重继承(multiple inheritance)”的资料,然后尽量避免这种用法。


学生遇见的常见问题:

##??这些注释是做什么用的?

答:这些是”填空题“注释你应该在其所在的位置填上正确的”is-a",“has-a”的概念。重新阅读一下这个练习看看其他注释就明白我说的什么意思了。

self.pet = None是什么作用?

答:就是让其所在的类的self.pet属性默认为None值。

supper(Employee ,self).__init__(name)做什么操作?

答:这是让你可以有效的运行父类中的__init__函数。去搜索关于“python supper”阅读其避免使用时误入陷阱和更好使用它的各种建议。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值