结合两个相同的子类

时间:2013-02-07 17:55:15

标签: flex oop

所以我有两个子类在Flex中扩展不同的基类,我怎么能把它们组合在一起,这样我才不会重复自己。

基本上我有类似

的东西
public class A extends B {
 // methods
}

public class C extends D {
 // same methods as class A
}

任何组合方式,以便我不会重复相同的代码两次。

3 个答案:

答案 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(),...方法出现在两个不同的类中。这就提出了这样一种可能性,即它们可能与这些类的状态无关。如果是这样,那么更好的解决方案是将它们完全删除到新的类中。

如果你这样做,

  1. 您还将删除两个类A和C,它们现在仅用于此目的。
  2. 你摆脱了两种继承关系。这使您的代码更加简单。
  3. 而且,你将实现不重复自我的目标。
  4. -

    //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>

我的直觉是,如果你经常遇到这个问题;您可能遇到需要进行重构的对象模型的问题。