一直没有写技术博客的习惯,今年打算开始立flag,在博客这块每周写2篇。主要会把最近在学习的东西做一个总结、记录和反思,作为一个知识输出的途径,也提高一下写作的水平。
那么flag来了,一年52周,一周两篇,明年的元旦我应该可以看到自己写了100篇的博客???希望不要划水,把这件事做好。(这篇也算hhhhhhhhhh)
目前研究生刚刚毕业了,年后会去魔都入职做中台开发,分享的内容可能是工作上遇到的问题的复盘反思,专栏学习的经验总结,经典书籍当中比较有趣的问题等。
今天的主题是Java中的继承与Python的继承之间的区别
public class Test { public static void main(String[] args) { new A(); new B(); } } class A { int i = 7; public A() { setI(20); System.out.println("i from A is " + i); } public void setI(int i) { this.i = 2 * i; } } class B extends A { public B() { System.out.println("i from B is " + i); } public void setI(int i) { this.i = 3 * i; } }
A是B的父类,经过两次对象实例化后,它们i的值分别为多少?
首先在main方法里new了两个实例对象,一个A一个B。
new A();的结果很简单,在其构造函数A()里,将20作为参数传递给了setI,使其成员变量i从7变成了40,然后打印输出。
而new B();语句,由于B是A的父类,构造函数的调用顺序是 先调用父类的构造函数 ,这里setI方法在父类和子类中都有相应的定义,并且有相同的方法签名,属于 方法重写 。因此父类的构造函数里调用的是子类重写后的setI方法,将传递进来的参数扩大了3倍赋值给成员变量i。而这个成员变量i是在父类定义,子类继承过来的,属于同一个实例对象,因此后面两次打印输出i的内容保持一致。
输出结果是
i from A is 40 i from A is 60 i from B is 60
再来看一下python 中的继承
class Person(): def __init__(self, identity): print('Person class init called') self.identity = identity def print_grade(self): print(self.grade) class Student(Person): def __init__(self, name, grade): print('Student class init called') Person.__init__(self, 'student') self.name = name self.grade = grade s = Student('Adam','newbie') s.print_grade()
这里Person是Student的父类,类的构造方法由__init__来进行,这边跟java比较不一样的是
Person.__init__(self, 'student')
当我们把这行代码注释掉时,父类构造函数的打印输出消失了,但是其print_grade()方法还是可以正常使用。
因此这里的猜测是: Python中构造方法并不是构造对象的作用,而只是一个初始化的准备工作的作用。
那么Java呢?也是一样,在jvm创建对象之后,调用构造方法进行初始化的准备工作。