7

我有一个类(Base)和一个 InfoBase 类型的字段,其中包含一些信息。Base 的专业化(Ext)需要保存附加信息(InfoExt)。因此,Ext 将 InfoExt 分配给 Base.info。但是,当 Base 替换 info 时我遇到了问题,因为它会分配info = new InfoBase()因此 InfoExt 的附加信息丢失。

因此,我创建了一个abstract void assign()in Base(变体 A)。在这种情况下,每次在 Ext 中使用时,都需要将 info 转换为 InfoExt。

因此,在变体 BI 中还创建了abstract InfoBase info().

                             variant A                        variant B
+----------------+  +---------------------------+  +----------------------------+
| InfoBase       |  | Base                      |  | Base'                      |
|----------------|  |---------------------------|  |----------------------------|
| + name: String |  | + info: InfoBase          |  | + abstract InfoBase info() |
|                |  | + abstract void assign()  |  | + abstract void assign()   |
|                |  |                           |  |                            |
+----------------+  +---------------------------+  +----------------------------+
          ^                      ^                               ^
          |                      |                               |
          +                      +                               +
+----------------+  +---------------------------+  +----------------------------+
| InfoExt        |  | Ext                       |  | Ext'                       |
|----------------|  |---------------------------|  |----------------------------|
| + id: int      |  | + void assign() {         |  | + InfoExt info             |
|                |  |     info = new InfoExt(); |  | + InfoBase info() {        |
|                |  |   }                       |  |     return info;           |
+----------------+  +---------------------------+  |   }                        |
                                                   | + void assign() {          |
                                                   |     info = new InfoExt();  |
                                                   |   }                        |
                                                   +----------------------------+

.

 class InfoBase {
   public String name;
 }

 abstract class Base {
    abstract public void assign();
    abstract InfoBase info();
 }


 class InfoExt extends InfoBase {
   public int id;
 }

 class Ext extends Base {
    public InfoExt info;

    @Override InfoBase info() { return info; }

    @Override public void assign() { info = new InfoExt(); }
 }

这是一种常见的情况,用通用的方法如何处理?变体 A/B 有什么缺点吗?

如何在 Base 中提供一个 info 字段,子类可以用来存储扩展信息?

谢谢您的考虑

4

4 回答 4

1

也许这样的东西是你正在寻找的?

abstract class Base {
    private InfoBase info; 

    abstract public void assign();

    protected void setInfo(InfoBase info) {
        this.info = info;
    }

    public InfoBase getInfo() { 
        return info;
    }
}

class Ext extends Base {
    private InfoExt info;

    @Override 
    public InfoExt getInfo() { 
        return info;
    }

    @Override
    public void assign() {
        info = new InfoExt();
        setInfo(info);
    }

}

这将允许 Base 服务InfoBase对象,而 Ext 可以服务InfoExt

于 2013-01-08T14:59:10.947 回答
0

如果您有一个 InfoBase 的子类,它的数据将被主要访问,您应该将 Base Class 中的属性“info”类型更改为 InfoExt。

在不久的将来,也许你会有任何其他具有不同数据和行为的 InfoBase 子类,你怎么做?在这种情况下,我建议你使用 GOF 的 Bridge-Pattern,它会帮助你解决它。

于 2013-01-08T14:57:54.783 回答
0

我不完全理解你的问题,但这里有一个提示:

通常,在实例化 Base 子类时,您将让每个子类在子类覆盖的第二种方法(初始化或类似方法)中执行其特定语句。因此,例如,每个子类将使用特定的InfoBase子类实例化信息

之后,Ext应该只覆盖需要 InfoBase 特定行为的方法,将info转换为正确的类。

这是最简单的设计。由于我不知道您的代码的复杂性,因此无法为您提供更具体的解决方案;但您也可以考虑使用适配器模式、策略或状态(当然取决于要解决的问题)。

于 2013-01-08T15:12:15.100 回答
0

如果您正在寻找一种避免强制转换的方法,这可能有效(使用泛型):

public abstract class Base<T extends InfoBase> {
    protected T info;

    public T info(){
        return info;
    }

    public abstract void assign();
}


public class ExtBase extends Base<InfoExt> {

    @Override
    public void assign() {
        info = new InfoExt();   
    }
}

Info 将是子类 ExtBase 的 InfoExt 类型。前任)

ExtBase b = new ExtBase();
b.info() // Returns Type InfoExt
于 2013-01-08T15:09:04.773 回答