想知道为什么Python为实例方法固定添加self作为第一个参数,而Java却不这样做吗?
可以从两者在创建对象的初始化流程中的不同来分析原因。
Java
java的构造方法名与类名相同,子类对象创建时其初始化方法会依次调用超类的构造方法,而超类构造方法其实初始化的是超类的对象(而非子类的对象),因此一个子类对象内其实含有多个超类子对象。
由此带来了一个问题,超类的实例方法操作的还是超类子对象的属性,影响不到子类实例,那么如果子类的实例属性与超类的实例属性名字相同,则就会产生混乱。
下面这个例子就展示了,如果money这个属性存在与两个子对象中,而调用属于超类的方法打印其值,得到的是超类子对象的值。
public class Inheritance {
public static void main(String[] args) {
SubClass sub = new SubClass();
sub.showMoney();
}
}
class SuperClass {
int money;
SuperClass() {
money = 10;
}
void showMoney() {
System.out.println("money: " + money);
}
}
class SubClass extends SuperClass {
int money;
SubClass() {
money = 12;
}
}
结果
money: 10
python
python对象的初始化过程与java有很大的不同,python中实例属性都是在__init__方法中创建和初始化的,而所有的实例方法包括__init__在内其实都是以self为第一个参数的类方法/静态方法。self相当于java中的this。由于构造方法都叫"init",所以父类的会被覆盖,但是可以通过super类调用。
python在初始化对象时,不会为每个超类都进行初始化,即不会有多个self,而是由我们自己选择调用超类的__init__方法来初始化子类的self,所以只需要把子类的self依次传给超类的__init__方法,即可完成初始化。从始至终,只有一个对象被创建。所有继承自超类的实例方法,调用时都自动传给其self参数,从而使其操作这一个对象的属性。相比java而言,比较清晰,不容易混乱。
class SuperClass:
def __init__(self):
self.money = 10
def show_money(self):
print(self.money)
class SubClass(SuperClass):
def __init__(self):
super(SuperClass, self).__init__()
self.money = 12
if __name__ == '__main__':
sub = SubClass()
sub.show_money()
结果
money: 12