为什么编译器允许超一流的参数的函数 [英] Why should compiler allow super-class of a parameter in a function

查看:108
本文介绍了为什么编译器允许超一流的参数的函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

 公共类ChildClass扩展影片剪辑
{
   公共职能ChildClass()
   {
   }

    公共职能aChildClassFunction()
     {
     }

}

 公共类AnotherChildClass扩展影片剪辑
{
   公共职能ChildClass()
   {
   }

    公共职能aChildClassFunction()
     {
     }

}
 

一些随机函数,要求childClass(但懒惰的程序员只是使用MovieClip类)

 公共职能setChildClassInstance(VAR MC:影片剪辑)
    {
//为什么三菱商事再present并允许作为参数???这是一个超一流的..即。结构的子集的子级。

          mc.aChildClassFunction(); //<<会产生运行时错误的第二个函数调用。

    }
 

上面的功能,可用于任何MovieClip实例也

  VAR childClassInstance:ChildClass;
 VAR anotherChildClassInstance:AnotherChildClass;

 setChildClassInstance(childClassInstance)//<<<<<有效的....没有编译器错误

 setChildClassInstance(anotherChildClassInstance)
  //<<<有效的,编译器错误..但会导致运行时错误!!!!
//
//
//
 

我不知道,怎么来的超级类(影片剪辑这里)被允许和再present themeselves作为参数子类(这里:ChildClass,AnotherChildClass)。尤其是因为,超实际上是子集他们的父母-SET,即。他们的孩子级。

感谢

影片剪辑的
解决方案

通过下面的类,你可以假设动物继承所有属性。

 包{
    进口的flash.display.MovieClip;
    公共类动物扩展影片剪辑{
        公共职能动物(){
            //构造函数code
        }
        公共职能咆哮():无效{
            跟踪('咆哮')
        }
    }
}
 

所以让我们来看看影片剪辑

继承树 <$p$p><$c$c>MovieClip->Sprite->DisplayObjectContainer->InteractiveObject->DisplayObject->EventDispatcher->Object

而现在,我们可以说

<$p$p><$c$c>Animal->MovieClip->Sprite->DisplayObjectContainer->InteractiveObject->DisplayObject->EventDispatcher->Object<br>

当我们输入施放动物的一个实例雪碧。

  VAR精灵:精灵=新的动物()
 

我们失去了在动物IE浏览器中定义的方法:咆哮
这是所有罚款,只要我们不要试图访问继承树上面定义的东西。
请记住,我们可以输入推倒树不起来。照片

使用上述类

  VAR精灵:精灵=新的动物()
sprite.growl()//这将错误,因为精灵不包含
 

现在这里是一个例外。
影片剪辑是动态的,所以类型转换为影片剪辑不会失去增加的方法(咆哮)。

 变种MC:影片剪辑=新的动物()
mc.growl()//跟踪咆哮
 

动态类的定义不能有,因为界面与他们相关的接口是一个合同,以实现他们的类。

public class ChildClass extends MovieClip
{
   public function ChildClass()
   {
   }

    public function aChildClassFunction()
     {
     }

}

 public class AnotherChildClass extends MovieClip
{
   public function ChildClass()
   {
   }

    public function aChildClassFunction()
     {
     }

}

Some random function that asks for childClass ( But a lazy programmer just uses MovieClip class )

    public function setChildClassInstance(var mc:MovieClip) 
    {
// How come "mc" represent and be allowed as parameter ??? It's a super-class.. ie. structurally a sub-set of child-class.

          mc.aChildClassFunction(); //<< Would generate run-time error for 2nd function call. 

    }

The above function can be used for any MovieClip instance also

 var childClassInstance:ChildClass ;
 var anotherChildClassInstance:AnotherChildClass ; 

 setChildClassInstance( childClassInstance )   // <<<<<VALID,  .... NO COMPILER ERROR 

 setChildClassInstance( anotherChildClassInstance )  
  //<<< VALID, NO COMPILER ERROR ..  BUT WILL CAUSE RUNTIME ERROR !!!! 
//
//
//

I wonder, how come SUPER CLASS (MovieClip here) be allowed and represent themeselves as parameter for child-classes ( here: ChildClass, AnotherChildClass). Especially because, "SUPERCLASSES" actually are "SUB-SET" of their PARENT-SET , ie. their child-class.

Thanks

解决方案

With the following class you can assume the Animal has inherited all the properties of of MovieClip.

package  {
    import flash.display.MovieClip;
    public class Animal extends MovieClip{
        public function Animal(){
            // constructor code
        }
        public function growl():void{
            trace('growl')
        }
    }
}

So lets look at the inheritance tree of MovieClip

MovieClip->Sprite->DisplayObjectContainer->InteractiveObject->DisplayObject->EventDispatcher->Object

And now we can say

Animal->MovieClip->Sprite->DisplayObjectContainer->InteractiveObject->DisplayObject->EventDispatcher->Object<br>

When we type cast an instance of Animal to Sprite.

var sprite:Sprite = new Animal()

we lose the methods that are defined in Animal IE:growl
This is all fine as long as we do not try to access anything defined above in the inheritance tree.
Remember we can type cast down the tree not up.

Using the above class

var sprite:Sprite = new Animal()
sprite.growl() // this will error since sprite does not contain

Now here is an exception to the rule.
MovieClip is dynamic so type casting as MovieClip will not lose the added method(growl).

var mc:MovieClip = new Animal()
mc.growl() // traces growl

Dynamic classes by definition can not have an interfaces associated with them since an interface is a contract to a class that implements them.

这篇关于为什么编译器允许超一流的参数的函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆