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对象的初始化过程与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