这里有2个类
父类 Father
public class Father {
public static int fa =1;
private static int fb =2;
protected static int fc =3;
static int fd =4;
public int a = 1;
private int b = 2;
protected int c = 3;
int d = 4;
public int getB() {
return b;
}
public void setB(int b) {
this.b = b;
}
public Father() {
System.out.println("i am father constructor");
}
public void haha(){
System.out.println("father haha");
}
public static void hehe (){
System.out.println("father hehe");
}
}
子类 Son
public class Son extends Father {
public static int fa =5;
private static int fb =6;
protected static int fc =7;
static int fd =8;
public int a = 5;
private int b = 6;
protected int c = 7;
int d = 8;
public Son(int a) {
this.a = a;
System.out.println("defined son's constructor");
}
public Son() {
//会默认执行父类的无参构造器
System.out.println("son's constructor");
}
@Override
public void haha() {
System.out.println("son haha");
}
public static void hehe (){
System.out.println("son hehe");
}
public void getFatherFiled(){
System.out.println("---------------获取Father的静态字段---------------");
System.out.println("Father static int1 " + super.fa);
System.out.println("Father static int2 =====> 这里 为Father's private static int fb" );
System.out.println("Father static int3 " `这里写代码片`+ super.fc);
System.out.println("Father static int4 " + super.fd);
System.out.println("---------------获取Son的静态字段---------------");
System.out.println("Son static int1 " + fa);
System.out.println("Son static int2 " + fb);
System.out.println("Son static int3 " + fc);
System.out.println("Son static int4 " + fd);
System.out.println("---------------获取Father的非静态字段---------------");
System.out.println("Father int1 " + super.a);
System.out.println("Father int2 " + super.getB());
System.out.println("Father int3 " + super.c);
System.out.println("Father int4 " + super.d);
System.out.println("---------------获取Son的非静态字段---------------");
System.out.println("Son int1 " + a);
System.out.println("Son int2 " + b);
System.out.println("Son int3 " + c);
System.out.println("Son int4 " + d);
System.out.println("----------------------调用父类的静态方法-------------------------");
super.hehe();
System.out.println("----------------------调用父类的非静态方法-------------------------");
super.haha();
System.out.println("----------------------调用自己的静态方法-------------------------");
hehe();//this.hehe();会有黄线警告 静态方法 不推荐这种调用
System.out.println("----------------------调用自己的非静态方法-------------------------");
haha();//this.haha()
}
}
测试类
public class Test {
public static void main(String[] args) {
Father fa = new Son();//会默认执行父类的无参构造器
//Father fa = new Son(1);会默认执行父类的无参构造器
//静态绑定 输出实例变量
System.out.println("-----------输出实例变量-----------");
System.out.println(fa.a);
System.out.println(fa.getB());
System.out.println(fa.c);
System.out.println(fa.d);
System.out.println("-------------静态变量--------------");
//输出静态字段
System.out.println(fa.fa);
System.out.println(fa.fc);
System.out.println(fa.fd);
//动态绑定 对于非静态方法
fa.haha();
//这里相当于调用了Father.hehe();
fa.hehe();//因此输出为father hehe 而不是son hehe;
System.out.println("------------son获取所有父类以及自己的变量------------");
((Son)fa).getFatherFiled();
}
}
结果:
i am father constructor
son's constructor
-----------输出实例变量-----------
1
2
3
4
-------------静态变量--------------
1
3
4
son haha
father hehe
------------son获取所有父类以及自己的变量------------
---------------获取Father的静态字段---------------
Father static int1 1
Father static int2 =====> 这里 为Father's private static int fb
Father static int3 3
Father static int4 4
---------------获取Son的静态字段---------------
Son static int1 5
Son static int2 6
Son static int3 7
Son static int4 8
---------------获取Father的非静态字段---------------
Father int1 1
Father int2 2
Father int3 3
Father int4 4
---------------获取Son的非静态字段---------------
Son int1 5
Son int2 6
Son int3 7
Son int4 8
----------------------调用父类的静态方法-------------------------
father hehe
----------------------调用父类的非静态方法-------------------------
father haha
----------------------调用自己的静态方法-------------------------
son hehe
----------------------调用自己的非静态方法-------------------------
son haha
结论:
1.子类继承父类 会继承父类中的所有(包括父类的静态方法,静态变量,实例方法,实例变量(非静态)) 即:在子类进行实例化的时候 会有一份父类的引用,这里为super。可以在子类中使用获取父类中的方法和字段。
2.子类可以直接访问父类中的非private 字段和方法 (包括静态和非静态)
3.子类可以重载这些方法 包括父类中的构造方法,但是覆盖的构造方法依然会执行父类的无参构造器(默认)
4.静态绑定:在构造一个子类的实例并向上转型为其父类的时候,利用父类的引用获取的字段 是 父类中的字段 (静态和非静态)。
5.但是调用的方法(这里要强调是实例方法) 是子类中覆盖的方法! (若用父类的引用去调用静态方法 那么还是调用了原来父类中的方法。(当然不推荐这么做 你的编译器会有黄线,你应该用类.方法去调用你父类中的静态方法))。
上述 “但是调用的方法(这里要强调是实例方法) 是子类中覆盖的方法!”说的就是动态绑定。
6.最后子类除了可以覆盖父类中的原有方法 还可以自己添加额外的方法,但是如果向上转型为父类,其引用无法调用父类中没有的方法,在确保安全的情况下 可以向下转型,调用属于自己的方法。
if(fa instanceof Son){
((Son)fa).getFatherFiled();
}