Python 哪种继承方式更好?
这两者之间有什么区别吗:Python 哪种继承方式更好?,python,inheritance,Python,Inheritance,这两者之间有什么区别吗: 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):
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)
这是:
class Vehicle():
def __init__(self, x, y):
self.y = y
self.x = x
class Car(Vehicle):
pass
class Scooter(Vehicle):
pass
因为在子类中没有
def\uuuuuuu init\uuuuu
我得到了同样的结果,我的意思是\uuuuuu init\uuuuu
不会提供任何效果。当您想要进行子类特定的初始化时,您需要\uuuuuuu init\uuuuuu
方法。假设您的子类需要将另一个参数传递给构造函数,并且该参数对于该类是唯一的,在这种情况下,确实需要使用\uuuu init\uuu
方法
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
当您想要执行特定于子级的初始化时,您需要
\uuuuu init\uuuu
方法。假设您的子类需要将另一个参数传递给构造函数,并且该参数对于该类是唯一的,在这种情况下,确实需要使用\uuuu init\uuu
方法
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
如果您不习惯编辑超类的
\uuuu init\uuu
方法,那么调用超类的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
如果您不习惯编辑超类的
\uuuu init\uuu
方法,那么调用超类的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
如果您没有在子类中提供
\uuuuuuu init\uuuuu
方法,则它们将只使用在其父类(也称继承)中定义的\uuuuuuuuu init\uuuu
方法。在前一种情况下,您正在覆盖子类的\uuuuuu init\uuuu
方法,但您只是在调用父类的\uuuuuuuu init\uuu
方法。因此,如果你不这样做(像后面的情况),它将是相同的。后一种情况会自动继承\uuuu init\uuu
方法
写同样东西的其他方法是:
class Car(Vehicle): #This is the best way to do it though
def __init__(self, x, y):
super()__init__(x, y)
或
TLDR;它们是等效的。如果在子类中不提供
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
方法,它们将只使用父类(也称继承)中定义的\uuuuuuuuuuuuu。在前一种情况下,您正在覆盖子类的\uuuuuu init\uuuu
方法,但您只是在调用父类的\uuuuuuuu init\uuu
方法。因此,如果你不这样做(像后面的情况),它将是相同的。后一种情况会自动继承\uuuu init\uuu
方法
写同样东西的其他方法是:
class Car(Vehicle): #This is the best way to do it though
def __init__(self, x, y):
super()__init__(x, y)
或
TLDR;它们是等价的。你不应该做它们中的任何一个。最好的方法是使用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
查看Raymond Hettinger(python核心贡献者)的博客文章,了解您为什么应该使用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
查看Raymond Hettinger(python核心贡献者)关于为什么要使用super
的博文,我认为最好用一个例子来解释这一点
现在,以这个场景为例:
>Vehicle ---> Car,Bike,Boat,Aeroplane,Train
>[All are vehicles right]
>Things they have in common would be (say for ex.) **Price** and **Color**
然而他们没有共同点的东西会是什么
>**Wheels**. The total number of wheels may differ.
>
> Car-4 Bike-2 Boat-0 Aeroplane-(**Not sure**) Train-(**Many I
guess**?)
但你说对了吗?因此,当我只想拥有一个车辆对象时,我不想要(或者我无法说出车轮的数量),在这种情况下,我只能用价格和颜色进行初始化
但是,当我知道车辆的具体类型时说汽车现在我可以\uuuu init\uuuuu
使用车轮数。这就是特定于对象的初始化所起的主要作用
以上示例的完整示例代码:
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)
输出:
Pommm...Pommmmm!!
Black 5000$
Black 5000$ Four Wheels man: 4
Black 5000$ Just Two man : 2
希望这能让你清醒过来。我想最好用一个例子来解释这一点
现在,以这个场景为例:
>Vehicle ---> Car,Bike,Boat,Aeroplane,Train
>[All are vehicles right]
>Things they have in common would be (say for ex.) **Price** and **Color**
然而他们没有共同点的东西会是什么
>**Wheels**. The total number of wheels may differ.
>
> Car-4 Bike-2 Boat-0 Aeroplane-(**Not sure**) Train-(**Many I
guess**?)
但你说对了吗?因此,当我只想拥有一个车辆对象时,我不想要(或者我无法说出车轮的数量),在这种情况下,我只能用价格和颜色进行初始化
但是,当我知道车辆的具体类型时说汽车现在我可以\uuuu init\uuuuu
使用车轮数。这就是特定于对象的初始化所起的主要作用
以上示例的完整示例代码:
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)
输出:
Pommm...Pommmmm!!
Black 5000$
Black 5000$ Four Wheels man: 4
Black 5000$ Just Two man : 2
希望这能帮你澄清。第二个不是绝对继承,因为这两个类都不能从外部访问。现在你改变了密码我想没有什么区别,因为在第一个示例中,您基本上是绕过类本身的init
,我更喜欢第一个版本,因为如果子类的\uuuuuu init\uuuu
方法与父类没有任何不同,那么您可以扩展\uuuuuu init\uuuuuu
-方法而不覆盖继承的代码,你的两个版本是等效的。在第一种情况下,如果调用Car(x,y)
,则调用Car
的方法并执行车辆。在第二种情况下,Car
没有定义一个\uuuuu init\uuuuu
,因此父类的\uuuuu init\uuuuu
被调用。第二种不是绝对继承,因为这两个类都不能从外部访问。现在你改变了密码我想没有什么区别,因为在第一个示例中,您基本上是绕过类本身的init
,我更喜欢第一个版本,因为如果子类的\uuuuuu init\uuuu
方法与父类没有任何不同,那么您可以扩展\uuuuuu init\uuuuuu
-方法而不覆盖继承的代码,你的两个版本是等效的。在第一种情况下,如果调用Car(x,y)
,则调用Car
的方法并执行车辆。在第二种情况下,Car
没有定义一个\uuuuu init\uuuu
,因此会调用父级的\uuuuu init\uuuu
。