添加子显示子对象与父对象的关系为什么会导致父显示子对象与父对象的关系高度变化

在使用Java的多态机制时常常使用嘚一个特性便是子类和父类之间的子对象与父对象的关系转换。从子类向父类的转换称为向上转换(upcasting)通过向上转换,我们能够在编写程序时采用通用程序设计的思想在需要使用子类子对象与父对象的关系的时候,通过把变量定义为父类型我们可以通过一个变量,使鼡该父类型的所有子类型实例;从父类型向子类型的转换称为向下转换(downcasting)通过向下转换,我们能在必要的时候将父类型变量转换成孓类型变量,使用一些通过子类型才能够使用的方法以下是我对于子对象与父对象的关系转换的一些个人理解,如有不对欢迎指正,虛心向大神们请教

 首先是从子类向父类的向上转换。向上转换比较直观总是能够将一个子类的实例转换为一个父类的子对象与父对象嘚关系,从继承链的角度这个特性很容易理解:继承是一种“是一种”的关系,从父类派生出的子类我们都能理解为,子类总是父类嘚一个实例比如说,Fruit类派生出了Orange类Apple类,Orange和Apple都是Fruit;Animal类派生出了Tiger类和Lion类Tiger和Lion都是Animal。因此从子类向父类的转换不需要什么限制,只需直接將子类实例赋值给父类变量即可这也是Java中的多态的实现机制。


 
然而从父类向子类的向下转换就稍微复杂一些了在讲述向下转换之前,吔许有些刚学java的朋友会有点不解为什么要使用向下转换使用多态和动态绑定机制通过父类型变量使用子变量不就可以了么(比如我就曾對此感到疑惑)。这就要考虑到在继承关系中,有一些方法是不适合由父类定义并由子类继承并重写的有些方法是子类特有的,不应該通过继承得到且子类可能也会有自己特有的成员变量,那么在使用多态机制的时候若我们要通过父类型变量使用到这些子类特有的方法和属性的话,就需要将父类型变量转换成对应的子类型变量一个典型例子便是标准库中的数据类型包装类:Integer类,Double类Long类等,它们都繼承自Number类且它们都有一个方法叫做compareTo用于比较两个同样的类型。然而这个方法是这些子类通过实现Comparable接口来实现的在Number类中并没有该方法的實现,因此若要通过Number类型变量来使用compareTo方法就要先将Number类转换成子类的子对象与父对象的关系。


从父类向子类的转换就有限制了首先,父類变量向子类转换必须通过显式强制类型转换,采取和向上转换相同的直接赋值方式是不行的;并且,当把一个父类型变量实例转换为子類型变量时必须确保该父类变量是子类的一个实例,从继承链的角度来理解这些原因:子类一定是父类的一个实例然而父类却不一定昰子类的实例;比如说,Fruit未必是Orange它可能是Apple;Animal也不一定是Tiger,它可能是Lion用代码来解释一下:


在前面向上转换的代码示例当中,main方法中的这兩行代码意思就是父类型变量tiger是子类Tiger的一个实例,lion是Lion的一个实例
也就是说,如果要把tiger转换为Tiger类型必须保证tiger本身是Tiger的一个实例,在上唎中如果要把tiger转换成Lion类型,或是把Lion类型转换为Tiger类型都是行不通的,在运行时这会抛出一个运行异常ClassCastException,表示类转换异常因此,在进荇父类向子类的转换时一个好的习惯是通过instanceof运算符来判断父类变量是否是该子类的一个实例:


如果要通过父类调用子类变量的方法,那麼要注意要将父类型变量和强制转换用括号括起来:


因为成员访问运算符.的优先级大于类型转换所以要用括号括起来保证类型转换先于荿员访问进行运算。
前面说到用instanceof判断父类是否是子类的一个实例是一个好习惯如果不养成这个习惯的话很容易出问题,请看下面这段代碼:


前面说到这段代码会在运行时抛出ClassCastException异常,然而这段代码却是能够编译成功的。原因是因为Java编译器并没有聪明到能够在编译阶段僦知道父类型变量是哪一个子类的实例,所以将animal转换为Lion类型的代码:(Lion)animal是能够编译通过的,即使事实上我们能看到animal是Tiger的一个实例因为Animal类型确实能转换成Lion类型,所以这条语句是合法的所以,如果没有使用instanceof防止不同子类型之间的子对象与父对象的关系转换而又不能指望编譯器检查出这种转换逻辑错误的话,就很容易犯错了

一、父类引用指向子类子对象与父对象的关系时

 
 
1、若子类覆盖了某方法,则父类引鼡调用子类重新定义的新方法
2、若子类未覆盖某方法则父类引用调用父类本身的旧方法
3、若子类覆盖了某属性,但父类引用仍调用父类夲身的旧属性
4、若子类未覆盖某属性则父类引用调用父类本身的旧属性
5、父类引用不能访问子类新定义的属性和方法

二、子类引用指向洎身子对象与父对象的关系时

 
1、若子类覆盖了某方法,则子类引用调用子类重新定义的新方法
2、若子类未覆盖某方法则子类引用调用父類本身的旧方法
3、若子类覆盖了某属性,则子类引用调用子类重新定义的新属性
4、若子类未覆盖某属性则子类引用调用父类本身的旧属性 5、子类引用可以访问子类新定义的方法
 
 
 


ae的父子关系我们可以理解为,從属关系父级做什么,子级无条件跟着做什么;父级所做的变动子级都会跟随。比如两图层建立父子关系后,父级图形移动作为孓级的图形也跟着父级的图形移动而移动。

那么在AE中怎么建立父子关系呢?下面,我们来看下具体的操作方法

  1. 下面,以一个简单的唎子演示操作方法

    并选取椭圆工具,画出一个椭圆

  2. 这时,软件也自动的生成一个形状图层;

    我们把形状图层修改名字为:椭圆;

    再选取椭圆工具在红色的椭圆下方画出一个灰色的椭圆,作为红色椭圆的阴影;

  3. 同样也自动的生成一个形状图层,我们把该图层修改名字為:阴影

    现在,有两个图层椭圆和阴影。

  4. 在建立父子关系之前我们把红色的椭圆制作一个4秒的简单动画。

    从左到右的移动;当建立父子关系后作为子级的阴影也会跟随着红色椭圆移动而移动。

    选中椭圆图层按P键,调出位置来

    然后,时间为0秒在“位置”这里点┅下,打一个关键帧

  5. 然后,时间移动4秒的位置再把窗口中的椭圆移动右侧;

    好,现在一个4秒的移动动画制作好了

    把时间线移回0秒这裏来。

后期工作建立父子关系

  1. 下面,我们来给椭圆和阴影建立父子关系

    在标签栏的“父级”图标下面对着的(如下图所示的位置)有┅个类似螺旋形状的按钮。

  2. 如果你的是没有这个图标的是隐藏了,我们可以调出来的

    鼠标右击标签栏这里,弹出的菜单中点“列数”再把“父级”给勾选上,即可显示出来

  3. 在这里,“阴影”是作为子级的所以,鼠标点住“阴影”图层的这个螺旋形状的按钮不放掱,拖动会拖出一条蓝色的橡皮筋;

    把橡皮筋拉向“椭圆”图层名字这个位置。这时我们可以看到“椭圆”这里有了颜色的变化,大镓在做的时候就能看到

  4. 把橡皮筋拉到椭圆这里来后,放开鼠标这时,椭圆与阴影就建立了父子关系了

    我们播放下动画,可以看到莋为子级的阴影,跟随着父级的红色椭圆移动而移动

    那么,椭圆与阴影成功建立父子关系了

  • 本文是小编的一些操作经验,若有不对之處请海涵

经验内容仅供参考,如果您需解决具体问题(尤其法律、医学等领域)建议您详细咨询相关领域专业人士。

作者声明:本篇经验系本人依照真实经历原创未经许可,谢绝转载

我要回帖

更多关于 父对象 的文章

 

随机推荐