2015-09-09 3 views
1

я решить эту проблему:Python понимание ООП, наследование

разработать приложение, которое работает со следующими типами:

  1. Person (поле Name, метод ShowData())
  2. Student (поле Education)
  3. Worker (поле WorkPlace)

Классы Student и Worker получены из класса Person.

Класс Academy в это контейнер собирает Students и Workers и показывает Name, Education или WorkPlace для всех лиц, в методе ShowAll().

Мы можем добавить новое лицо в Academy путем вызова метода 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 

Может Academy должен унаследовать Person и метод AddPerson будет так:

def add(self,name): 
    super(Academy,self).__init__(name) 
+2

Похоже, домашнее задание, но я скажу, что showAll не должен быть статическим методом. – postelrich

+2

И снова это падение! Еще одна партия студентов изо всех сил пытается сделать домашнее задание на SO ;-) – zmo

ответ

2

первая вещь:

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 

вам не нужно иметь метод Academy «s showAll() быть статический метод, так как по вашему дизайну Академия является законным быть одиночным, то есть классом, имеющим один экземпляр.

Также theWholeList очень плохое имя для списка. Поскольку вы знаете, это список, так как вы назначаете ему список. Имя должно описывать его семантику, то есть то, что она содержит, для чего она используется.

Вы должны переписать его следующим образом:

class Academy: 
    def __init__(self): 
     self.person_list = [] 

    def show_all(self): 
     for item in self.person_list: 
      item.show_data() 

И вы бы создание экземпляра его однажды:

академии = Академия()

Тогда следующее:

class Person(Academy): 
    def __init__(self,name): 
     self.name = name 
     super(Person, self).theWholeList.append(self) 

является плохой дизайн: в объектно-ориентированном программировании вы должны думать об инкапсулировании данных. Здесь вы делаете предположение, что Person знает внутренности Academy. А что, если вы решите изменить реализацию Academy, так что theWholeList переименован? Или переключился на dict()? Это должно быть прозрачным для «пользователя» класса Academy. Лучший дизайн должен быть:

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)) 

Таким образом, вы можете использовать его следующим образом:

person_a = Person("John Doe") 
person_b = Person("Jim Smith") 
academy.add_person(person_a) 
academy.add_person(person_b) 

И, наконец, если вам интересно:

Может академия должна унаследовать Person

В большинстве случаев подклассификация является неправильным ответом на неправильный вопрос. Вам нужно подкласс, если вы хотите продлить или specialize поведение класса. Классическим примером может быть:

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") 

Так что в вашем случае, у вас есть класс человека, который реализует 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 здесь не будет более подробно, так как я полагаю, что у вас есть учитель, вы можете больше узнать о комментариях, которые я сделал. Но, по крайней мере, вы пробовали, допустили некоторые ошибки (И ОШИБКИ ХОРОШИЕ!). Но я не даю вам полного ответа, моя единственная цель состоит в том, чтобы настроить вас в правильном настроении, чтобы сделать ваш код лучшим дизайном!

Надеюсь, это поможет!

+0

Btw, имеющий Работника и Студента как подклассы Человека, также плохой дизайн; это роли, а не подтипы. На самом деле вы можете легко и сразу. –

+0

@peter Я очень согласен с тобой, но тогда нам, возможно, нужно будет сказать учителю ОП, что его упражнение глупо :-) И не все учителя так хорошо относятся к такой критике (да, я часто критиковал упражнения моего учителя, когда Я был в uni) – zmo

+0

Хорошо быть способным критиковать - это умение, как и любое другое. Говорить «Это глупый дизайн» для учителя тоже было бы глупо, но спрашивать: «Почему, по-вашему, так должно быть сделано?» или «Может ли это быть смоделировано таким образом вместо этого?» сильно меняет разговор. –

1

Вы хотите чтобы иметь возможность добавить людей:

>>> 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 необходимо перебирать всех людей, вызывающих ShowData на них. Это будет выполняться по-разному для каждого типа.

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() 

Где, например, Worker будет осуществлять ShowData как:

def ShowData(self): 
    print 'Name: ' + self.name + ', Education:' + self.edu 
Смежные вопросы