2012-09-23 51 views
0

我想知道是否有办法在不破坏封装的情况下做到这一点,我希望抽象类依赖实现子类中定义的参数。像这样:抽象类从实现子类中获取参数?

public abstract class Parent { 

    private int size; 
    private List<String> someList; 

    public Parent() { 
     size = getSize(); 
     someList = new ArrayList<String>(size); 
    } 

    public abstract int getSize(); 

} 

public class Child extends Parent { 

    @Override 
    public int getSize() { 
     return 5; 
    } 

} 

这难看吗?有没有更好的办法?或许更重要的是,这是一个好主意吗?

编辑:

类在一个框架的背景下创建的,所以默认参数的构造函数始终是一个叫(事实上,父类扩展了另一个类)。 size参数仅用于说明目的,我不打算将它用于List实现。

回答

4

不,不难看。这种模式被命名为“模板方法”。但是,当方法不是一个简单的getter,而是实现业务逻辑的东西时,它通常更有用。

在你的情况其他的解决办法是在父类中定义受保护的构造和孩子相关的参数调用它:

public abstract class Parent { 

    private int size; 
    private List<String> someList; 

    protected Parent(int size) { 
     this.size = size; 
     someList = new ArrayList<String>(size); 
    } 

    public int getSize() { 
     return size; 
    } 

} 

public class Child extends Parent { 
    public Child() { 
     super(5); 
    } 
} 
+0

嗨AlexR,谢谢你的回答,但有一些这种方法的影响,我没有提到足够快,我已经编辑他们到我的问题。抱歉。 –

2

如果构造函数是您使用的唯一地方getSize(),只需要它作为构造函数参数。

但更重要的是,为什么你在乎尺寸?除非你知道有一个问题,只要使用默认的大小和其他人一样:

public abstract class Parent { 

    private List<String> someList = new ArrayList<String>(); 

    // use default constructor  
} 
+0

对不起,我应该澄清更多,类是在一个框架的上下文,所以默认的无参构造函数总是被调用的。大小参数仅用于说明目的,我不打算将它用于List实现。 –

1

的模式是不难看,除了当你尝试在构造函数中使用它。它允许您以一种意想不到的方式修改Child。

public class Child extends Parent { 

    private int mySize = 5; 

    @Override 
    public int getSize() { 
     // The -1 is only to help clarify what happens 
     return mySize - 1; 
    } 

} 

如果你现在创建一个实例儿童它实际上抛出一个异常,因为负的容量是不允许的。您应该认识到,类的属性只在父构造函数完成后才初始化。 (如果使用Parent构造函数设置了一个属性并且在Child中定义了一个默认值,它将会愉快地覆盖刚才在Parent()中设置的值)