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:A
2:B
3:BB
4:true
5:true
6:AA
7:BB
8:AA
9:AA
10:BB

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

正确输出结果为:

1:A
2:B
3:BB
4:true
5:true
6:AA
7:B
8:AA
9:AA
10: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);//
System.out.println(bb.SB);//
aa.setSA(22);
bb.setSB(11);
System.out.println(bb.SB);//
bb=aa;
System.out.println(bb instanceof BB2);
System.out.println(bb instanceof PP);
System.out.println(aa.SA);//
System.out.println(bb.SB);//
System.out.println(aa.getSA());//
System.out.println(bb.getSB());//
System.out.println(bb.SB);//
}
}

3:总结

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

Java向上下转型中的陷阱{详细}的更多相关文章

  1. Java进阶4表达式中的陷阱

    Java进阶4表达式中的陷阱 20131103 表达式是Java中最基本的组成单元,各种表达式是Java程序员最司空见惯的内容,Java中的表达式并不是十分的复杂,但是也有一些陷阱.例如当程序中使用算 ...

  2. Java集合与泛型中的陷阱

    List,List<Object>区别 List<Integer> t1 = new ArrayList<>(); // 编译通过 List t2 = t1; // ...

  3. Java 理论和实践: 了解泛型 识别和避免学习使用泛型过程中的陷阱

    Brian Goetz (brian@quiotix.com), 首席顾问, Quiotix 简介: JDK 5.0 中增加的泛型类型,是 Java 语言中类型安全的一次重要改进.但是,对于初次使用泛 ...

  4. (转)Java中的容器详细总结

    Java中的容器详细总结(编辑中) 原文链接:http://anxpp.com/index.php/archives/656/ 注:本文基于 Jdk1.8 编写 通常程序总是根据运行时才知道的某些条件 ...

  5. 《手把手教你》系列技巧篇(十八)-java+ selenium自动化测试-元素定位大法之By css中卷(详细教程)

    1.简介 按计划今天宏哥继续讲解倚天剑-css的定位元素的方法:ID属性值定位.其他属性值定位和使用属性值的一部分定位(这个类似xpath的模糊定位). 2.常用定位方法(8种) (1)id(2)na ...

  6. Java中System的详细用法

    System.arraycopy System.arraycopy的函数原型是: public static void arraycopy(Object src, int srcPos, Object ...

  7. Java多态与C++中多态的实现

    大牛的文章,值得拜读http://www.ibm.com/developerworks/cn/java/j-lo-polymorph/ 粘贴过来好多图片丢失了 /(ㄒoㄒ)/~~ 众所周知,多态是面向 ...

  8. Java 序列化Serializable详解(附详细例子)

    Java 序列化Serializable详解(附详细例子) 1.什么是序列化和反序列化 Serialization(序列化)是一种将对象以一连串的字节描述的过程:反序列化deserialization ...

  9. Java Annotation认知(包括框架图、详细介绍、示例说明)

    摘要 Java Annotation是JDK5.0引入的一种注释机制. 网上很多关于Java Annotation的文章,看得人眼花缭乱.Java Annotation本来很简单的,结果说的人没说清楚 ...

随机推荐

  1. 【Java Web开发学习】跨域请求

    [Java Web开发学习]跨域请求 ================================================= 1.使用jsonp ===================== ...

  2. win10 修改用户目录为英文

    win10家庭版怎样进入 administratornet user administrator /active:yes net user administrator /active:no

  3. Java Swing JFrame实现全屏--无标题,无边框

    实现方式一: import java.awt.Dimension; import java.awt.Toolkit; import javax.swing.JFrame; public class T ...

  4. 为什么要使用MQ消息中间件?这3个点让你彻底明白!

    前言 一个用消息队列的人,不知道为啥用,有点尴尬.没有复习这点,很容易被问蒙,然后就开始胡扯了. 回答:这个问题,咱只答三个最主要的应用场景,不可否认还有其他的,但是只答三个主要的,即以下六个字: 解 ...

  5. 【TCP/IP网络编程】:04基于TCP的服务器端/客户端

    摘要:结合前面所讲述的知识,本篇文章主要介绍了简单服务器端和客户端实现的框架流程及相关函数接口. 理解TCP和UDP 根据数据传输方式的不同,基于网络协议的套接字一般分为TCP套接字和UDP套接字(本 ...

  6. 区块链学习——HyperLedger-Fabric v1.0环境搭建详细教程

    相对与v0.6版本来说,1.0版本改变较大,此处不多说,只是将小白自己搭建1.0环境的过程分享给大家.希望对大家能有所帮助! 这一篇可能对前面的环境搭建会写的有些粗略,如有疑问,可阅读上一篇V0.6版 ...

  7. js中正则表达式的易错点

    文章目录 1. 匹配符部分匹配规则 2. 分组匹配规则: 3. 注意^的不同用法 4. 不要忘记转义 5. 正则表达式对象中lastIndex属性 6. exec VS match 1. 匹配符部分匹 ...

  8. uni-app实现图片和视频上传功能

    使用uni-app实现点击上传,既可以上传视频,有可以上传图片,图片预览,删除图片和视频功能,最终效果如下.uni-app里面没有提供同时上传视频和图片这个插件,只能靠自己手写,  1.页面布局 通过 ...

  9. Java之缓冲流(字节/字符缓冲流)

    概述 缓冲流,也叫高效流,是对4个基本的 FileXxx 流的增强,所以也是4个流,按照数据类型分类: 字节缓冲流: BufferedInputStream , BufferedOutputStrea ...

  10. 从无到有通过IDEA搭建SpringBoot项目

    本人第一次写博客希望记录当下,努力成为IT界中的清流,写的不好多多包涵. SpringBoot是由Pivotal团队在2013年开始研发.2014年4月发布第一个版本的全新开源的轻量级框架.它基于Sp ...