python中组合的实际用法

时间:2017-06-21 15:34:34

标签: python object-composition

我一直在阅读关于python中的构图,在关注了stackoverlow上的一些文章和答案之后,我想我能够 < em>如何实现 。但是我无法找到答案的一个问题是 为什么 组成? (而不是与继承的利益相比)。这是我从here得到的一个例子:

cellsPerColumnLimitFilter

我想通过一个小小的现实例子来理解它可以通过分离两个相关的课程来获益(并且有什么好处?

2 个答案:

答案 0 :(得分:2)

使用示例的扩展版

class Salary:
    def __init__(self,pay):
        self.pay=pay

    def get_total(self):
       return (self.pay*12)

    def increase(self):
        self.pay *= 1.1


class Employee:
    def __init__(self,pay,bonus):
        self.pay=pay
        self.bonus=bonus
        self.obj_salary=Salary(self.pay)

    def annual_salary(self):
        return "Total: "  +  str(self.obj_salary.get_total()+self.bonus)


obj_emp=Employee(100,10)
print (obj_emp.annual_salary())

调用employee.salary.increase比employee.increase

更有意义

如果你需要多个物品呢?你会继承其中一个或所有这些导致名称可能的名称冲突吗?

class Game:
    def __init__(self):
        self.screens       = [LoadingScreen, MapScreen]        
        self.player        = Player()
        self.display       = Display()
        self.stats         = Stats(self.display)
        self.screenIndex   = self.player.getScreen()
        self.currentScreen = self.screens[self.screenIndex]()
        self.run()

*编辑* 看了这个之后

but on looking it up again i find that increase could be renamed to increaseSalary so employee.increaseSalary() would make sense right?

您可以简单地将增加移动到员工类,但是如果您有一个Manager类或Boss类,则需要为每个类重复相同的代码

class Employee:
    def __init__(self,pay,bonus):
        self.pay=pay
        self.bonus=bonus

    def annual_salary(self):
        return "Total: "  +  str(self.obj_salary.get_total()+self.bonus)

    def increase_salary(self):
        self.pay *= 1.1


class Manager:
    def __init__(self,pay,bonus):
        self.pay=pay
        self.bonus=bonus

    def annual_salary(self):
        return "Total: "  +  str(self.obj_salary.get_total()+self.bonus)

    def increase_salary(self):
        self.pay *= 1.1

class Boss:
    def __init__(self,pay,bonus):
        self.pay=pay
        self.bonus=bonus

    def annual_salary(self):
        return "Total: "  +  str(self.obj_salary.get_total()+self.bonus)

    def increase_salary(self):
        self.pay *= 1.1

只有一次

class Salary:
    def __init__(self,pay):
        self.pay=pay

    def get_total(self):
       return (self.pay*12)

    def increase(self, addition):
        self.pay *= addition

您还可以使用类方法更轻松地查找平均值,最大值,最小值等

答案 1 :(得分:0)

好吧,即使我是一个菜鸟,我也会尝试一下。也可能有一些我缺席的点,但这是我想的方式,任何人,答案:

因为它为您提供了很大的灵活性,并且允许您撰写&#39;可能不一定具有父/子关系的对象(经典OOP中的对象称为IS-A类型继承)

例如,

说你有一个rifle课程。你想在其上添加(或撰写)attachments

你将如何继承?它不会非常灵活。

所以您可以做的是将附件定义为自己的类,比如sightmuzzle break类,然后将这些附件类的实例声明为rifle中的字段class和BAM现在可以访问sightmuzzle break中定义的方法,就像继承子类可以访问其超类方法一样。

无论如何要继续,你可以从这个例子中看到现在创建各种武器类是多么容易,比如howitzer,如果做得好,你可以声明sight的实例和muzzle break中的howitzer

请注意,我们创建的关系层次结构完全是平的。

要使用继承执行所有这些操作,您可以使用weaponsight中定义的相同方法定义基类,例如muzzle break。然后,您将创建分支到riflehowitzer的子类。

现在假设您不希望rifle拥有sight而只有scope。你必须通过基类中的所有这些箍和恶作剧来实现这一目标。

使用合成,您只需创建一个新类scope(实际上可以从sight继承),从sight中删除rifle的实例并插入scope的字段实例。请注意,howitzer没有进行任何更改。

尽管如此,我仍然认为继承是一种在适当的情况下被利用的有用工具,就像组合一样。