[英]Python understanding OOP, inheritance
I solve this problem: 我解决了这个问题:
Develop an application which operates with next types: 开发一个适用于以下类型的应用程序:
Person
(field Name
, method ShowData()
) Person
(字段Name
,方法ShowData()
) Student
(field Education
) Student
(实地Education
) Worker
(field WorkPlace
) Worker
(场WorkPlace
) Classes Student
and Worker
are derived from class Person
. 类
Student
和Worker
派生自Person
类。
Class Academy
in it's container collects Students
and Workers
and shows Name
, Education
or WorkPlace
for all persons in method ShowAll()
. 类
Academy
在它的容器收集Students
和Workers
,并显示Name
, Education
或WorkPlace
中的方法所有人ShowAll()
We can add new persons to Academy
by calling method AddPerson()
. 我们可以通过调用方法
AddPerson()
将新人添加到Academy
。
Which hierarchy of classes is the best for solving this problem? 哪个类的层次结构最适合解决这个问题?
Code should include inheritance and use collections. 代码应包括继承和使用集合。
This is my solution, but i don't know how to realize method AddPerson
: 这是我的解决方案,但我不知道如何实现方法
AddPerson
:
class Academy(object):
theWholeList = []
@staticmethod
def showAll():
for obj in Academy.theWholeList:
if isinstance(obj,Student):
print obj.name+' - '+obj.edu
elif isinstance(obj,Worker):
print obj.name+' - '+obj.wplace
class Person(Academy):
def __init__(self,name):
self.name = name
super(Person, self).theWholeList.append(self)
def showData(self):
return vars(self)
class Student(Person):
def __init__(self, name, edu):
super(Student, self).__init__(name)
self.edu = edu
class Worker(Person):
def __init__(self, name, wplace):
super(Worker, self).__init__(name)
self.wplace = wplace
Maybe Academy
must inherit Person
and method AddPerson
will be like that: 也许
Academy
必须继承Person
和方法AddPerson
将是这样的:
def add(self,name):
super(Academy,self).__init__(name)
first thing: 第一件事:
class Academy(object):
theWholeList = []
@staticmethod
def showAll():
for obj in Academy.theWholeList:
if isinstance(obj,Student):
print obj.name+' - '+obj.edu
elif isinstance(obj,Worker):
print obj.name+' - '+obj.wplace
you do not need to have Academy
's method showAll()
be a static method, as on your design the Academy is legitimate to be a singleton, ie a class having a single instance. 你不需要
Academy
的方法showAll()
是一个静态的方法,因为在你的设计中,学院是合法的单身,即一个具有单个实例的类。
Also theWholeList
is a very bad name for a list. 此外,
theWholeList
是列表的一个非常糟糕的名称。 Because you know it is a list, as you're assigning it a list. 因为你知道它是一个列表,因为你要为它分配一个列表。 The name shall describe its semantic, ie the kind of things it contains, what it is used for.
名称应描述其语义,即它包含的东西的种类,它的用途。
You should rewrite it as follows: 你应该按如下方式重写它:
class Academy:
def __init__(self):
self.person_list = []
def show_all(self):
for item in self.person_list:
item.show_data()
And you would instanciate it once: 而且你会一次实现它:
academy = Academy() 学院=学院()
Then the following: 然后是以下内容:
class Person(Academy):
def __init__(self,name):
self.name = name
super(Person, self).theWholeList.append(self)
is bad design: in object oriented programming you should think about encapsulating data. 糟糕的设计:在面向对象的编程中,你应该考虑封装数据。 Here you're making the assumption that
Person
knows the internals of Academy
. 在这里,你正在做的假设
Person
知道的内部Academy
。 And what if you decide to change Academy
's implementation so theWholeList
is renamed? 如果您决定更改
Academy
的实现以便重命名theWholeList
,该怎么办? Or switched into a dict()
? 或者切换成
dict()
? This should be transparent to the "user" of the class Academy
. 这应该对班级
Academy
的“用户”透明。 A better design should be: 更好的设计应该是:
class Academy:
... # cf earlier
def add_person(self, person):
self.person_list.append(person)
class Person(Academy):
def __init__(self,name):
self.name = name
def show_data(self):
print("My name is: {}".format(name))
So you can use it as follows: 所以你可以按如下方式使用它:
person_a = Person("John Doe")
person_b = Person("Jim Smith")
academy.add_person(person_a)
academy.add_person(person_b)
And finally you're wondering: 最后你想知道:
Maybe Academy must inherit Person
也许学院必须继承人
Most of the time, subclassing is the wrong answer of a wrong question. 大多数时候,子类化是错误问题的错误答案。 You need to subclass when you want to extend or specialize behaviour of a class.
当您想要扩展或专门化类的行为时,您需要子类。 A classical example would be:
一个经典的例子是:
class Animal:
def noise(self):
raise NotImplementedError # virtual method
class Duck(Animal):
def noise(self):
print("quack")
class Cat(Animal):
def noise(self):
print("meaw")
So in your case, you have a class person that implements show_data, and what you want is to extend the behaviour, for worker and student: 所以在你的情况下,你有一个实现show_data的类人,你想要的是为工人和学生扩展行为:
class Worker(Person): # a worker _is_ a person!
def __init__(self, name, unit):
# left as an exercise to the OP
def show_data(self):
# left as an exercise to the OP
class Student(Person):
def __init__(self, name, promo):
# left as an exercise to the OP
def show_data(self):
# left as an exercise to the OP
I won't get into much more details here, as I suppose you have a teacher you can ask more about the comments I made. 我不会在这里得到更多细节,因为我想你有一位老师,你可以更多地询问我所做的评论。 But at least you tried, made some mistakes (AND MISTAKES ARE GOOD!).
但至少你试过,犯了一些错误(并且错误很好!)。 But I'm not giving you a full answer, my only goal here is to set you up in the right mind set to make your code a better design!
但是我没有给你一个完整的答案,我唯一的目标是让你在正确的思维定下让你的代码变得更好!
I hope this helps! 我希望这有帮助!
You want to be able to add people: 您希望能够添加人员:
>>> academy = Academy()
>>> academy.add(Person('Pete'))
>>> academy.showAll()
Name: Pete
>>> academy.add(Student('Taras', 'Higher'))
>>> academy.showAll()
Name: Pete
Name: Taras, Education: Higher
>>> academy.add(Worker('riotburn', 'StackOverflow')
>>> academy.showAll()
Name: Pete
Name: Taras, Education: Higher
Name: riotburn, Workplace: StackOverflow
showAll
needs to iterate over all people calling ShowData
on them. showAll
需要迭代调用ShowData
所有人。 This will be implemented differently for each type. 对于每种类型,这将以不同方式实现。
class Academy(object):
def __init__(self):
self.people = []
def add(self, person):
self.people.append(person)
def showAll(self):
for person in self.people:
person.ShowData()
Where for example, Worker
will implement ShowData
as: 例如,
Worker
将实现ShowData
:
def ShowData(self):
print 'Name: ' + self.name + ', Education:' + self.edu
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.