我想启动一个子类的多个实例,每个实例都从一个类的特定实例而不是常规类获取其属性。
例如,如果我有建筑物和房间,则每个房间都必须属于建筑物的特定实例,并考虑其属性和方法。
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
继承Building
?1个
还有就是房间和建筑物之间的关系:每个房间是在建筑物和每一个建筑包含零个或多个房间。你可以表示的关系,或两者,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
。然后,对于每一个Room
在Building
其self.building.location
现在new_location
。
另外,您通常不希望aRoom
支持a的方法Building
。调用Evacuate_Building
aRoom
没有多大意义。Evacuate_Room
可能会打电话。在这种情况下,您Building
可能会执行以下操作:
def Evacuate_Building(self):
for room in self.rooms:
room.Evacuate_Room()
但是,如果你发现一个Room
着火,因此,你需要撤离整座Building
即Room
是,包括所有的房间?简单:您可以撤消Room
的building
属性:
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] 删除。
我来说两句