Java向上下转型中的陷阱{详细}

网友投稿 264 2022-09-17

Java向上下转型中的陷阱{详细}

1: 多态

多态时继承下面的产物,之所以存在向上向下转型的目的,就是解决参数传递的不变形,体现面向接口编程的重要性,

1.1 方法的多态性

①. 方法的重载:同一个方法名称可以根据参数的类型或个数不同调用不同的方法体。  ②. 方法的覆写:同一个父类的方法,可能根据实例化子类的不同也有不同的表现形式。

1.2. 对象的向上转型

出现了父类指向了子类那么出现 向上转型  对象的向上转型:​​父类 父类对象 = 子类实例​​

class Person{ public void say() { System.out.println("我是Person"); }}public class Student extends Person { public void say() { System.out.println("我是Student"); } public void gotoSchool() { System.out.println("我的职责是上学"); } public static void main(String[] args) { // 向上转型 父类实例对象指向子类实例 只保留父类子类同名的方法,且子类变量覆盖父类变量 Person p=new Student(); p.say(); }}

输出: 我是Student

目的: 用于参数统一化,假设父类有n个子类,方法要接受子类的实例,如果没有向上转型,就需要定义n个方法接收不同的对象

1.3 对象的向下转型

对象的向下转型:​​子类 子类对象 = (子类)父类实例​​

class Person{ public void say() { System.out.println("我是Person"); }}public class Student extends Person { public void say() { System.out.println("我是Student"); } public void gotoSchool() { System.out.println("我的职责是上学"); } public static void main(String[] args) { // 向上转型 父类实例对象指向子类实例 只保留父类子类同名的方法,且子类变量覆盖父类变量 Person p=new Student(); p.say(); // 向下转型 子类实例指向父类 可以拥有子类自己的方法, Student s=(Student) p; s.say(); s.gotoSchool(); }}

注意:  向下转型之前一定要进行向上转型!!(让父类先指向子类)否则在转型时会出现ClassCastException(类型转换异常–运行时异常)

问题: 如果向下转型存在安全隐患,那么如何转型才靠谱

class Person{ public void print() { System.out.println("我是人"); } public void p() { System.out.println("伤心的一天"); }}class Student extends Person{ public void print() { System.out.println("我是学生"); } public void fun() { System.out.println("开心的一天!"); }}public class Test{ public static void main(String[] args) { Person per = new Student(); //per是否能表示Person实例 System.out.println(per instanceof Person); //per是否能表示Student实例 System.out.println(per instanceof Student); if(per instanceof Student) { Student stu = (Student)per; stu.fun(); } }}

注意: 虽然增强了 程序的健壮性 但是,仅仅是这样,你还是需要 在这之前 进行 父类指向子类实例的过程  父类 父类对象 = 子类实例

1,4 扩展调用的例子

class Person{ public void print() { System.out.println("我是人"); }}class Student extends Person{ public void print() { System.out.println("我是学生"); }}class Worker extends Person{ public void print() { System.out.println("我是工人"); }}public class Test{ public static void main(String[] args) { whoAreYou(new Student()); whoAreYou(new Worker()); } public static void whoAreYou(Person per) { per.print(); }}

2: 存在公共变量的分析过程

先类看一个代码:

class BB{ public String S="B"; public String getS() { return this.S; } public void setS(String s) { this.S = s; }}public class AA extends BB{ public String S="A"; public String getS() { return this.S; } public void setS(String s) { this.S = s; } public static void main(String[] args) { AA aa = new AA(); BB bb = new BB(); System.out.println(aa.S); System.out.println(bb.S); aa.setS("AA"); bb.setS("BB"); System.out.println(bb.S); bb=aa; aa=(AA) bb; System.out.println(bb instanceof BB); System.out.println(bb instanceof AA); System.out.println(aa.S); System.out.println(bb.S); System.out.println(aa.getS()); System.out.println(bb.getS()); System.out.println(bb.S); }}

一般我们认为输出

1:A2:B3:BB4:true5:true6:AA7:BB8:AA9:AA10:BB

上面输出 前6个没有问题,第七个由于前面执行了B.setS 所以我们认为应该为BB

正确输出结果为:

1:A2:B3:BB4:true5:true6:AA7:B8:AA9:AA10:B

那么为什么我们 第 7 10输出结果为 B呢, 我们打上断点看一下:

1: aa实例 由于继承了bb 所以域中存在S='B'

当执行了 设置BB的时候, 值按照我们的意思改变了

当执行了向上转型的时候,AA指向父类的实例,所以发生改变

所以第 System.out.println(bb.S); 能够输出 B,

而 System.out.println(bb.getS());为什么输出AA 因为当前指向指向子类 aa aa中的getS方法与父类同名,那么执行子类的方法,注意:如果这里为不同名称的方法,那么执行父类的方法,

我给出这个代码:

package LL;class BB2{ public int SB=1; public int getSB() { return SB; } public void setSB(int sB) { SB = sB; }}public class PP extends BB2{ public int SA=2; public int getSA() { return SA; } public void setSA(int sA) { SA = sA; } public static void main(String[] args) { PP aa = new PP(); BB2 bb = new BB2(); System.out.println(aa.SA);//2 System.out.println(bb.SB);//1 aa.setSA(22); bb.setSB(11); System.out.println(bb.SB);//11 bb=aa; System.out.println(bb instanceof BB2); System.out.println(bb instanceof PP); System.out.println(aa.SA);//22 System.out.println(bb.SB);//1 System.out.println(aa.getSA());//22 System.out.println(bb.getSB());//22 System.out.println(bb.SB);//1 }}

3:总结

最好将变量private 私有化 ,以免阅读程序麻烦存在public变量时候,继承的子类 执行的时候 回拷贝一份父类的变量,(表示 父类修改变量不会影响子类拷贝这个变量的值)当发生向上转型的时候,父类指向子类实例,那么父类实例拥有与子类实例一样的参数变量,转型的时候 子类只会保留与父类中同名的方法,其他放弃最后: 向下转型的时候 ,一定必须让父类实例指向子类

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:汽车私域流量运营方案,私域运营流程整合!
下一篇:Hibernate 继承映射可能会遇到的错误
相关文章

 发表评论

暂时没有评论,来抢沙发吧~