简体   繁体   English

令人困惑的Python OOP继承

[英]Confusing Python OOP-Inheritance

I am new to Python language. 我是Python语言的新手。 I have only 10 days experience on it. 我只有10天的经验。 When I start learning there is no difficult, but it make me slow down when I reach "Object Oriented Concept", especially "Inherited". 当我开始学习时,没有困难,但是当我达到“面向对象的概念”,尤其是“继承的”时,这会使我放慢速度。

Some of my background knowledge about "Inherited is the child class can get all of characteristic and behavior of parent class, in other words - data and methods of parent". 我的一些有关“继承是子类的背景知识,可以获取父类的所有特征和行为,换句话说-父类的数据和方法”。 Ok, I am going to show the concept that make me confuse with two programs. 好的,我将展示使我与两个程序混淆的概念。 Both of them are getting the same result, so why people are making different. 他们两个都得到相同的结果,所以人们为什么有所不同。

First: 第一:

class Parent():    
    parentdata = 0    
    def __init__(self):        
        pass    
    def getParentData(self):
        return Parent.parentdata
    def setParentData(self, setdata):
        Parent.parentdata = setdata



class Child(Parent):
    childdata = 0
    def __init__(self):
        pass
    def getChildData(self):
        return Child.childdata
    def setChildData(self, setdata):
        Child.childdata = setdata


child = Child()
print "Default Child's Data is :" + str(child.getChildData())#getting 0
child.setChildData(3)
print "After Adding Child's Data is :"+ str(child.getChildData()) # getting 3
print "Default Parent's Data is:"+ str(child.getParentData())# getting 0
child.setParentData(1)
print "After Adding Parent's Data is :"+str(child.getParentData())# getting 1

Second: 第二:

class Parent():
    parentdata = 0
    def __init__(self):
        pass
    def getParentData(self):
        return Parent.parentdata
    def setParentData(self, setdata):
        Parent.parentdata = setdata

class Child(Parent):
    childdata = 0
    def __init__(self):
        #super(Child, self).__init__()
        #super(Child, self).__init__(self, self)
        Parent.__init__(self)
    def getChildData(self):
        return Child.childdata
    def setChildData(self, setdata):
        Child.childdata = setdata
child = Child()
print "Default Child's Data is :" + str(child.getChildData())#getting 0
child.setChildData(3)
print "After Adding Child's Data is :"+ str(child.getChildData()) # getting 3
print "Default Parent's Data is:"+ str(child.getParentData())# getting 0
child.setParentData(1)
print "After Adding Parent's Data is :"+str(child.getParentData())# getting 1

And please also guide me, how to use Super() method for instance of Parent.__init__(self) Somebody used, Super method in there and some are doing as my way.I am not clearly these two different. 并且还请引导我,如何使用Super()方法作为Parent.__init__(self)实例。有人使用了,其中的Super方法正在执行,有些是我的方法。我不清楚这两个不同之处。

In these two program - I am not using __init__ as constructor. 在这两个程序中-我没有使用__init__作为构造函数。 If I am going to use __init__ as to add data into the class's data(childdata,parentdata), how do I insert parameter in Parent.__init__(self) and both of their def __init__(self): method? 如果要使用__init__将数据添加到类的数据(childdata,parentdata)中,如何在Parent.__init__(self)和它们的def __init__(self):方法中插入参数?

Your example seems to be behaving as expected. 您的示例似乎表现出预期。 You have set up both classes with class level data -- that is, every Parent will be sharing the same value of parentData and every child will be sharing the same value of childData. 您已经使用类级别的数据设置了两个类,也就是说,每个Parent将共享相同的parentData值,而每个孩子将共享相同的childData值。 Since your method names are not shared, your 'Child' instance will behave independently of 'Parent' except that calling setParentData on a Child will push the value into the state of all parents -- but NOT of all children. 因为你的方法名称不共享的,你的“孩子”的实例将独立“父”的行为除了对孩子,调用setParentData将值推到所有家长的状态-但不是所有的孩子。

The more common example would look like this: 更常见的示例如下所示:

class Parent(object):
     shared_state = 0

     def __init__(self):
         self.private_state = 1

     def get_shared(self):
         return self.shared_state

     def get_private(self)
         return self.private_state

class Child(Parent):
    shared_state = 2

    def __init__(self):
        Parent.__init__(self)
        self.private_state = 3 
        #in this case calling the Parent constructor is not really needed but it's good practice


 p = Parent()
 p.get_shared()
 > 0
 p.get_private()
 > 1

 new_p = Parent()
 new_p.get_shared()
 > 0


 c = Child()
 c.get_shared()
 > 2
 c.get_private()
 > 3

In this example all the parents share the variable 'shared_state' -- but each has it's own copy of private_state independent of the other Parents. 在此示例中,所有父级都共享变量“ shared_state”,但是每个父级都具有独立于其他父级的自己的private_state副本。 Likewise each Child shares a copy of Child's shared_state -- which is different from Parent's shared state. 同样,每个孩子共享一个孩子的shared_state的副本-与父对象的共享状态不同。

Essntially when the same name (for a class variable like shared_state) or a method (like get_private or get_shared) appears in a child class, the it overrides the original version. 实质上,当子类中出现相同的名称(对于诸如shared_state之类的类变量)或方法(诸如get_private或get_shared之类)时,它将覆盖原始版本。 That's why calling get_shared() on a Child returns 2, which is Child.shared_state. 这就是为什么在Child上调用get_shared()返回2的原因,即Child.shared_state。 In your original code you explicitly called Parent.parentData from Chold so you got the value from Parent. 在您的原始代码中,您从Chold显式调用了Parent.parentData,因此您从Parent获得了值。

The core idea behind imheritance is to make it easy to share common functionality and only write new classes or methods for what is specific to a particular need: 继承性的核心思想是使共享功能易于共享,并且仅针对特定需求编写新的类或方法:

class Vehicle(object):
    def __init__(self, name, passengers):
       self.Passengers = passengers
       self.Name = name

    def go(self):
       print "%n is going with  %i passengers" % (self.Name, self.Passengers)

    def get_name(self):
       print self.Name

class Car(Vehicle):
    def go(self):
       print "%n is driving along with  %i passengers" % (self.Name, self.Passengers)

class Boat(Vehicle):
    def go(self):
       print "%n is sailing along with  %i passengers" % (self.Name, self.Passengers)

class Truck(Car):
    def deliver(self):
        print "%n is delivering cargo" % self.Name

Here the subclasses can all 'go' but they do it in different ways -- the nice thing is that code using them doesn't need to know what they are, it just calls go on them and they go in their own ways. 在这里,所有子类都可以“执行”,但是它们以不同的方式执行-令人高兴的是,使用它们的代码不需要知道它们是什么,只需调用它们,它们就以自己的方式运行。 The Truck 'goes' like a car and has a method for doing deliveries as well which the Boat and Car don't have. 卡车像汽车一样“行驶”,并且具有船和船所没有的交货方法。 All of the classes share the 'get_name' method so it does not have to be rewritten -- it's there for free in all derived classes. 所有类都共享“ get_name”方法,因此不必重写-所有派生类中都免费提供该方法。 So as you see you can share functions and data, replace them with different functions or data that have the same names (so outside code can get at them the same way) or add new functions and data. 因此,如您所见,您可以共享功能和数据,将它们替换为具有相同名称的其他功能或数据(以便外部代码可以以相同的方式获取它们)或添加新的功能和数据。

You might want to check out Head First Python for a more thorough intro to these ideas. 您可能想查看Head First Python ,以获得有关这些想法的更全面介绍。 And of course there's a lot here on SO. 当然,SO上有很多内容。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM