gpt4 book ai didi

Python:继承与组合

转载 作者:太空狗 更新时间:2023-10-29 17:40:22 49 4
gpt4 key购买 nike

我正在使用 Python 中的两个类,应该允许其中一个类将来自另一个类的任意数量的对象作为子对象,同时将这些子对象的 list 作为属性保留。对于这种父 <> 子情况,继承似乎是显而易见的选择,但我得到的是一个组合示例。这是简化的代码:

class Parent:
def __init__(self, firstname, lastname):
self.firstname = firstname
self.lastname = lastname
self.kids = []

def havechild(self, firstname):
print(self.firstname, "is having a child")
self.kids.append(Child(self, firstname))


class Child(Parent):
def __init__(self, parent, firstname):
self.parent = parent
self.firstname = firstname
self.lastname = parent.lastname

所以基本上,虽然让 Child() 继承自 Parent() 似乎具有直观意义,但删除继承根本不会改变任何东西。离开 Child(Parent) 而不仅仅是 class Child() 我能看到的唯一好处是,如果我需要向 Parent< 添加更多方法/em> 我希望 Child 继承。使用 self.parent = parent,我已经可以访问 Parent 的任何其他 future 属性。

是否有另一种方法可以使用纯继承而不是将 Parent 实例传递给 Child 构造函数(组合)?

最佳答案

从Parent继承Child或从Child继承Parent肯定是不好的。

正确的做法是创建一个基类,比方说 Person 并从中继承 Child 和 Parent。这样做的一个好处是消除代码重复,目前您只有名字/姓氏字段复制到两个对象中,但您可能有更多数据或其他方法,如 get_name() 可以使用这个数据。

这是一个例子:

class Person:
def __init__(self, firstname, lastname):
self.firstname = firstname
self.lastname = lastname

def get_name(self):
return f"{self.firstname} {self.lastname}"


class Parent(Person):
def __init__(self, firstname, lastname):
super().__init__(firstname, lastname)
self.kids = []

def havechild(self, firstname):
print(self.firstname, "is having a child")
self.kids.append(Child(self, firstname))


class Child(Person):
def __init__(self, parent, firstname):
super().__init__(firstname, parent.lastname)
self.parent = parent

另一种方法是不继承,但只有一个 Person 对象(相对于 Parent 和 Child)。跟踪家庭状况和 parent /子女的功能可以移到另一个对象中。

这种方法的一个优点是您遵循 single responsibility principle并保持对象简单,每个对象只做一件事。

这是一个例子:

from collections import defaultdict


class Person:
def __init__(self, firstname, lastname):
self.firstname = firstname
self.lastname = lastname

def get_name(self):
return f"{self.firstname} {self.lastname}"


class FamilyRegistry(object):
def __init__(self):
self.kids = defaultdict(list)

def register_birth(self, parent, child_name):
print(parent.firstname, "is having a child")
child = Person(child_name, parent.lastname)
self.kids[parent.lastname].append(child)
return child

def print_children(self, person):
children = self.kids[person.lastname]
if len(children) == 0:
print("{} has no children" % person.get_name())
return
for child in children:
print(child.get_name())

它是这样工作的:

joe = Person('Joe', 'Black')
jill = Person('Jill', 'White')
registry = FamilyRegistry()
registry.register_birth(joe, 'Joe Junior') # Joe is having a child
registry.register_birth(joe, 'Tina') # Joe is having a child
registry.print_children(joe) # Joe Junior Black
# Tina Black
registry.print_children(jill) # Jill White has no children

关于Python:继承与组合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20847727/

49 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com