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小时内删除侵权内容。
发表评论
暂时没有评论,来抢沙发吧~