设计问题:增强代码可重用性的特定案例

3
我有几个View的子类实例(如ImageView、ViewGroup、TextView等),它们都实现了a()和b()两种方法,并且它们都必须运行相同的init()方法,该方法很长且对它们所有的实例都是一样的。 在这种情况下,我应该如何设计我的架构以增强代码的可重用性?
如果使用C++,我可以从View和一个新的抽象类中多重继承,并在创建时运行init(),并具有抽象方法a()和b()。那么在Java中如何实现呢?
也许有一种通过某种装饰器来实现的方式?

我会创建一个单独的“Globals”类,您可以在其中放置将由多个活动使用的方法,并从需要它们的类中调用它们。在每个类中需要时,只需调用“Globals.a()”。 - codeMagic
1
我完全不同意那种做法。 - AHungerArtist
@codeMagic 这是结构化编程,应该避免使用。 - LuGo
4个回答

1
如果我理解正确的话,您可以创建一个抽象类AbstractView,它扩展了View并实现了您的通用init()方法。AbstractView应该声明抽象方法a()b(),但是将实现留给子类。
public abstract class AbstractView extends View {
    public void init() {
        // common init implementation here
    }

    public abstract void a();
    public abstract void b();
}

由于您正在尝试向一组现有的子类(ImageViewViewGroupTextView等)添加行为,因此您可能确实需要为每个子类创建一个包装器(MyImageViewMyViewGroupMyTextView等)。这些子类中的每一个都将扩展AbstractView并实现自己的a()b()方法,但继承公共的init()方法(以及在View类中实现的所有方法)。然后,您可以为ImageViewViewGroupTextView等中现有的行为创建委托方法,以保持不变。

public class MyImageView extends AbstractView {

    private ImageView wrappedImageView;

    public MyImageView(Context context) {
        wrappedImageView = new ImageView(context);
    }

    // TODO: Implement other constructor wrappers

    final void clearColorFilter() {
        wrappedImageView.clearColorFilter();
    }

    // TODO: Implement other method wrappers

    @Override
    public void a() {
        // specific implementation here
    }

    @Override
    public void b() {
        // specific implementation here
    }
}

此外,View还可以被声明为一个接口,该接口定义了所有视图应该绑定的契约。 - Arun Manivannan
@ArunManivannan 这是一种可能性,但Android已经有一个View类了。不清楚OP是在扩展它还是从头开始。 - Bill the Lizard
哎呀,没注意到是“Android”标签。对此感到抱歉。 - Arun Manivannan
@OfekRon 哦,我没有意识到 ImageView、ViewGroup、TextView 等都是已经内置的类。 - Bill the Lizard
@OfekRon 请查看我的更新。这很棘手(读作“凌乱”),因为您正在尝试在超类和其子类之间添加新行为。 - Bill the Lizard

0
你需要一个新的抽象类,并带有init()方法:
public abstract class MyAbstractView extends View {
  public void init() {
    //TODO: implement init 
  }
  public abstract void a();
  public abstract void b();
}

让你的类(ImageView、TextView)继承自这个抽象类。


它们不是我的类,ImageView等都是Android内置的,这就是为什么我一开始没有采用这种方法的基本原因。 - Ofek Ron
@OfekRon 如果这些类是内置的,那么你如何实现:_我让它们都实现a()和b()两个方法_。 - LuGo

0

如果我正确理解了你的回答,你应该做的是:

public abstract class MyBaseView extends View{

  public MyBaseView(Context context) {
    super(context);
    init();
    // TODO Auto-generated constructor stub
  }


  private void init(){

  }

  public abstract void a();
  public abstract void b();
}

然后再使用以下方式扩展它:

public class MyView extends MyBaseView{

    public MyView(Context context) {
        super(context);
        // TODO Auto-generated constructor stub
    }

    @Override
    public void a() {
        // TODO Auto-generated method stub

    }

    @Override
    public void b() {
        // TODO Auto-generated method stub

    }

}

0

你可以定义一个类层次结构,其中实现了init()、a()和b()方法。根据层次结构中的子类依次添加内容。最终,你的视图将调用该类上的方法并为自身生成内容。

      interface WidgetContent {
        void init();

        void a();

        void b();
    }

    abstract class AbstractWidgetContent implements WidgetContent  {
        public void init(){}

        public abstract void a();

        public abstract void b();
    }

    class BaseViewWidgetContent extends AbstractWidgetContent {

        public void a() {
        }

        public void b() {
        }

    }

    class ImageViewWidgetContent extends BaseViewWidgetContent {

        public void a() {
        }

        public void b() {
        }
    }

class PictureView extends ImageView{
    ImageViewWidgetContent imageContent;

}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接