所以我有两个子类在Flex中扩展不同的基类,我怎么能把它们组合在一起,这样我才不会重复自己。
基本上我有类似
的东西public class A extends B {
// methods
}
public class C extends D {
// same methods as class A
}
任何组合方式,以便我不会重复相同的代码两次。
答案 0 :(得分:1)
<强> Favor composition over inheritance 强>
所以,问题是,你应该如何撰写解决方案?
一种可能性是使用Decorator模式。这实际上是现有类的包装器。为了使这项工作,您的类可能需要实现一个接口,该接口公开您完成工作所需的任何内容。
类似于:
public interface IFoo {
function get name():String;
function set name(value:String):void;
}
public class A extends B implements IFoo {
protected var _name:String;
public function get name():String {
return _name;
}
public function set name(value:String):void {
_name = value;
}
}
public class C extends D implements IFoo {
protected var _name:String;
public function get name():String {
return _name;
}
public function set name(value:String):void {
if (_value != _name) {
_name = value;
dispatchEvent(new Event('nameChanged'));
}
}
}
public class FooDecorator {
protected var _foo:IFoo;
public function FooDecorator(foo:IFoo) {
_foo = foo;
}
public function sayName():void {
trace('foo name is', _foo.name);
}
}
另一种解决方案是给出封装行为的第五种类型的A和C成员变量(就像Jeffry所说的那样,但我更愿意在可能的情况下服从law of Demeter):
class NameSayer {
function sayName(name:String):void {
trace('foo name is', _foo.name);
}
}
然后
public class A extends B {
public var name:String;
public var sayer:NameSayer;
//note that this method would be identical in both Classes
//but this is OK because the underlying logic is encapsulated
//and can be easily changed
public function sayName():void {
if (sayer) {
sayer.sayName();
}
}
}
我认为很多开发人员热衷于关注DRY,并且正如杰弗里所说,这可能会导致您的架构出现其他更糟糕的问题。这些解决方案中哪些(如果有的话)是合适的,取决于您要完成的目标。
答案 1 :(得分:1)
您有两个实现完全相同方法的子类(扩展不同的父类)。
public class B {}
public class D {}
public class A extends B {
// methods
m1();
m2();
...
}
public class C extends D {
// same methods as class A
m1();
m2();
...
}
现在让我们谈谈它。
现在,在您的情况下,您有m1(),m2(),...方法出现在两个不同的类中。这就提出了这样一种可能性,即它们可能与这些类的状态无关。如果是这样,那么更好的解决方案是将它们完全删除到新的类中。
如果你这样做,
-
//Parent classes (child classes are now gone)
public class B {}
public class D {}
-
// Your new class
public class X {
// methods that previously were in A and C
m1();
m2();
...
}
答案 2 :(得分:0)
虽然,我对它的使用情有不同;你可以使用include指令。
创建一个名为sharedMethods.as(或任何你想要的)的文件。这不是一个真正的阶级;它只包括代码片段:
public var mySharedMethod(mySharedMethodArguments:ArgumentType):void{
// do something
}
然后你可以把它包含在你的其他课程中:
public class A extends B {
include "sharedMethods.as";
}
public class C extends D {
include "sharedMethods.as";
}
您的包含文件中的代码将被编译为A类和C类的一部分。
您还可以将共享代码放在另一个类中,并在A和C中都有该类的实例。然后,您必须编写包装器方法或深入调用类似这样的调用:aInstance.sharedCodeObject.sharedMethod();
< / p>
我的直觉是,如果你经常遇到这个问题;您可能遇到需要进行重构的对象模型的问题。