a1=(A)b2--> a1 = b2 is OK. Because B is a kind of A, we don't have to cast. b2.s--> b2 is a B, it has a s="class:B" a1.s--> a1 is a A, s="class:A" a2.s--> same above b1.s--> b1 is B now, it has a s="class:B" If you add functions there, things will be different.
class A{ String s = "A"; public void say() {System.out.println("I am an A");} } class B extends A{ String s = "B"; public void say() {System.out.println("I am a B");} } ... main A a; B b= new B(); a = b; System.out.println(a.s); // A System.out.println(b.s); // B a.say(); // I am B**************************** b.say(); // I am B
包你明白,我帮你解释: class A { String s="class:A"; }class B extends A//多了一个class关键字,我帮你去掉了 { String s="class:B"; }//好像少了个括号,我帮你加了public class TypeV { public static void main(String args[])//少了一个void关键字,我帮你加了 { B b1,b2 = new B(); A a1,a2; System.out.println(b2.s);//为什么这里输出的是class:B,请见注释一 a1=(A)b2; System.out.println(a1.s);//但是把b2的值付给类A的a1的时候a1的值变成的class:A,请见注释二 a2=b2; System.out.println(a1.s);//请见注释三 System.out.println(a2.s);//请见注释四 b1=(B)a1; System.out.println(b1.s);//请见注释五 } } 输出结果: class:B class:A class:A class:A class:B Press any key to continue...注释一: 类A和类B是父子关系,它们两个都有各自的属性(数据成员),而现在有一个特殊的属性,就是它们都有一个所谓的共同姓名标识s,当然在我们现实生活中,老爸A和儿子B也不可能是同名的吧,所以在这里它们的姓名标识分别被标记了class:A和class:B,所以在你第一个输出语句时输出的是子类B的姓名标识,因为你new 出来的对象就是子类B的对象,你的子类B属性(数据成员s)隐藏了父类A的属性(数据成员s),就是说子类B的姓名是对自己而言的,虽然老爸A也有姓名,但这是两回事,老爸A的姓名就是老爸A的,儿子B的姓名就是儿子B的,明白吗?注释二: 这里讲到的就是继承问题,子类B继承了父类A,我们就可以说子类B是属于父类A家族的,再打个比方,电器类A下有电视机子类B,我们就可以说电视机类B是电器类A,而不能说电器类A就是电视机类B,经过a1=(A)b2;这一转换,子类B的对象b2就当成是父类A来处理了,就是说现在由父类A来代言帮儿子B讲话了,所以输出的是class:A,用OOP的话讲就是父类隐藏的属性重新可见了,因为经过了转换注释三: 多余的解释,同注释二,输出为class:A注释四: a2=b2; 原理同注释二差不多,只是这里没有强制转换,但JAVA语言认为这是安全的,子类可以直接处理成父类,因为父类管理了子类的一些共同行为和属性,但父类不可以直接处理成子类,这是不安全的,所以一定要用强制转换,而且是不可缺的...假如你去管你老爸老妈的事,我想他们不会轻易同意吧,还是要在强烈要求下,才允许你管他们,这里说的强烈要求就可以理解为强制转换,相反你老爸老妈养你这么大,衣食住行生下来就管,有没有经过你的同意呀?呵呵,如果你懂C++的多态性该有多好啊:D 输出为class:A注释五: 就是上面注释四说的,b1子类不可以直接去管你的父类,所以要强制转换,转换后,就是说父类同意了你子类的属性和行为,输出结果也就是输出为class:B全文完...不知你听懂了没有:(
b2.s--> b2 is a B, it has a s="class:B"
a1.s--> a1 is a A, s="class:A"
a2.s--> same above
b1.s--> b1 is B now, it has a s="class:B"
If you add functions there, things will be different.
String s = "A";
public void say() {System.out.println("I am an A");}
}
class B extends A{
String s = "B";
public void say() {System.out.println("I am a B");}
}
... main
A a;
B b= new B();
a = b;
System.out.println(a.s); // A
System.out.println(b.s); // B
a.say(); // I am B****************************
b.say(); // I am B
class A
{
String s="class:A";
}class B extends A//多了一个class关键字,我帮你去掉了
{
String s="class:B";
}//好像少了个括号,我帮你加了public class TypeV
{
public static void main(String args[])//少了一个void关键字,我帮你加了
{
B b1,b2 = new B();
A a1,a2;
System.out.println(b2.s);//为什么这里输出的是class:B,请见注释一 a1=(A)b2;
System.out.println(a1.s);//但是把b2的值付给类A的a1的时候a1的值变成的class:A,请见注释二 a2=b2;
System.out.println(a1.s);//请见注释三
System.out.println(a2.s);//请见注释四 b1=(B)a1;
System.out.println(b1.s);//请见注释五
}
}
输出结果:
class:B
class:A
class:A
class:A
class:B
Press any key to continue...注释一:
类A和类B是父子关系,它们两个都有各自的属性(数据成员),而现在有一个特殊的属性,就是它们都有一个所谓的共同姓名标识s,当然在我们现实生活中,老爸A和儿子B也不可能是同名的吧,所以在这里它们的姓名标识分别被标记了class:A和class:B,所以在你第一个输出语句时输出的是子类B的姓名标识,因为你new 出来的对象就是子类B的对象,你的子类B属性(数据成员s)隐藏了父类A的属性(数据成员s),就是说子类B的姓名是对自己而言的,虽然老爸A也有姓名,但这是两回事,老爸A的姓名就是老爸A的,儿子B的姓名就是儿子B的,明白吗?注释二:
这里讲到的就是继承问题,子类B继承了父类A,我们就可以说子类B是属于父类A家族的,再打个比方,电器类A下有电视机子类B,我们就可以说电视机类B是电器类A,而不能说电器类A就是电视机类B,经过a1=(A)b2;这一转换,子类B的对象b2就当成是父类A来处理了,就是说现在由父类A来代言帮儿子B讲话了,所以输出的是class:A,用OOP的话讲就是父类隐藏的属性重新可见了,因为经过了转换注释三:
多余的解释,同注释二,输出为class:A注释四:
a2=b2; 原理同注释二差不多,只是这里没有强制转换,但JAVA语言认为这是安全的,子类可以直接处理成父类,因为父类管理了子类的一些共同行为和属性,但父类不可以直接处理成子类,这是不安全的,所以一定要用强制转换,而且是不可缺的...假如你去管你老爸老妈的事,我想他们不会轻易同意吧,还是要在强烈要求下,才允许你管他们,这里说的强烈要求就可以理解为强制转换,相反你老爸老妈养你这么大,衣食住行生下来就管,有没有经过你的同意呀?呵呵,如果你懂C++的多态性该有多好啊:D
输出为class:A注释五:
就是上面注释四说的,b1子类不可以直接去管你的父类,所以要强制转换,转换后,就是说父类同意了你子类的属性和行为,输出结果也就是输出为class:B全文完...不知你听懂了没有:(