基类派生类的设计问题

由于业务需求,现有

基类A,派生类A1、A2
基类B,派生类B1、B2

目前是基类A持有基类B,但是业务上需要A1持有B1,A2持有B2,怎样设计会比较好?

谢谢

阅读 3.9k
6 个回答

鄙人抽象思考能力有限,所以我还是得把AB两个类对应到具体的东西来思考:

Arm(武器): Mauser(毛瑟), Rifle(来福), Revolver(左轮), Pistol(手枪)

clipboard.png

Bullet: Gold, Silver (wow!!), Copper
clipboard.png

@边城 我给出的解决方案使用了泛型,主要是提供另一种思路。不一定比不用泛型简洁。

但是业务上需要A1持有B1,A2持有B2

由于业务相关信息在问题中不很清楚,我做个假设--除了持有之外,并不对B1,B2做customized的操作。

如果上面得假设不合理,请指出。我可以再改进方案。

// B是一个上限是Bullet的泛型。我们可以初始化
// Arm<GoldBullet>, Arm<SilverBullet>, ...
// 与List<E>类似,不过E没有上限。
class Arm <B extends Bullet> {
  // ammunition
  private List<B> bullets = new ArrayList<>();
  public void fire() {
    bullets.forEach((b) -> {
      System.out.println("fire!!! "+b.toString());
    });
  }

  public void addBullet(B b) {
    bullets.add(b);
  }
}

class Rifle extends Arm <GoldBullet> {   
}


class Pistol extends Arm <SilverBullet>{  
}

// 对Rifle和Pistol的具体使用
final Rifle rifle = new Rifle();
rifle.addBullet(new GoldBullet()); // OK!!

// Nope... Buddy, there's no silver bullet for you.
// 狼人来了...
rifle.addBullet(new SilverBullet()); 

根据业务功能拆分出接口来

给你一个参考方案,另外也可以考虑用泛型来处理。不管 Java 的泛型我不太熟,等其他高人了

class B {}
class B1 extends B {}
class B2 extends B {}

class A {
    B data;
    B getData() {
        return data;
    }
    void setData(B b) {
        data = b;
    }
}

class A1 extends A {
    B1 data;
    B1 getData() {
        return (B1) super.getData();
    }
    void setData(B1 b) {
        super.setData(b);
    }
    void setData(B b) {
        if (!(b instanceof B1)) {
            throw new ClassCastException();
        }
        super.setData(b);
    }
}

这个采用泛型可以很好地解决问题

class A<T extends B> {
    private T b;
    public T getB() {
        return b;
    }
}

class B {
    
}

class A1 extends A<B1>{
    
}

class B1 extends B{}

class A2 extends A<B2>{}

class B2 extends B{}

不知道这个是不是你要的:

public class B {
}
public class B1 extends B {
}
public class B2 extends B {
}
public class A <T extends B> {
    private T data;
    public T getData(){ return data;}

    public void setData(T data) {
        this.data = data;
    }
}

public class Main {
    public static void main(String[] args) {
        A<B1> a1 = new A<B1>();
        A<B2> a2 = new A<B2>();
        a1.setData(new B1());
        a2.setData(new B2());
        // .....
    }
}

使用泛型,A这边不需要继承结构。

按楼上的范型吧,不过也要注意范型的问题~~

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题