java关于子类父类类型转换和引用的问题 麻烦给接受一下这道题的要点谢谢
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java关于子类父类类型转换和引用的问题 麻烦给接受一下这道题的要点谢谢相关的知识,希望对你有一定的参考价值。
class A String s="class A"; void show() System.out.println(s); class B extends A String s="class B"; void show() System.out.println(s); public class TypeConvert public static void main(String args[]) B b1;B b2=new B(); A a1,a2; a1=(A)b2; a2=b2; System.out.println(a1.s); a1.show(); System.out.println(a2.s); a2.show(); b1=(B)a1; System.out.println(b1.s); b1.show(); System.out.println(b2.s); b2.show();
这道题主要是多态(动态绑定)
父类引用指向子类对象:所能看到的只是父类那部分属性和方法
在执行期间判断所引用对象的实际类型,根据其实际的类型调用其相应的方法。 原来父类对象中方法的地址指向自己的方法,当父类引用指向new子类对象的过程时指针会发生改变,父类对象中方法的指针从指向自己的方法变成指向new对象对应类中重写的那个方法(如图绿色箭头)。
下面话内存图解释:
代码解释:
System.out.println(a1.s);a1是父类引用,指向new B()对象,a1所能看到的只是A对象的属性和方法(如图)。其属性是:class A
a1.show();a1是父类引用,指向new B()对象。此过程有指针指向变化,如图绿色箭头指向,a1所指向A对象中方法的地址现在指向B类中的方法。B中的s的值是:class B
System.out.println(b1.s);B对象的引用b1指向B对象,能看到对象里面的所以内容。其属性的值是子类自己的值:class B
b1.show();B对象的引用b1指向B对象的方法的地址,此地址指向子类自己的方法,对应属性s的值是:class B
参考技术A 是要输出结果吗。分析如下:1、类A,打印 class A
2、类B继承类A,打印class B
3、main中
3.1、B b1;定义一个类型B引用变量 b1
3.2、B b2 = new B();定义一个类型B引用变量b2指向一个B类对象
3.3、A a1, a2;定义两个类型A的引用变量 a1,a2
3.4、a1 = (A) b2; b2所指向的类型B的对象向上转型为A类型然后a1指向它
3.5、a2 = b2;a2指向b2所指向的对象
3.6、System.out.println(a1.s);由于a1指向b2所指向的对象,所以输出class A
3.7、a1.show();由于a1是基类引用所以输出 class B
3.8、System.out.println(a2.s);由于a2和b2指向相同对象,所以输出class A
3.9、a2.show();由于a2是基类引用所以输出 class B
3.10、b1 = (B) a1;将a1指向的对象向下转型为类型B然后b1指向它
3.11、System.out.println(b1.s);b1指向a1指向的对象,所以输出class B
3.12、b1.show();由于a2是派生类引用所以输出 class B
3.13、System.out.println(b2.s);b2指向对象类型B所以为class B
3.14、b2.show();class B
java中的强制类型转换
用(String)做强制类型转换 和 用String.valueOf() 有什么区别
在Java中强制类型转换分为基本数据类型和引用数据类型两种,这里我们讨论的后者,也就是引用数据类型的强制类型转换。
在Java中由于继承和向上转型,子类可以非常自然地转换成父类,但是父类转换成子类则需要强制转换。因为子类拥有比父类更多的属性、更强的功能,所以父类转换为子类需要强制。那么,是不是只要是父类转换为子类就会成功呢?其实不然,他们之间的强制类型转换是有条件的。
当我们用一个类型的构造器构造出一个对象时,这个对象的类型就已经确定的,也就说它的本质是不会再发生变化了。在Java中我们可以通过继承、向上转型的关系使用父类类型来引用它,这个时候我们是使用功能较弱的类型引用功能较强的对象,这是可行的。但是将功能较弱的类型强制转功能较强的对象时,就不一定可以行了。
举个例子来说明。比如系统中存在Father、Son两个对象。首先我们先构造一个Son对象,然后用一个Father类型变量引用它:
Father father = new Son();
在这里Son 对象实例被向上转型为father了,但是请注意这个Son对象实例在内存中的本质还是Son类型的,只不过它的能力临时被消弱了而已,如果我们想变强怎么办?将其对象类型还原!
Son son = (Son)father;
这条语句是可行的,其实father引用仍然是Father类型的,只不过是将它的能力加强了,将其加强后转交给son引用了,Son对象实例在son的变量的引用下,恢复真身,可以使用全部功能了。
前面提到父类强制转换成子类并不是总是成功,那么在什么情况下它会失效呢?当引用类型的真实身份是父类本身的类型时,强制类型转换就会产生错误。例如:
Father father = new Father();
Son son = (Son) father;
这个系统会抛出ClassCastException异常信息。
所以编译器在编译时只会检查类型之间是否存在继承关系,有则通过;而在运行时就会检查它的真实类型,是则通过,否则抛出ClassCastException异常。
所以在继承中,子类可以自动转型为父类,但是父类强制转换为子类时只有当引用类型真正的身份为子类时才会强制转换成功,否则失败。
扩展资料:
public class TestCastClassException
public static void main(String[] args)
Father father = new Son();
//这两句话是不对的,因为一个father类型的引用(指针)是看不见、看不到son中新定义的数据成员或者成员函数的
//虽然这个对象的本质是Son类型的,它也确实有这样的数据成员和成员函数,但是指针的作用范围不够,它看不到。
//代码后面附上模型分析
//father.son = 2;
//father.show_son();
father.show_father();
father.show();
Father father1 = (Father)father;//一个对象在内存中被new出来后,只能选择访问它的方式,不能修改它的布局(包含的成员的个数等)
father1.show();
//main
class Father
public int father = 2;
Father()
void show()
System.out.println("This is father");
void show_father()
System.out.println("father!!");
class Son extends Father
public int son = 1;
Son()
void show()
System.out.println("This is son");
void show_son()
System.out.println("son!!");
参考技术A用(String)做强制类型转换和用String.valueOf()区别在于:
String 就是直接强制转化成String型的字符串,且有优先级限制,像int i=123;不能String s=(String)i。
而String.valueOf()里面的参数转换可以是double、long、char[] 、long等等,没限制,所以String s=String.valueOf(i)。
toString()方法返回的是这个对象的字符串表示,就像是这个对象的名字一样,任何对象都可以有自己的名字,你可以重写其toString()方法,给其赋予任意的名字。
但是调用toString()方法的对象不能为 null,否则会抛出异常:java.lang.NullPointerException。
例子如下:
扩展资料:
java中强制类型转换
在Java中强制类型转换分为基本数据类型和引用数据类型两种,这里我们讨论的后者,也就是引用数据类型的强制类型转换。
在Java中由于继承和向上转型,子类可以非常自然地转换成父类,但是父类转换成子类则需要强制转换。
因为子类拥有比父类更多的属性、更强的功能,所以父类转换为子类需要强制。那么,是不是只要是父类转换为子类就会成功呢?其实不然,他们之间的强制类型转换是有条件的。
当我们用一个类型的构造器构造出一个对象时,这个对象的类型就已经确定的,也就说它的本质是不会再发生变化了。
在Java中我们可以通过继承、向上转型的关系使用父类类型来引用它,这个时候我们是使用功能较弱的类型引用功能较强的对象,这是可行的。但是将功能较弱的类型强制转功能较强的对象时,就不一定可以行了。
举个例子来说明。比如系统中存在Father、Son两个对象。首先我们先构造一个Son对象,然后用一个Father类型变量引用它:
Father father = new Son();
在这里Son 对象实例被向上转型为father了,但是请注意这个Son对象实例在内存中的本质还是Son类型的,只不过它的能力临时被消弱了而已,如果我们想变强怎么办?将其对象类型还原!
Son son = (Son)father;
这条语句是可行的,其实father引用仍然是Father类型的,只不过是将它的能力加强了,将其加强后转交给son引用了,Son对象实例在son的变量的引用下,恢复真身,可以使用全部功能了。
前面提到父类强制转换成子类并不是总是成功,那么在什么情况下它会失效呢?
当引用类型的真实身份是父类本身的类型时,强制类型转换就会产生错误。例如:
Father father = new Father();
Son son = (Son) father;
这个系统会抛出ClassCastException异常信息。
所以编译器在编译时只会检查类型之间是否存在继承关系,有则通过;而在运行时就会检查它的真实类型,是则通过,否则抛出ClassCastException异常。
所以在继承中,子类可以自动转型为父类,但是父类强制转换为子类时只有当引用类型真正的身份为子类时才会强制转换成功,否则失败
参考技术BJava中的强制类型转换的转换方式如下:
当用一个类型的构造器构造出一个对象时,这个对象的类型就已经确定的,也就说它的本质是不会再发生变化了。
在Java中可以通过继承、向上转型的关系使用父类类型来引用它,这个时候是使用功能较弱的类型引用功能较强的对象。但是将功能较弱的类型强制转功能较强的对象时,就不一定可以行了。
扩展资料:
在Java项目的实际开发和应用中,常常需要用到将对象转为String这一基本功能。常用的转换方法有Object.toString(),(String)要转换的对象,String.valueOf(Object)等。
强制类型转换具有两种形式:显式强制转换和隐式强制类型转换。
强制类型转换是把父类型转换为子类型。因为子类型比父类型的内涵要丰富,无非就是属性更多功能更强,所以要把父类型转换为子类型,需要强制。
比如:
long a = 10 ;
int b = (int) a。
通过 (int)可以强制转型 , 但是这样会丢失精度 , 比如a如果超过了b的范围 , 那么强转成int型, 只会等于int的最大值。
参考资料来源:百度百科—强制类型转换
参考技术C强制类型转换有两种,转换方法如下(都需要使用C语言):
1、显式强制类型转换:
TYPE b = (TYPE) a;其中,TYPE为类型描述符,如int,float等。经强制类型转换运算符运算后,返回一个具有TYPE类型的数值,这种强制类型转换操作并不改变操作数本身,运算后操作数本身未改变,例如:
int n=0xab65;
char a=(char)n;
2、隐式强制类型转换:
隐式类型转换发生在赋值表达式和有返回值的函数调用表达式中。在赋值表达式中,如果赋值符左右两侧的操作数类型不同,则将赋值符右边操作数强制转换为赋值符左侧的类型数值后,赋值给赋值符左侧的变量。如:
int n;
double d=3.88;
n=d;//执行本句后,n的值为3,而d的值仍是3.88。
扩展资料:
类型转换遵循以下规则:
1、若参与运算量的类型不同,则先转换成同一类型,然后进行运算。
2、转换按数据长度增加的方向进行,以保证精度不降低。如int型和long型运算时,先把int量转成long型后再进行运算。
a、若两种类型的字节数不同,转换成字节数高的类型。
b、若两种类型的字节数相同,且一种有符号,一种无符号,则转换成无符号类型。
3、所有的浮点运算都是以双精度进行的,即使仅含float单精度量运算的表达式,也要先转换成double型,再作运算。
4、char型和short型(在visual c++等环境下)参与运算时,必须先转换成int型。
5、在赋值运算中,赋值号两边量的数据类型不同时,赋值号右边量的类型将转换为左边量的类型。如果右边量的数据类型长度比左边长时,将丢失一部分数据,这样会降低精度,丢失的部分直接舍去。
C++语言编译系统提供的内部数据类型的隐式自动转换规则如下:
1、执行算术运算时,低类型(短字节)可以转换为高类型(长字节);例如: int型转换成double型,char型转换成int型等等;
2、赋值表达式中,等号右边表达式的值的类型自动隐式地转换为左边变量的类型,并赋值给它;
3、函数调用时,将实参的值传递给形参,系统首先会自动隐式地把实参的值的类型转换为形参的类型,然后再赋值给形参;
4、函数有返回值时,系统首先会自动隐式地将返回表达式的值的类型转换为函数的返回类型,然后再赋值给调用函数返回;
参考资料:百度百科- 强制类型转换
参考技术D强制类型转换分两种形式:
1. 显式强制类型转换 :
C中显式强制类型转换很简单,格式如下: TYPE b = (TYPE) a, 其中,TYPE为类型描述符,如int,float等。
经强制类型转换运算符运算后,返回一个具有TYPE类型的数值,这种强制类型转换操作并不改变操作数本身,运算后操作数本身未改变。
2.隐式强制类型转换:
隐式类型转换发生在赋值表达式和有返回值的函数调用表达式中。
在赋值表达式中,如果赋值符左右两侧的操作数类型不同,则将赋值符右边操作数强制转换为赋值符左侧的类型数值后,赋值给赋值符左侧的变量。
在函数调用时,如果return后面表达式的类型与函数返回值类型不同,则在返回值时将return后面表达式的数值强制转换为函数返回值类型后,再将值返回。
扩展资料:
强制类型转换规则、格式、注意事项及异常处理:
1.转换规则:
从存储范围大的类型到存储范围小的类型。
具体规则为:
double→float→long→int→short(char)→byte
2.语法格式为:
(转换到的类型)需要转换的值
示例代码:
double d = 3.10;
int n = (int)d;
3.注意问题:
强制类型转换通常都会存储精度的损失,所以使用时需要谨慎。
4.异常处理:
方式一:捕获处理
捕获处理的格式:
try可能发生异常的代码;catch(捕获的异常类型 变量名)处理异常的代码....
捕获处理要注意的细节:
(1) 如果try块中代码出了异常经过了处理之后,那么try-catch块外面的代码可以正常执行。
(2)如果try块中出了异常的代码,那么在try块中出现异常代码后面的代码是不会执行了。
(3) 一个try块后面是可以跟有多个catch块的,也就是一个try块可以捕获多种异常的类型。
(4) 一个try块可以捕获多种异常的类型,但是捕获的异常类型必须从小到大进行捕获,否则编译报错。
方式二:抛出处理
抛出处理要注意的细节:
(1)如果一个方法的内部抛出了一个异常 对象,那么必须要在方法上声明抛出。
(2)如果调用了一个声明抛出异常 的方法,那么调用者必须要处理异常。
(3)如果一个方法内部抛出了一个异常对象,那么throw语句后面的代码都不会再执行了(一个方法遇到了throw关键字,该方法也会马上停止执行的)。
(4) 在一种情况下,只能抛出一种类型异常对象。
参考资料:百度百科-强制类型转换
以上是关于java关于子类父类类型转换和引用的问题 麻烦给接受一下这道题的要点谢谢的主要内容,如果未能解决你的问题,请参考以下文章