AS3 中的函数重载
Function Overloading in AS3
刚在网上看到as3不支持函数重载。我在网站上查看了与此相关的问题,但答案似乎不够清楚,无法解决我的问题。
我尝试通过以下方式重载事件 class:
public function SelectEvent(type:String, selecteditem:Buyer, bubbles:Boolean=false, cancelable:Boolean=false)
{
super(type,bubbles,cancelable);
selectedbuyer = selecteditem;
}
public function SelectEvent(type:String, selecteditem:Shop, bubbles:Boolean=false, cancelable:Boolean=false)
{
super(type,bubbles,cancelable);
selectedshop = selecteditem;
}
我不知道如何在不重载的情况下使它工作,这与 AS3 不兼容。
另外,我有一个 returning 函数 :
override public function clone():Event
{
return new SelectEvent (type, selecteditem, bubbles, cancelable);
}
如何 return 不同的参数对应不同的项目?如果买方通过,买方需要 returned。如果通过了 Shop,则需要对 shop 进行 returned。此外,买家和商店都是电影剪辑。有没有办法通过将它们称为电影剪辑然后区分它们来做到这一点?
您不能在 as3 中重载函数,但您可以将参数作为对象传递并检查类型:
public function SelectEvent(type:String, selecteditem:Object, bubbles:Boolean=false, cancelable:Boolean=false)
{
super(type,bubbles,cancelable);
if(selecteditem is Shop) {
selectedshop = selecteditem as Shop
} else if(selecteditem is Buyer) {
selectedbuyer = selecteditem as Buyer
}
}
答案是多态。
不要将参数键入 Buyer
或 Shop
,您应该使用两者的超类型。
是的,Object
是一切的超类型,因为每个对象都是Object
类型(顾名思义)。 Buyer
或 Shop
都扩展了 Object
。没有办法解决它。但是,通过这种方式,您可以直接将 所有内容 传递给您的事件。它看起来像那样。
public class SelectEvent extends Event
{
private var selectedObject:Object; // I prefer camelCase (new words in the name start with capital letter)
public function SelectEvent(type:String, selectedItem:Object, bubbles:Boolean=false, cancelable:Boolean=false)
{
super(type,bubbles,cancelable);
selectedObject = selectedItem;
}
如您所见,此处的目标是使用与您的两种类型都兼容的类型。 Object
就是这样一种类型,因为您的两种类型都扩展了它。您总是可以传递一个更专业的类型(也就是您的类型),而不是一个不太专业的类型(也就是对象)。
使用兼容类型的相同方法的不同解决方案是使用 interface。
接口基本上只是功能列表。它甚至不包括如何实现这些功能。一个简单的例子是驾驶执照。有驾照的人可以开车、停车等。如果 class 执行接口列出的所有操作,它就可以实现该接口。这就像获得驾驶执照一样,因为你已经证明你可以开车、停车等。
什么类型的对象在幕后实现这些功能并不重要,只要有东西就可以。
根据上面的定义,自动驾驶汽车可以获得驾驶执照,即使它不是人类并且与人类没有太多共同之处。它能够完成获得驾驶执照所必需的那些事情。这就是最重要的。
请记住,此功能列表很可能是空的。
那么让我们创建一个空接口:
package
{
public interface ISelectable // start with capital I, then capital first letter of name by convention
{
}
}
就像class一样,接口是类型。在这种情况下,您的 select 事件期望的类型:
public class SelectEvent extends Event
{
private var selected:ISelectable;
public function SelectEvent(type:String, selectedItem:ISelectable, bubbles:Boolean=false, cancelable:Boolean=false)
{
super(type,bubbles,cancelable);
selected = selectedItem;
}
为了通过 Buyer
或 Shop
,它们必须是 ISelectable
类型。因此他们必须实施它:
public class Buyer extends Whatever implements ISelectable
和
public class Shop extends Whatever implements ISelectable
请注意,super class 是什么并不重要。再次声明:接口不关心继承。
当 Object 用更少的代码完成几乎相同的事情时,使用接口有什么意义?
重点是接口定义明确。如前所述,Object 允许您传递所有内容。即使是没有任何意义的事情。
问题是您首先创建该事件的原因。您想要监听该事件,以便在 某事 被 select 编辑时收到通知。这就是我可以从您使用的名称中看出的。但是然后呢?你想用那些 selected 的东西做什么?
这是一个示例场景:无论什么时候 selected,它都应该改变它的外观。
您现在可以做的是将这些东西添加到界面中:
包裹
{
public interface ISelectable // 以大写 I 开头,然后按照约定大写名字的首字母
{
函数 selected():void;
函数 deselected():void;
}
}
现在您的 class 和 都必须 具有这些方法才能实现接口。每个人对 selected 的反应都不同。在下文中,我假设它们都是 Sprite
对象,在 selected 或取消选择时会改变它们的外观。
public class Buyer extends Sprite implements ISelectable
{
public function selected():void
{
alpha = 1; // fully visible
}
public function deselected():void
{
alpha = .5; // transparent
}
或者像这样:
public class Shop extends Sprite implements ISelectable
{
public function selected():void
{
x += 10; // move to right a bit
}
public function deselected():void
{
x -= 10; // move back
}
不同之处在于接口将保证对象能够执行承诺的事情。当你雇用一个有驾照的人时,他可能是一个人、一辆自动驾驶汽车、一个机器人,甚至是一只猴子。你不知道它会是什么,但你可以保证无论它是什么外星人,它都能开车、停车等等
对于一个对象,你没有那个保证,因为它可能是一切。
上述接口的用例可能如下所示:
使用此修改后的事件 class 检索 selected 项目和类型常量:
public class SelectEvent extends Event
{
public const SELECTED:String = "selected";
private var selected:ISelectable;
public function SelectEvent(type:String, selectedItem:ISelectable, bubbles:Boolean=false, cancelable:Boolean=false)
{
super(type,bubbles,cancelable);
selected = selectedItem;
}
public function get selectedItem():ISelectable
{
return selected;
}
侦听该类型的事件:
addEventListener(SelectEvent.SELECTED, onSelected);
function onSelected(event:SelectEvent):void
{
event.selectedItem.selected();
}
其他答案很可靠,适用于多种编程语言,但这种方法在 AS3 中也很常见,不需要类型转换:
public class SelectedEvent {
public static const SELECTED_BUYER:String = "selectedBuyer";
public static const SELECTED_SELLER:String = "selectedSeller";
public var buyer:Buyer;
public var seller:Seller;
public function SelectEvent(type:String, bubbles:Boolean=false, cancelable:Boolean=false)
{
super(type,bubbles,cancelable);
}
}
//[...]
var evt:SelectedEvent = new SelectedEvent(SelectedEvent.SELECTED_BUYER);
evt.buyer = selectedBuyer;
dispatchEvent(evt);
这种方法的缺点显然是 它不能强制您在调度事件之前为属性设置值。当我有大量事件时,我更喜欢这种方法,这些事件在逻辑上似乎应该分组在相同的 class 下,但每个事件需要不同的属性。
或者,如果出于某种原因您需要使用相同的事件,而不管用户选择的是买家还是卖家,您可以这样处理:
private function selectedEventHandler(event:SelectedEvent):void {
if (event.buyer) {
//do stuff here
} else if (event.seller) {
//do other stuff here
}
}
这再次避免了类型转换的需要(尽管您可能会争辩说这种方法并没有更好)
我认为 Adobe 是这样做的:
public function SelectEvent(type:String, selectedBuyer:Buyer = null, selectedSeller:Seller = null, bubbles:Boolean=false, cancelable:Boolean=false)
{
super(type,bubbles,cancelable);
this.buyer = selectedBuyer;
this.seller = selectedSeller;
}
}
但我讨厌凌乱的构造函数。
刚在网上看到as3不支持函数重载。我在网站上查看了与此相关的问题,但答案似乎不够清楚,无法解决我的问题。
我尝试通过以下方式重载事件 class:
public function SelectEvent(type:String, selecteditem:Buyer, bubbles:Boolean=false, cancelable:Boolean=false)
{
super(type,bubbles,cancelable);
selectedbuyer = selecteditem;
}
public function SelectEvent(type:String, selecteditem:Shop, bubbles:Boolean=false, cancelable:Boolean=false)
{
super(type,bubbles,cancelable);
selectedshop = selecteditem;
}
我不知道如何在不重载的情况下使它工作,这与 AS3 不兼容。
另外,我有一个 returning 函数 :
override public function clone():Event
{
return new SelectEvent (type, selecteditem, bubbles, cancelable);
}
如何 return 不同的参数对应不同的项目?如果买方通过,买方需要 returned。如果通过了 Shop,则需要对 shop 进行 returned。此外,买家和商店都是电影剪辑。有没有办法通过将它们称为电影剪辑然后区分它们来做到这一点?
您不能在 as3 中重载函数,但您可以将参数作为对象传递并检查类型:
public function SelectEvent(type:String, selecteditem:Object, bubbles:Boolean=false, cancelable:Boolean=false)
{
super(type,bubbles,cancelable);
if(selecteditem is Shop) {
selectedshop = selecteditem as Shop
} else if(selecteditem is Buyer) {
selectedbuyer = selecteditem as Buyer
}
}
答案是多态。
不要将参数键入 Buyer
或 Shop
,您应该使用两者的超类型。
是的,Object
是一切的超类型,因为每个对象都是Object
类型(顾名思义)。 Buyer
或 Shop
都扩展了 Object
。没有办法解决它。但是,通过这种方式,您可以直接将 所有内容 传递给您的事件。它看起来像那样。
public class SelectEvent extends Event
{
private var selectedObject:Object; // I prefer camelCase (new words in the name start with capital letter)
public function SelectEvent(type:String, selectedItem:Object, bubbles:Boolean=false, cancelable:Boolean=false)
{
super(type,bubbles,cancelable);
selectedObject = selectedItem;
}
如您所见,此处的目标是使用与您的两种类型都兼容的类型。 Object
就是这样一种类型,因为您的两种类型都扩展了它。您总是可以传递一个更专业的类型(也就是您的类型),而不是一个不太专业的类型(也就是对象)。
使用兼容类型的相同方法的不同解决方案是使用 interface。
接口基本上只是功能列表。它甚至不包括如何实现这些功能。一个简单的例子是驾驶执照。有驾照的人可以开车、停车等。如果 class 执行接口列出的所有操作,它就可以实现该接口。这就像获得驾驶执照一样,因为你已经证明你可以开车、停车等。 什么类型的对象在幕后实现这些功能并不重要,只要有东西就可以。
根据上面的定义,自动驾驶汽车可以获得驾驶执照,即使它不是人类并且与人类没有太多共同之处。它能够完成获得驾驶执照所必需的那些事情。这就是最重要的。
请记住,此功能列表很可能是空的。 那么让我们创建一个空接口:
package
{
public interface ISelectable // start with capital I, then capital first letter of name by convention
{
}
}
就像class一样,接口是类型。在这种情况下,您的 select 事件期望的类型:
public class SelectEvent extends Event
{
private var selected:ISelectable;
public function SelectEvent(type:String, selectedItem:ISelectable, bubbles:Boolean=false, cancelable:Boolean=false)
{
super(type,bubbles,cancelable);
selected = selectedItem;
}
为了通过 Buyer
或 Shop
,它们必须是 ISelectable
类型。因此他们必须实施它:
public class Buyer extends Whatever implements ISelectable
和
public class Shop extends Whatever implements ISelectable
请注意,super class 是什么并不重要。再次声明:接口不关心继承。
当 Object 用更少的代码完成几乎相同的事情时,使用接口有什么意义?
重点是接口定义明确。如前所述,Object 允许您传递所有内容。即使是没有任何意义的事情。
问题是您首先创建该事件的原因。您想要监听该事件,以便在 某事 被 select 编辑时收到通知。这就是我可以从您使用的名称中看出的。但是然后呢?你想用那些 selected 的东西做什么?
这是一个示例场景:无论什么时候 selected,它都应该改变它的外观。
您现在可以做的是将这些东西添加到界面中: 包裹 { public interface ISelectable // 以大写 I 开头,然后按照约定大写名字的首字母 { 函数 selected():void; 函数 deselected():void; } }
现在您的 class 和 都必须 具有这些方法才能实现接口。每个人对 selected 的反应都不同。在下文中,我假设它们都是 Sprite
对象,在 selected 或取消选择时会改变它们的外观。
public class Buyer extends Sprite implements ISelectable
{
public function selected():void
{
alpha = 1; // fully visible
}
public function deselected():void
{
alpha = .5; // transparent
}
或者像这样:
public class Shop extends Sprite implements ISelectable
{
public function selected():void
{
x += 10; // move to right a bit
}
public function deselected():void
{
x -= 10; // move back
}
不同之处在于接口将保证对象能够执行承诺的事情。当你雇用一个有驾照的人时,他可能是一个人、一辆自动驾驶汽车、一个机器人,甚至是一只猴子。你不知道它会是什么,但你可以保证无论它是什么外星人,它都能开车、停车等等
对于一个对象,你没有那个保证,因为它可能是一切。
上述接口的用例可能如下所示:
使用此修改后的事件 class 检索 selected 项目和类型常量:
public class SelectEvent extends Event
{
public const SELECTED:String = "selected";
private var selected:ISelectable;
public function SelectEvent(type:String, selectedItem:ISelectable, bubbles:Boolean=false, cancelable:Boolean=false)
{
super(type,bubbles,cancelable);
selected = selectedItem;
}
public function get selectedItem():ISelectable
{
return selected;
}
侦听该类型的事件:
addEventListener(SelectEvent.SELECTED, onSelected);
function onSelected(event:SelectEvent):void
{
event.selectedItem.selected();
}
其他答案很可靠,适用于多种编程语言,但这种方法在 AS3 中也很常见,不需要类型转换:
public class SelectedEvent {
public static const SELECTED_BUYER:String = "selectedBuyer";
public static const SELECTED_SELLER:String = "selectedSeller";
public var buyer:Buyer;
public var seller:Seller;
public function SelectEvent(type:String, bubbles:Boolean=false, cancelable:Boolean=false)
{
super(type,bubbles,cancelable);
}
}
//[...]
var evt:SelectedEvent = new SelectedEvent(SelectedEvent.SELECTED_BUYER);
evt.buyer = selectedBuyer;
dispatchEvent(evt);
这种方法的缺点显然是 它不能强制您在调度事件之前为属性设置值。当我有大量事件时,我更喜欢这种方法,这些事件在逻辑上似乎应该分组在相同的 class 下,但每个事件需要不同的属性。
或者,如果出于某种原因您需要使用相同的事件,而不管用户选择的是买家还是卖家,您可以这样处理:
private function selectedEventHandler(event:SelectedEvent):void {
if (event.buyer) {
//do stuff here
} else if (event.seller) {
//do other stuff here
}
}
这再次避免了类型转换的需要(尽管您可能会争辩说这种方法并没有更好)
我认为 Adobe 是这样做的:
public function SelectEvent(type:String, selectedBuyer:Buyer = null, selectedSeller:Seller = null, bubbles:Boolean=false, cancelable:Boolean=false)
{
super(type,bubbles,cancelable);
this.buyer = selectedBuyer;
this.seller = selectedSeller;
}
}
但我讨厌凌乱的构造函数。