1、概述
诚如各位所知,java的三大特性:封装、继承、多态。其中继承,是java中最有学问的一点也是最相对来说最难理解的一些东西,本文针对于此,做一些实例分析,希望能够帮助大家理解java中的继承机制
2、栗子
情况一:当父类和子类有同名同类型的属性时,使用时需要注意
public class Main {
public static void main(String[] args) {
Parent chidParent = new Child();
System.out.println("Parent:" + chidParent.getAge()); //40
System.out.println("Parent:" + chidParent.age); //18 这个结果你能接受吗?哈哈
Child child = Child.class.cast(chidParent);
System.out.println("Child:" + child.getAge()); //40
System.out.println("Child:" + child.age); //40
}
}
@Getter
@Setter
class Child extends Parent {
Integer age = 40; //名称和父类的同名
}
@Getter
@Setter
class Parent {
Integer age = 18;
}
我们发现,那个18为什么会输出出来呢?父类和子类的变量是同时存在的,即使是同名。子类中看到的是子类的变量,父类中看到的是父类中的变量,它们互相隐藏,而同名的方法则是实实在在的覆盖(重写),属性不存在重写哟。有了这个解释,就好理解了吧
情况二:当父类和子类有同名不同类型的属性时,使用时需要注意
public class Main {
public static void main(String[] args) {
// 报错Error:(20, 12) java: com.sayabc.boot2demo1.main.Child中的getAge()
// 无法覆盖com.sayabc.boot2demo1.main.Parent中的getAge()
// 返回类型java.lang.String与java.lang.Integer不兼容
Parent chidParent = new Child();
}
}
@Getter
class Child extends Parent {
String age = "40"; //名称和父类的同名
public void setAge(String age) {
this.age = age;
}
}
@Getter
class Parent {
Integer age = 18;
public void setAge(Integer age) {
this.age = age;
}
}
我们高兴的发现,如果类型不同,编译器还发现不了,但是一运行,就报错啦。这算编译器的bug吗?哈哈
情况三:继承中最基本的类加载顺序,不做过多解释。静态代码块只执行一次,并且优先于mai方法先执行
public class Main {
public static void main(String[] args) {
Parent chidParent = new Child();
}
}
@Getter
class Child extends Parent {
static {
System.out.println("Child的静态块");
}
{
System.out.println("Child的构造块");
}
Child() {
System.out.println("Child的构造方法");
}
}
@Getter
class Parent {
Integer age = 18;
static {
System.out.println("Parent的静态块");
}
{
System.out.println("Parent的构造块");
}
Parent() {
System.out.println("Parent的构造方法");
}
}
结果如下:
Parent的静态块
Child的静态块
Parent的构造块
Parent的构造方法
Child的构造块
Child的构造方法
备注:此处需要注意,此处子类没有显示调用super(),但父类的构造还是执行了的。但是,但是,但是,如果构造快为有参构造,请记得显示调用super方法,否则父类是不能被初始化的。如果子类的构造器没有显示地调用超类的构造器,则将自动调用超类默认(没有参数) 的构造器。如果超类没有不带参数的构造器,并且在子类的构造器又没有显式地调用超类的其他构造器,则 java 编译器将报告错误
情况四:子类和父类有同名同类型的静态常量的时候
public class Main {
public static void main(String[] args) {
Parent parent = new Child();
System.out.println(parent.name); //fangshixiangParent
Child child = new Child();
System.out.println(child.name); //fangshixiangChild
}
}
@Getter
@Setter
class Child extends Parent {
static String name = "fangshixiangChild";
}
@Getter
@Setter
class Parent {
static String name = "fangshixiangParent";
}
有了前面的基础,这个现象就很好解释了。同理:当有同名不同类型的属性时,直接获取属性还是会各自获取到自己的,但get方法就不行,就会报错了。
3、使用场景
各种设计模式,都会以此为依托,才能有更好的设计
4、最后
java的三大特性都非常的重要,如果不理解虚拟机对类的一些处理,有时候会犯迷糊,影响逻辑的设计,所以此文用简单用例希望能帮助大家理解。日后也许会持续更新
—-题后语—-
有任何问题,可以跟我留言讨论,欢迎指正,不胜感激。
有任何疑问,亦可扫码向我提我哟~