简体   繁体   English

哪种更好的继承方式?

[英]Which is the better way to inheritance?

Is there any difference between this: 之间有什么区别:

class Vehicle():
    def __init__(self,  x, y):
        self.y = y
        self.x = x

class Car(Vehicle):
    def __init__(self, x, y):
        Vehicle.__init__(self, x, y)

class Scooter(Vehicle):
    def __init__(self, x, y):
         Vehicle.__init__(self,  x, y)

and this: 和这个:

class Vehicle():
    def __init__(self,  x, y):
         self.y = y
         self.x = x

class Car(Vehicle):
         pass            

class Scooter(Vehicle):
         pass

Because without def __init__ in child classes I got the same thing, I mean __init__ doesn't provide any effect. 因为在子类中没有def __init__ ,我得到的是同一件事,我的意思是__init__不会提供任何效果。

You should't do either of them. 您都不应该这样做。 The best way to do it is using super . 最好的方法是使用super

class Vehicle():
    def __init__(self,  x, y):
        self.y = y
        self.x = x

class Car(Vehicle):
    def __init__(self, x, y):
        super(Car, self).__init__(x, y)
        # super().__init__(x, y) # for python3

Check this blog post by Raymond Hettinger (core python contributor) on why you should be using super 查看Raymond Hettinger(Python核心贡献者)的这篇博客文章,为什么您应该使用super

You need __init__ method when you want to do child specific initialisation. 要进行子级特定的初始化时,需要__init__方法。 Assume your child classes require another argument to be passed to the constructor and is unique to that class, in that case __init__ method is really required. 假设您的子类需要将另一个参数传递给构造函数,并且该参数对于该类是唯一的,在这种情况下,确实需要__init__方法。

class Vehicle():
    def __init__(self,  x, y):
        self.y = y
        self.x = x

class Car(Vehicle):
    def __init__(self, x, y, z):
        Vehicle.__init__(self, x, y)
        self.z = z

class Scooter(Vehicle):
    def __init__(self, x, y, z):
         Vehicle.__init__(self,  x, y)
         self.z = z

If you don't provide an __init__ method in the child classes, they will just use the __init__ method defined in their parent class (aka inheritance). 如果您未在子类中提供__init__方法,则它们将仅使用其父类(即继承)中定义的__init__方法。 In the former case, you are overriding the __init__ method for the child classes but you are simply calling the __init__ method of the parent class. 在前一种情况下,您将为子类覆盖__init__方法,但是您只是在调用父类的__init__方法。 So if you don't do that (like the later case) it will be the same. 因此,如果您不这样做(如后一种情况),它将是相同的。 The later case automatically inherits the __init__ method. 后一种情况会自动继承 __init__方法。

Other ways to write the same thing would be: 写同一件事的其他方法是:

class Car(Vehicle): #This is the best way to do it though
   def __init__(self, x, y):
      super()__init__(x, y)

Or 要么

class Car(Vehicle):
   def __init__(self, x, y):
      self.x = x
      self.y = y

TLDR; TLDR; They are equivalent. 它们是等效的。

I think this would be best explained with an example. 我认为最好用一个例子来解释。

Now take this scenario: 现在采取这种情况:

>Vehicle  ---> Car,Bike,Boat,Aeroplane,Train

>[All are vehicles right]

>Things they have in common would be (say for ex.) **Price** and **Color**

However things they won't have in common would be? 但是他们不会有共同点的是什么?

>**Wheels**. The total number of wheels may differ.
>

> Car-4 Bike-2 Boat-0 Aeroplane-(**Not sure**) Train-(**Many I
    guess**?)

But you get the point right? 但是你说对了吗? So When I want to just have a Vehicle object I don't want (or I can't tell the number of wheels ) In that case I can initialize only with just price and color 因此,当我只想要一个Vehicle对象时,我不需要(或者我不能说出车轮的数量),在这种情况下,我只能使用价格和颜色进行初始化

However when I know the specific type of Vehicle say Car now I can __init__ it with number of wheels . 但是,当我知道车辆的特定类型后,现在说“ 汽车”,就可以用车轮数__init__它。 Now this is where object specific initializations play a major role. 现在,这是对象特定的初始化起主要作用的地方。

A full example code of the above sample: 以上示例的完整示例代码:

class Vehicle():
    def __init__(self,  x, y):
        self.color = y
        self.price = x
    def Horn(self):
        print("Pommm...Pommmmm!!")

class Car(Vehicle):
    def __init__(self, x, y,wheel):
        Vehicle.__init__(self, x, y)
        self.wheel = "Four Wheels man: 4"

class Scooter(Vehicle):
    def __init__(self, x, y,wheel):
         Vehicle.__init__(self,  x, y)
         self.wheel = "Just Two man : 2"



VehObj = Vehicle("5000$","Black")
VehObj.Horn()
print(VehObj.color,VehObj.price)

#However note this

carObj = Car("5000$","Black",4)
print(carObj.color,carObj.price,carObj.wheel)

#Look at this

sObj = Scooter("5000$","Black",2)
print(sObj.color,sObj.price,sObj.wheel)

Output: 输出:

Pommm...Pommmmm!!
Black 5000$
Black 5000$ Four Wheels man: 4
Black 5000$ Just Two man : 2

Hope that cleared you up. 希望这能使您心情舒畅。

Calling the init method of super class is optional if you don't wont to edit the __init__ method of superclass. 如果您不想编辑超类的__init__方法,则调用超类的init方法是可选的。

but if you want to edit the superclass method you need custom init 但是,如果要编辑超类方法,则需要自定义init

class Vehicle():
    def __init__(self,  x, y):
        self.y = y
        self.x = x


class Car(Vehicle):
    def __init__(self, x, y, z):
        Vehicle.__init__(self, x, y)
        self.z = z

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

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