先看看构造函数的加载顺序
-
构造函数
package Loader;
class Parent {
public Parent() {
System.out.println("parent");
}
}
public class LoadTest extends Parent {
public LoadTest() {
System.out.println("LoadTest");
}
public static void main(String[] args) {
new LoadTest();
}
}
输出:
parent
LoadTest
多级的继承关系按规则逐级向上 找到最上面的开始父类开始构造
package Loader;
class root {
public root() {
System.out.println("root ");
}
}
class Parent extends root{
public Parent() {
System.out.println("parent");
}
}
public class LoadTest extends Parent {
public LoadTest() {
System.out.println("LoadTest");
}
public static void main(String[] args) {
Parent parent = new LoadTest();
LoadTest loadTest = new LoadTest();
}
}
输出:
root
parent
LoadTest
root
parent
LoadTest
2 静态块和构造函数
package Loader;
class Parent {
static{
System.out.println("parent static block");
}
public Parent() {
System.out.println("parent");
}
}
public class LoadTest extends Parent {
static{
System.out.println("LoadTest static block");
}
public LoadTest() {
System.out.println("LoadTest");
}
public static void main(String[] args) {
new LoadTest();
}
}
输出:
parent static block
LoadTest static block
parent
LoadTest
3 静态块 块 和构造函数
package Loader;
class Parent {
static{
System.out.println("parent static block");
}
{
System.out.println("parent block");
}
public Parent() {
System.out.println("parent");
}
}
public class LoadTest extends Parent {
static{
System.out.println("LoadTest static block");
}
{
System.out.println("LoadTest block");
}
public LoadTest() {
System.out.println("LoadTest");
}
public static void main(String[] args) {
new LoadTest();
}
}
输出:
parent static block
LoadTest static block
parent block
parent
LoadTest block
LoadTest
结论:
父类静态块
自身静态块
父类块
父类构造器
自身块
自身构造器
2、普通方法和变量
package Loader;
class Parent {
public String str = "parent";
public void getFir() {
System.out.println("Parent getFir");
}
public void getSec() {
System.out.println("Parent getSec");
}
}
public class LoadTest extends Parent {
public String str = "LoadTest";
public int a = 1;
public void getFir() {
System.out.println(" LoadTest getFir");
}
public void getSec() {
System.out.println("LoadTest getSec");
}
public void getThd() {
System.out.println("LoadTest getthd");
}
public static void main(String[] args) {
Parent parent = new LoadTest();
LoadTest loadTest = new LoadTest();
System.out.println(parent.str);
parent.getFir();
System.out.println(loadTest.str);
loadTest.getFir();
// parent.getThd(); //编译错误
loadTest.getThd();
// System.out.println(parent.a); // 编译错误
System.out.println(loadTest.a);
}
}
输出为:
parent
LoadTest getFir
LoadTest
LoadTest getFir
LoadTest getthd
1
父类类型的引用指向子类的实例时 该引用只能调用父类中的变量和方法
当父类中的方法被重写后 (只指方法,变量是不会有重写的概念 ) 将调用实例类的方法(动态连接 动态调用 根据这个对象引用实际的类型来获取对应的方法)。
单看:
package Loader;
class Parent {
public void getFir() {
getSec();
}
public void getSec() {
System.out.println("Parent getSec");
}
}
public class LoadTest extends Parent {
public void getFir() {
getSec();
}
public void getSec() {
System.out.println("LoadTest getSec");
}
public void getThd() {
System.out.println("LoadTest getthd");
}
public static void main(String[] args) {
Parent parent = new LoadTest();
LoadTest loadTest = new LoadTest();
parent.getFir();
loadTest.getFir();
}
}
输出会比较明显的:
LoadTest getSec
LoadTest getSec
SUN目前的JVM实现机制,类实例的引用就是指向一个句柄(handle)的指针,这个句柄是一对指针:
一个指针指向一张表格,实际上这个表格也有两个指针(一个指针指向一个包含了对象的方法表,另外一个指向类对象,表明该对象所属的类型);
另一个指针指向一块从java堆中为分配出来内存空间