У меня вопрос. Я изучаю Python и пытаюсь понять суперклассы, подклассы и иерархию между ними. У меня есть одна вещь, которую я не понял полностью. Я пытаюсь написать программу, где есть суперкласс класса "Человек" и подкласс "День рождения". Я определил метод init для обоих из них. Что я хочу сделать, я хочу создать экземпляр Person. В то же время он должен создать тот же экземпляр для Birthday.Because все люди имеют дни рождения :) И я хочу использовать методы, которые я определил в классе "День рождения". Код;
import datetime
class Person(object):
def __init__(self,name):
self.name=name
Birthday.__init__(self,name)
def gender(self,gender):
self.gender=gender
class Birthday(Person):
def __init__(self,name):
self.objectlike=[]
self.birthday=None
self.youget={}
def setbirth(self,year,month,day):
self.birthday=datetime.date(year,month,day)
def getbirth(self):
return self.birthday
def __str__(self):
return self.name
def setyouget(self,year,thing):
self.youget[year]=thing
def setlikeob(self,thing):
self.objectlike.append(thing)
def nextbirth(self):
thisyearbirth=getbirth().year.replace(year=datetime.date.today().year)
return thisyearbirth
def howlong(self):
return self.nextbirth()-datetime.date.today()
def getage(self):
age=datetime.date.today().year-self.birthday.year
return age
Проблема заключается в том, что я создаю экземпляр Person, например,
joey=Person('Joey Tribiani')
Затем я пытаюсь установить день рождения для joey;
joey.setbirth(1980,5,5)
В нем говорится: "Объект Person" не имеет атрибута "setbirth"
Как я могу решить эту проблему? Я думаю, что я должен добавить код для инициализации методы, но я не знаю, что add.I добавил "День рождения. INIT (я, имя)" для класса Person, но это не сработало.
(Кстати, это мой первый вопрос. Я прочитал много тем на этом сайте. Я поражен тем, насколько полезны люди, использующие его.)
На самом деле существует два аспекта наследования - субтипирование (семантическое) и наследование реализации (техническое).
Семантически, наследование описывает отношение "есть" - если B является подклассом A, тогда B "является" A (с некоторыми специализациями)), и вы должны иметь возможность использовать экземпляры A и B точно так же (это известен как Принцип замещения Лискова).
Технически, наследование ограничено видом композиции/делегирования (что семантически, "имеет" отношение) - подкласс имеет ссылку на его родительский класс, а методы (и другие атрибуты класса), не определенные в подклассе, просматриваются на родителя (и его родителя и т.д.). Это означает, что наследование также может использоваться для повторного использования кода ("наследование реализации"), в конечном итоге без уважения к принципу подписи Лискова ("наследование типа")
Обратите внимание, что в динамически типизированных языках, таких как Python, вам действительно не нужно наследование для подтипирования. У вас может быть класс B, который реализует тот же самый интерфейс, что и класс A, и поэтому является надлежащим подтипом в соответствии с Liskov - без наследования от A вообще и не имеет общего предка с A.
Теперь вернемся к вашему коду... Первая очевидная ошибка - сделать Birthday
подклассом Person
, поскольку день рождения, очевидно, не является человеком (семантически, отношения - это композиция: у человека есть день рождения). Вторая очевидная ошибка - когнитивная: похоже, что вы получаете отношения наследования неправильным образом. Если Birthday
наследуется от Person
тогда это класс Birthday
который получает доступ к методам Person
, а не наоборот.
Есть и другие очевидные проблемы, но они не имеют реального значения ATM. Сначала переосмыслите свой код с точки зрения "есть" (состав/делегирование), тогда пришло время решить эти проблемы.
В соответствии с введенным выше кодом Person is the Superclass
а Birthday is the Subclass
. Итак, это подкласс, который наследуется от суперкласса, а не наоборот.
Кроме того, Inheritance
является отношением is-a
. Отношение " Have/Has-A
соответствует composition
. Вы можете прочитать больше здесь.
Birthday
- это подклассPerson
?