java类继承总结一 父类类型与子类类型之间的转化问题

本文将通过一个实例描述父类类型与子类类型之间的转化问题,这个很特殊的问题常常会导致一些潜在的危险,让你整整一个晚上都在调试程序以解决一个让人抓狂的java.lang.ArrayStoreException异常。

1. 子类数组的引用可以装换为超类数组的引用

2. 子类的引用child可以转换为父类的引用parent(这里假设parent是父类对象,child是子类对象),但却不可以通过 parent调用child的特有方法

class Employee{
  protected String name;
  protected long salary;
  public Employee(String aName){
    this.name = aName;
  }
  
  public void setSalary(long aSalary){
    this.salary = aSalary;
  }
  
  public long getSalary(){
    return this.salary;
  }
}

class Manager extends Employee{
  protected long bonus;
  public Manager(String aName){
    super(aName);
  }
  
  public void setBonus(long aBonus){
    this.bonus = aBonus;
  }
  
  public long getSalary(){
    return super.getSalary()+this.bonus;
  }
}

public static void main(String[] args) {
    //注意,这时managers 和employees 引用的是同一个数组
    Manager[] managers = new Manager[10];
    Employee[] employees = managers;
    //(a)注意,下面三条语句是可以通过的,但运行时会抛出异常
    employees[0] = new Employee("Abel"); //运行时此处抛出java.lang.ArrayStoreException异常
    managers[0].setSalary(1000);
    managers[0].setBonus(500);
    //(b)这样的语句编译和运行都没有问题
    employees[0] = new Manager("Abel");
    employees[0].setSalary(1000);
    managers[0].setSalary(1000);
    managers[0].setBonus(500);
}

总结:
1. 在java中,对象变量是多态的,一个employee既可以引用Employee类型的实例,也可以引用子类Manager类型的实例,但一个manager不能引用一个Employee类型的实例,例如:
   (1) Employee e = new Manager("Abel") 是合法的
   (2)Manager   m = new Employee("Abel") 是不合法的
  原因很容易理解,manager与employee是is-a的关系,任何一个manager都是一个emplpyee,如(1)所示,一个Employee类型的引用e可以引用Manager类型的实例,这意味着可以通过e使用Manager中任何继承自Employee的方法(注意,e不能使用Manager的特有方法,如e.setBonus(1000)是不合法的),Employee e = new Manager("Abel")的潜台词就是说,e从Employee的角度描述Manager,e就是一个Employee,不管e引用的是什么,编译器就把它当一个Employee来看。

2. 对于上面(a)的代码,不能运行是可以理解的, employees[0]虽然在声明时是Employee类型,但Employee[] employees = managers;规定了employees[i]指向的必须是Manager类型的实例,因此employees[0] = new Employee("Abel"); 这条语句必然会引发异常。
   (a)处的代码employees[0] = new Employee("Abel");可以通过编译似乎也情有可原,因为employees声明的类型是Employee[], 那么employees[0]自然可以接受一个Employee类型的引用,但实际上

Employee[] employees = managers;赋值的过程中又规定了employees接受的必须是Manager类型,从上面的例子可以看出,运行的时候会做这样的检查,但编译的时候不会检查的这么深入,只会检查变量的声明类型,看来java编译器还不够智能啊 :)

3. 在实际编程的过程中,使用对象变量的多态性时一定要注意(尤其是使用数组的时候),否则编译通过,但运行报错,这个错误很可能让你调试一个晚上才能找出问题所在!!

java类继承总结一 父类类型与子类类型之间的转化问题(转)的更多相关文章

  1. C#父类对象和子类对象之间的转化

    1. 子类到父类 Chinese c = new Chinese(); Person p1 = c;  //从变量c看是一个中国人,所以可以把人的标签贴上去 2. 父类到子类 Chinese c2 = ...

  2. Java类继承关系中的初始化顺序

    Java类初始化的顺序经常让人犯迷糊,现在本文尝试着从JVM的角度,对Java非继承和继承关系中类的初始化顺序进行试验,尝试给出JVM角度的解释. 非继承关系中的初始化顺序 对于非继承关系,主类Ini ...

  3. 【转】C++中了类继承和调用父类的构造函数方法

    构造方法用来初始化类的对象,与父类的其它成员不同,它不能被子类继承(子类可以继承父类所有的成员变量和成员方法,但不继承父类的构造方法).因此,在创建子类对象时,为了初始化从父类继承来的数据成员,系统需 ...

  4. java学习(五)java类继承

    1.制作一个工具类的文档 javadoc -d 目录 -author -version   arrayTool.java 实例: class arrayDemo { public static voi ...

  5. idea中查看java类继承图

    复习java io,看了书里的这张图,太模糊了,想弄个出来放大看,一开始试了idea发现只能看父类,后来折腾了一会试了其他工具才发现还是idea好用. :) 一.打开type hierachy 光标放 ...

  6. 【深入理解JVM】:Java类继承关系中的初始化顺序

    尝试着仔细阅读thinking in java 看到一篇很好的文章http://blog.csdn.net/u011080472/article/details/51330114

  7. 存在继承关系的Java类对象之间的类型转换(一)

      类似于基本数据类型之间的强制类型转换. 存在继承关系的父类对象和子类对象之间也可以 在一定条件之下相互转换. 这种转换需要遵守以下原则: 1.子类对象可以被视为是其父类的一个对象2.父类对象不能被 ...

  8. java类的封装、继承、多态

    一.封装(encapsulation) 封装性就是把类(对象)的属性和行为结合成一个独立的相同单位,并尽可能隐蔽类(对象)的内部细节,对外形成一个边界,只保留有限的对外接口使之与外部发生联系.封装的特 ...

  9. java基础-继承

    浏览以下内容前,请点击并阅读 声明 一个由其他类继承的类叫子类(也叫继承类,扩展类等),该类继承的类叫父类或超类.除了Object类意外,所有的类都有切仅有一个父类,如果一个类没有用extends关键 ...

随机推荐

  1. EasyDSS RTMP流媒体服务器中调用videojs播放rtmp视频显示在左上角问题

    本文转自EasyDarwin团队成员Penggy的博客:http://www.jianshu.com/p/f63f5b7c691b 问题描述: 近期我开发了一款新一代的RTMP/HLS流媒体服务器软件 ...

  2. openssl编译出错解决

    tar -jxvf trafficserver-3.0.2.tar.bz2 ./configure --prefix=/usr/install/trafficserver --with-user=ca ...

  3. 機器學習基石 机器学习基石(Machine Learning Foundations) 作业1 习题解答 (续)

    这里写的是  习题1 中的    18 , 19, 20 题的解答. Packet 方法,我这里是这样认为的,它所指的贪心算法是不管权重更新是否会对train data有改进都进行修正,因为这里面没有 ...

  4. Underscore template

    /********************************************************************* * Underscore template * 说明: * ...

  5. Ubuntu下改变文件权限

    Ubuntu下改变权限 有问题,待解决!! 参考:修改linux文件权限命令:chmod 起因:init 0 指令能在普通用户下调用,很方! 指令 chmod 格式: chmod 000 xxx.x ...

  6. Hibernate 一对一 (one-to-one)

    一对一(one-to-one)实例(Person-IdCard) 一对一的关系在数据库中表示为主外关系.例如.人和身份证的关系.每个人都对应一个身份证号.我们应该两个表.一个是关于人信息的表(Pers ...

  7. maven搭建ssm框架问题总结

    1. Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.6.0:compile (default-comp ...

  8. 报错 Inferred type 'S' for type parameter 'S' is not within its bound; 解决办法

    出现情况: Inferred type 'S' for type parameter 'S' is not within its bound; should extends xxxxxx 出现这种问题 ...

  9. flask第八篇——url_for【1】

    我们已经知道,知道了url就可以找到对应的视图函数,那么现在问题来了,如果我们知道了视图函数,要怎么找到url呢?这时候我们就需要url_for函数了. # coding: utf-8 from fl ...

  10. 从数据库导出数据到excel之List<List<Object>>导出

    说明:有时候数据处理为List<List<Object>>更方便 姊妹篇:从数据库导出数据到excel之List<Map<>>导出 兄弟篇:从数据库导出 ...