经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » Java相关 » Java » 查看文章
Java中的对象转型
来源:cnblogs  作者:Joker1937  时间:2018/10/15 9:30:17  对本文有异议

向上转型:子类对象转为父类,父类可以是接口。公式:Father f = new Son();Father是父类或接口,son是子类。

向下转型:父类对象转为子类。公式:Son s = (Son)f;

我们将形参设为父类Animal类型,当执行test.f(c)时,内存情况如下图:

c作为Cat类型传入,Animal a作为形参,相当于执行了Animal a = new Cat(),这时a和c同时指向Cat对象,但此时a不能访问Cat类扩展的数据成员,所以再将a强转成Cat类型即可。如果不存在这样的转型机制,则针对猫和狗我们还要分别写两个函数f(Cat c)和f(Dog d)。但其实上图程序的可扩展性也不是最好的。我们还可以利用动态绑定(即多态)将扩展性进一步提升。多态机制的三个前提分别是:(1)要有继承,(2)要重写,即子类对父类中某些方法进行重新定义,(3)要向上转型,用父类引用指向子类对象。下面来看一个例子:

  1. class Animal {private String name;/** * 在Animal类自定义的构造方法
  2.      * @param name     */Animal(String name) {this.name = name;
  3.     }/** * 在Animal类里面自定义一个方法enjoy     */public void enjoy() {
  4.         System.out.println("动物的叫声……");
  5.     }
  6. }class Cat extends Animal {private String eyesColor;/** * 在子类Cat里面定义Cat类的构造方法
  7.      * @param n
  8.      * @param c     */Cat(String n, String c) {/** * 在构造方法的实现里面首先使用super调用父类Animal的构造方法Animal(String name)。
  9.          * 把子类对象里面的父类对象先造出来。         */super(n);
  10.         eyesColor = c;
  11.     }/** * 子类Cat对从父类Animal继承下来的enjoy方法不满意,在这里重写了enjoy方法。     */public void enjoy() {
  12.         System.out.println("我养的猫高兴地叫了一声……");
  13.     }
  14. }/**
  15.  * 子类Dog从父类Animal继承下来,Dog类拥有了Animal类所有的属性和方法。
  16.  * @author gacl
  17.  * */class Dog extends Animal {/** * 在子类Dog里面定义自己的私有成员变量     */private String furColor;/** * 在子类Dog里面定义Dog类的构造方法
  18.      * @param n
  19.      * @param c     */Dog(String n, String c) {/** * 在构造方法的实现里面首先使用super调用父类Animal的构造方法Animal(String name)。
  20.          * 把子类对象里面的父类对象先造出来。         */super(n);
  21.         furColor = c;
  22.     }/** * 子类Dog对从父类Animal继承下来的enjoy方法不满意,在这里重写了enjoy方法。     */public void enjoy() {
  23.         System.out.println("我养的狗高兴地叫了一声……");
  24.     }
  25. }/**
  26.  * 子类Bird从父类Animal继承下来,Bird类拥有Animal类所有的属性和方法
  27.  * @author gacl
  28.  * */class Bird extends Animal {/** * 在子类Bird里面定义Bird类的构造方法     */Bird() {/** * 在构造方法的实现里面首先使用super调用父类Animal的构造方法Animal(String name)。
  29.          * 把子类对象里面的父类对象先造出来。         */super("bird");
  30.     }/** * 子类Bird对从父类Animal继承下来的enjoy方法不满意,在这里重写了enjoy方法。     */public void enjoy() {
  31.         System.out.println("我养的鸟高兴地叫了一声……");
  32.     }
  33. }/**
  34.  * 定义一个类Lady(女士)
  35.  * @author gacl
  36.  * */class Lady {/** * 定义Lady类的私有成员变量name和pet     */private String name;private Animal pet;/** * 在Lady类里面定义自己的构造方法Lady(),
  37.      * 这个构造方法有两个参数,分别为String类型的name和Animal类型的pet,
  38.      * 这里的第二个参数设置成Animal类型可以给我们的程序带来最大的灵活性,
  39.      * 因为作为养宠物来说,可以养猫,养狗,养鸟,只要是你喜欢的都可以养,
  40.      * 因此把它设置为父类对象的引用最为灵活。
  41.      * 因为这个Animal类型的参数是父类对象的引用类型,因此当我们传参数的时候,
  42.      * 可以把这个父类的子类对象传过去,即传Dog、Cat和Bird等都可以。
  43.      * @param name
  44.      * @param pet     */Lady(String name, Animal pet) {this.name = name;this.pet = pet;
  45.     }/** * 在Lady类里面自定义一个方法myPetEnjoy()
  46.      * 方法体内是让Lady对象养的宠物自己调用自己的enjoy()方法发出自己的叫声。     */public void myPetEnjoy() {
  47.         pet.enjoy();
  48.     }
  49. }public class Jerque {public static void main(String args[]) {/** * 在堆内存里面new了一只蓝猫对象出来,这个蓝猫对象里面包含有一个父类对象Animal。         */Cat c = new Cat("Catname", "blue");/** * 在堆内存里面new了一只黑狗对象出来,这个黑狗对象里面包含有一个父类对象Animal。         */Dog d = new Dog("Dogname", "black");/** * 在堆内存里面new了一只小鸟对象出来,这个小鸟对象里面包含有一个父类对象Animal。         */Bird b = new Bird();/** * 在堆内存里面new出来3个小姑娘,名字分别是l1,l2,l3。
  50.     * l1养了一只宠物是c(Cat),l2养了一只宠物是d(Dog),l3养了一只宠物是b(Bird)。
  51.          * 注意:调用Lady类的构造方法时,传递过来的c,d,b是当成Animal来传递的,
  52.          * 因此使用c,d,b这三个引用对象只能访问父类Animal里面的enjoy()方法。         */Lady l1 = new Lady("l1", c);
  53.         Lady l2 = new Lady("l2", d);
  54.         Lady l3 = new Lady("l3", b);/** * 这三个小姑娘都调用myPetEnjoy()方法使自己养的宠物高兴地叫起来。         */l1.myPetEnjoy();
  55.         l2.myPetEnjoy();
  56.         l3.myPetEnjoy();
  57.     }
  58. }

上面的例子中,我们发现,如果我们想要加入新的动物,只需定义相应的类继承Animal,完全不用动任何一处代码,因为这里运用了面向对象最核心的东西——多态。与之前的例子不同,虽然我们一直强调当用父类的引用指向子类对象,父类无法访问子类自己的成员,但是方法与数据成员不同,具体调哪一个方法是等到运行时决定的,new出了什么对象就调用相应对象的方法,取决于实际new出的对象而不是指向对象的引用,所以当传入不同动物类型,mypetEnjoy()就会去执行不同的方法。

 

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号