从实例继承,而不是从类继承[Python 3]

伍迪

我想启动一个子类的多个实例,每个实例都从一个类的特定实例而不是常规类获取其属性。

例如,如果我有建筑物和房间,则每个房间都必须属于建筑物的特定实例,并考虑其属性和方法。

class Building:
     def __init__(self, buildingName, location):
        self.buildingName = buildingName
        self.location = location
        # lots more intersting stuff

    def Evacuate_Building(self):
        # do some stuff
        pass

class Room(Building):
     def __init__(self, roomName, roomType):
        self.roomName = roomName
        self.roomType = roomType
        # lots more intersting stuff

    def Directions(self, Current_Location):
        '''do some stuff involving this.roomName and this.location which comes from the specific instance of the class'''
        pass

假设我有三座建筑:“北”,“南”和“西”。

每个建筑都有自己的房间。

仅看北楼,就有房间“ N1”,“ N2”,“ N3”,“ N4”。

在我的代码中,我将首先浏览并启动三个建筑物,然后启动房间,并通过一些方法将它们链接回其相应的建筑物。

这使我可以使用Directions方法,该方法从其父类实例中提取属性位置,该属性是该Building所独有的,而不是常规值。它还需要能够使用父类Evacuate_Building中的方法。

我可以通过每次使用super(buildingName,location)或Building .__ init __(self,buildingName,location)在更标准的设置中初始化房间来传递位置数据来解决此问题,但是这意味着我必须为每个单房间,如果我在建筑物中添加或更改某些内容,则需要更改每个单房间的初始化和初始化代码(如果已添加其他属性)。

我也可以通过将Building的实例作为参数传递给init,然后进行this.location = building.location来复制属性,但这也具有与上述相同的问题,而且我没有这种方法。

我希望通过某种方式传递建筑物的特定实例,以便房间继承其特定属性和方法。

欢迎任何反馈,建议,批评,完全不同的方法!先感谢您!

阿巴内特

您的设计很奇怪。房间不是建筑物,为什么要Room继承Building1个

还有就是房间和建筑物之间的关系:每个房间是在建筑物和每一个建筑包含零个或多个房间。你可以表示的关系,或两者,2组合物, -即通过添加成员:

class Room:
    def __init__(self, building, roomName, roomType):
        self.building = building
        self.roomName = roomName
        self.roomType = roomType
        # lots more intersting stuff

要么:

class Building:
    def __init__(self, buildingName, location):
        self.buildingName = buildingName
        self.location = location
        self.rooms = set()
    def add(self, room):
        self.rooms.add(room)

如果需要,您甚至可以Room.__init__拨打电话building.add(self)


请注意,这恰好为您提供了所需的内容:每个对象Room都与一个特定的Building实例self.building,而不是与Building该类相关。

因此,您不必为每个单一位置编写位置Room,只需将同一Building实例传递给所有位置。而且,如果我在中添加或更改某项内容,则该建筑物中的Building每个人都Room将看到其中的更改,self.building而无需重复自己或做任何特殊的事情。

甚至不仅仅是静态地在代码中。您可以使用Building运行时移动self.location = new_location然后,对于每一个RoomBuildingself.building.location现在new_location


另外,您通常不希望aRoom支持a的方法Building调用Evacuate_BuildingaRoom没有多大意义。Evacuate_Room可能会打电话在这种情况下,您Building可能会执行以下操作:

def Evacuate_Building(self):
    for room in self.rooms:
        room.Evacuate_Room()

但是,如果你发现一个Room着火,因此,你需要撤离整座BuildingRoom是,包括所有的房间?简单:您可以撤消Roombuilding属性:

if is_on_fire(room):
    room.building.Evacutate_Building()

1.这就是继承的含义:class Room(Building):表示anyRoom是一个Building或者,换种说法:任何需要aBuilding并得到a的代码Room都会对此感到满意。有时有理由颠覆这种含义(例如,mixin类只是一大堆方法实现;如果编写class Skyscraper(Building, MajorConstructionMixin):,实际上并没有在声明aSkyscraper是a,MajorConstructionMixin因为这并不意味着什么;您只是在借用一些方便的实现代码),但这仍然是您所颠覆的含义。

2.请注意,如果在两个方向上都添加引用,则会有一个引用循环。这不是非法的,甚至通常不是问题;这仅意味着当您放弃建筑物及其所有房间时,CPython垃圾收集器将不会找到它们并将其立即删除,直到下一次收集器运行为止。虽然这没什么大不了的,但是大多数程序并不需要双向的关系,因此您应该查看是否可以通过消除一个来简化设计。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章