一直没有写技术博客的习惯,今年打算开始立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创建对象之后,调用构造方法进行初始化的准备工作。