找工作的大四狗,心情很烦。抱怨之后进入今天的主题:Java中的继承。
提到Java中的继承,我突然好想吐槽Oracle的脑洞,在Java8中接口方法可以用default修饰然后加方法体,Java9中就可以用private修饰了(当然9现在已经灭绝了)。搞不懂这波操作。。。
接着说继承,先说一下子类和父类的初始化顺序:首先排在第一位的当然就是父类的静态代码块了,毕竟人家是父类而且在类加载的时候就执行了,然后子类的静态代码块紧随其后,正应了一句“上阵父子兵”啊!然后如果实例化子类的话,就是父类的构造代码块和构造函数,子类的构造代码块和构造函数。可能会有人好奇,我明明实例化的子类对象,父类你掺和进来干嘛?安啦,既然你没有显式的说出来,那只能是人家隐式的表达了:在每个构造函数的第一句,都为你默默加上了一句super()哦!这时候就要小心了,子类带参数的构造函数第一句是不是super(参数)呢?当然不是的,因为每个类都默认为你提供不带参的构造函数,所以人家只能向你提供自己定义的空参构造函数。就是这个样子
class A{
public A(){
System.out.println("A");
}
}
class B extends A{
public B(int i) {
// super(); 这里是默认提供的
System.out.println("B");
}
}
public class Main {
public static void main(String[] args) {
new B(2);
}
}
那么有人就是想要调用父类带参的构造方法,呵呵,不惯你这毛病,自己手动定义去!不过这里还需要注意一点,如果自己定义了带参数的构造函数,那么顺带着把不带参的构造函数也写了吧!不然你很容易遇到这样那样的毛病,比如这样
class B {
public B(int i) {
System.out.println("B");
}
}
public class Main {
public static void main(String[] args) {
new B();
}
}
很明显,这是一个错误的示例。所以说Java还是很傲娇的。。
还有就是父类中的私有成员变量,emmm,怎么说呢?并不是没有继承过来,只不过不能直接用而已。就好像XX的爸爸妈妈给了ta一个小盒子,但是ta没有钥匙,所以ta就不能用盒子里面的东西了。但是人家是有的,验证如下
class A{
private int i;
public int getI() {
return i;
}
public void setI(int i) {
this.i = i;
}
}
class B extends A{}
public class Main {
public static void main(String[] args) {
B b=new B();
b.setI(3);
System.out.println(b.getI()); //3
}
}
汗!这么紧凑的写法不是一个优秀程序猿的作风。
然后就是方法的重写,主要就是遵循以下原则:方法名相同,参数类型相同;子类返回类型小于等于父类方法返回类型;子类抛出异常小于等于父类方法抛出异常;子类访问权限大于等于父类方法访问权限。这些都算是多态能够存在的必要条件吧。