package three.day.newcharacter;
class A1
{
public int num01 = 1;
public void func01()
{
System.out.println("func01 in A");
}
public void func02()
{
// System.out.println("func02 in A");
func01();
}
}
class B extends A1
{
public int num01 = 2;
public void func01()
{
System.out.println("func01 in B");
}
public void func03()
{
System.out.println("func03 in B");
}
}
public class MemoryModel
{
public static void callFunc01(A1 a)
{
a.func01();
a.func02();
//a.func03();
((B) a).func03();
System.out.println(a.num01);
}
public static void callFunc02(B b)
{
b.func01();
b.func02();
b.func03();
System.out.println(b.num01);
}
public static void main(String[] args)
{
A1 a01 = new A1();
B b01 = new B();
A1 a02 = new B();
//B b02 = new A1();//编译错误(语法错误) 下塑造型
//B b02 = (B) new A1();//运行错误
//Exception in thread "main" java.lang.ClassCastException:
//three.day.newcharacter.A1 cannot be cast to three.day.newcharacter.B
//b02.func03();
B b03 = new B();
A1 a03 = b03; //上塑造型
//A a04 = new A();
//B b04 = a04;//编译错误(语法错误)
//B b04 = (B) a04;//运行错误
callFunc01(a01);//与((B) a).func03();配合使用时,造成运行错误(编译器解释时错误)
callFunc01(b01);
callFunc02(b01); //func01 in B 成员方法在内存模型的角度来看,B的成员方法func01将父类中的func01覆盖,内存模型的方法覆盖
//func02 in A 存在于A定义,B继承了,内存模型的方法继承
//func03 in B 存在于B定义,正常调用
System.out.println(a01.num01);//1 存在于A定义,正常调用
System.out.println(b01.num01);//2 存在于B定义,正常调用
/*
callFunc01(a02);
//callFunc02(a02);
*/
/**
* 以下语句最值得揣摩,有利于理解内存模型
*/
//callFunc01(a03);
//callFunc02(a03);//如果不强制转换,出现编译错误(语法错误)
// callFunc02((B) a03);//callFunc02(B b)的参数要求,要不然左子类型右父对象(就错误)
// B b03 = new B();A a03 = b03;经过这两句之后,编译器已经认为a03是父对象
//结论:也就是说,编译器是根据一个对象的类型来判断是父对象还是子对象
//而不是这个对象实际占据的内存空间(或者说内存模型)
}
}
class A1
{
public int num01 = 1;
public void func01()
{
System.out.println("func01 in A");
}
public void func02()
{
// System.out.println("func02 in A");
func01();
}
}
class B extends A1
{
public int num01 = 2;
public void func01()
{
System.out.println("func01 in B");
}
public void func03()
{
System.out.println("func03 in B");
}
}
public class MemoryModel
{
public static void callFunc01(A1 a)
{
a.func01();
a.func02();
//a.func03();
((B) a).func03();
System.out.println(a.num01);
}
public static void callFunc02(B b)
{
b.func01();
b.func02();
b.func03();
System.out.println(b.num01);
}
public static void main(String[] args)
{
A1 a01 = new A1();
B b01 = new B();
A1 a02 = new B();
//B b02 = new A1();//编译错误(语法错误) 下塑造型
//B b02 = (B) new A1();//运行错误
//Exception in thread "main" java.lang.ClassCastException:
//three.day.newcharacter.A1 cannot be cast to three.day.newcharacter.B
//b02.func03();
B b03 = new B();
A1 a03 = b03; //上塑造型
//A a04 = new A();
//B b04 = a04;//编译错误(语法错误)
//B b04 = (B) a04;//运行错误
callFunc01(a01);//与((B) a).func03();配合使用时,造成运行错误(编译器解释时错误)
callFunc01(b01);
callFunc02(b01); //func01 in B 成员方法在内存模型的角度来看,B的成员方法func01将父类中的func01覆盖,内存模型的方法覆盖
//func02 in A 存在于A定义,B继承了,内存模型的方法继承
//func03 in B 存在于B定义,正常调用
System.out.println(a01.num01);//1 存在于A定义,正常调用
System.out.println(b01.num01);//2 存在于B定义,正常调用
/*
callFunc01(a02);
//callFunc02(a02);
*/
/**
* 以下语句最值得揣摩,有利于理解内存模型
*/
//callFunc01(a03);
//callFunc02(a03);//如果不强制转换,出现编译错误(语法错误)
// callFunc02((B) a03);//callFunc02(B b)的参数要求,要不然左子类型右父对象(就错误)
// B b03 = new B();A a03 = b03;经过这两句之后,编译器已经认为a03是父对象
//结论:也就是说,编译器是根据一个对象的类型来判断是父对象还是子对象
//而不是这个对象实际占据的内存空间(或者说内存模型)
}
}