我刚刚在网上看到as3不支持函数重载。我在网站上看到了与此相关的问题,但答案似乎不足以解决我的问题。
我尝试通过以下方式重载事件类:
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不兼容。
另外,我有一个返回功能:
override public function clone():Event
{
return new SelectEvent (type, selecteditem, bubbles, cancelable);
}
如何针对不同的参数返回不同的项目?如果买方通过,则需要退回买方。如果商店通过,则需要退回商店。此外,买家和商店都是电影剪辑。有没有办法通过将它们称为动画片段来区分它们?
答案 0 :(得分:1)
你不能在as3中重载函数,但你可以将参数作为Object传递并检查类似的类型:
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
}
}
答案 1 :(得分:1)
其他答案非常强大且适用于多种编程语言,但这种方法在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);
这种方法的缺点显然是它不能强制您在调度事件之前为属性设置值。我喜欢这种方法,当我有大量的事件,从逻辑上看,它们应该在同一个类下分组,但每个事件需要不同的属性。
或者,如果出于某种原因,无论用户是选择买家还是卖家,您都需要使用相同的事件,您可以像这样处理:
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;
}
}
但我讨厌凌乱的建设者。
答案 2 :(得分:0)
答案是多态性。
您应该使用两者的超类型,而不是将参数键入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。
接口基本上只是一个功能列表。它甚至不包括如何实现这些功能。一个简单的例子是驾驶执照。拥有许可证的人可以驾驶汽车,停放汽车等。如果一个班级完成了界面列出的所有内容,它就可以实现该界面。这就像收到驾照一样,因为你已经证明你可以开车,停车等。 只要有什么东西可以在幕后实现这些功能,这并不重要。
鉴于上述定义,自驾车可以获得驾驶执照,即使它不是人类,也不会与人类有太多共同之处。它能够做那些获得驾驶执照所必需的东西。这一切都很重要。
请记住,这个功能列表很可能是空的。 所以让我们创建一个空接口:
package
{
public interface ISelectable // start with capital I, then capital first letter of name by convention
{
}
}
就像类一样,接口也是类型。在这种情况下,您选择的事件期望的类型:
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
请注意,超类是什么并不重要。再说一遍:界面不关心继承。
使用界面的重点是什么?当使用较少的代码时,Object几乎完全相同?
关键是界面是明确定义的。如上所述,Object允许您传递所有内容。即使是没有任何意义的事情。
问题是您首先创建该事件的原因。您希望收听该事件,以便在选择某事时收到通知。这就是我从您使用的名称中可以看出的内容。但那又怎样?你想用这些东西做什么?
以下是一个示例场景:每当选择某个内容时,它应该改变它的外观。
您现在可以做的是将这些内容添加到界面: 包 { public interface ISelectable //以大写字母I开头,然后是按照惯例的首字母大写字母 { function selected():void; function deselected():void; } }
现在,您的类必须拥有这些方法才能实现接口。每个人对选择的反应都不同。在下面我假设它们都是Sprite
个对象,它们在选择或去除后会改变它们的外观。
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
}
不同之处在于界面将保证对象能够做出承诺的事情。当你雇用驾驶执照的人时,他可能是一个人,一个自驾车,一个机器人甚至一只猴子。你不知道它会是什么,但你可以保证无论外星人是什么,它都可以开车,停车等等。
使用Object,您没有这种保证,因为它可能就是一切。
上述界面的用例可能如下所示:
使用此修改后的Event类来检索所选项目和类型常量:
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();
}