《通过艰难的方式学习Python》第二版。练习45
我正在学习《Learn Python the Hard Way》第二版,刚刚做完一个练习,要求我写出“是一个(is-a)”和“有一个(has-a)”的关系。我能用类,但对“是一个”和“有一个”这两个概念感到困惑。所以我不知道我做的是否正确,任何建议都会很感激。谢谢。
## Animal is-a object (yes, sort of confusing) look at the extra credit
class Animal(object):
pass
## ?? Dog is-a object
class Dog(Animal):
def __init__(self, name):
## ?? Dog has-a name
self.name = name
## ?? Cat is-a object
class Cat(Animal):
def __init__(self, name):
## ?? Cat has-a name
self.name = name
class Person(object):
def __init__(self, name):
## ?? Person has-a name
self.name = name
## Person has-a pet of some kind
self.pet = None
## ?? Employee is-a object
class Employee(Person):
def __init__(self, name, salary):
## ?? hmm what is this strange magic?
super(Employee, self).__init__(name)
## ?? Employee has-a salary
self.salary = salary
## ?? Fish is-a object
class Fish(object):
pass
## ?? Salmon is-a object, type of a fish
class Salmon(Fish):
pass
## ?? Halibut is-a object, type of a fish
class Halibut(Fish):
pass
## rover is-a Dog
rover = Dog("Rover")
## ?? satan is-a Cat
satan = Cat("Satan")
## ?? mary is-a person
mary = Person("Mary")
## ?? mary has-a pet called satan
mary.pet = satan
## ?? frank is-a Employee on 120000 salary
frank = Employee("Frank", 120000)
## ?? frank has-a pet called rover
frank.pet = rover
## ?? flipper is Fish
flipper = Fish()
## ?? crouse is-a Salmon
crouse = Salmon()
## ?? harry is-a Halibut
harry = Halibut()
4 个回答
基本上,你说的没错。你先建立一个基础类,比如说“鱼”(Fish),然后通过继承这个基础类,添加更多的细节和特性,这样就扩展了这个基础类。这就是你所说的“是一个”(is-a)关系。
比如说,员工(Employee)“是一个”人(Person),同时也“拥有一个”薪水(Salary)。薪水可以是一个单独定义的对象,一个人可能有,也可能没有。你甚至可以把这个薪水对象放到其他对象里,让它们也“拥有”这个薪水:
class AnimalActor(Dog):
def __init__(self, salary):
self.__salary = salary
s = Salary(50000)
lassie = AnimalActor(s)
比如“拉西”(lassie)“是一个”狗(Dog),同时也“拥有一个”薪水。
《艰难学Python》这本书对章节进行了调整,所以虽然以前这是第45个练习,现在变成了第42个练习。这一章讲的是“is-a”和“has-a”关系,之前我也搞不太明白。
根据我所了解的,这个问题在Stack Overflow上被认为是偏题的。不过,当我在网上寻找帮助时,这里是我找到答案的第一个地方之一,所以我就把我的答案加到这个问题里。我不太确定是否应该回答“糟糕”的问题,但我很确定我不是唯一一个在这个练习上挣扎的人;)
我的答案:
## Animal is-a object
class Animal(object):
pass
## Dog is-a Animal (Animal is-a Object, so Dog is-a Object as well.)
class Dog(Animal):
def __init__(self, name):
## Dog has-a name
self.name = name
## Cat is-a Animal (Animal is-a Object, so Cat is-a Object as well.)
class Cat(Animal):
def __init__(self, name):
## Cat has-a Name
self.name = name
## Person is-a Object
class Person(object):
def __init__(self, name):
## Person has-a name
self.name = name
## Person has-a pet of some kind
self.pet = None
## Employee is-a Person (and is-a Object, of course, everything is-a Object!)
class Employee(Person):
def __init__(self, name, salary):
## ?? This is a reliable way to call the
## __init__ method from Employee's 'super Class'
## Person (including name and pet)
super(Employee, self).__init__(name)
## Employee has-a salary
self.salary = salary
## Fish is-a Object
class Fish(object):
pass
## Salmon is-a Fish
class Salmon(Fish):
pass
## Halibut is-a Fish
class Halibut(Fish):
pass
## rover is-a Dog (with name 'Rover')
rover = Dog("Rover")
## satan is-a Cat (with name 'Satan')
satan = Cat("Satan")
## mary is-a Person (with name 'Mary')
mary = Person("Mary")
## mary has-a pet called satan.
mary.pet = satan
## frank is-a Employee with name "Frank" and salary 120000.
## Note: Because Employee is-a Person, frank falls under the
## Person class too.
frank = Employee("Frank", 120000)
## frank (the Employee from above) has a pet named rover. Since
## frank is-a Employee, which falls under (is-a) Person, this means
## he has-a pet as well.
frank.pet = rover
## flipper is-a Fish
flipper = Fish()
## course is-a Salmon
crouse = Salmon()
## harry is-a Halibut
harry = Halibut()
你已经很接近了。我记得我刚开始学习面向对象编程(OOP)的时候也很挣扎,尤其是在学了一些C语言之后。其实,面向对象编程比看起来要简单得多……这里唯一有点难的是第一个概念,就是你提到的……动物是一个对象。
虽然你说得对,狗、猫和员工都是对象,但更重要的是,它们分别是动物、动物和人。
这个练习其实是关于面向对象编程的一个特性,叫做继承。比如,狗的类层次结构是这样的:
对象 -> 动物 -> 狗
一只狗既是动物也是对象,它“拥有”这两者的所有属性。现在,这些属性可以在子类中被重写,但那是后面再讨论的内容。
我觉得你在“比目鱼”和“鲑鱼”那部分开始理解这个概念了。它们都是对象,也是鱼。
最后我想说的是:
弗兰克是一个员工(同时也是一个人和对象),他的名字是弗兰克,薪水是120000。
希望这些能帮到你。