在父构造函数中初始化子级之前调用子方法的Java抽象父级方法

时间:2016-04-28 18:05:22

标签: java inheritance constructor abstract

我有以下课程:

abstract class Parent
{
    private ClassDependentOnSize classDependentOnSize;

    public Parent ()
    {
        this.classDependentOnSize = new ClassDependentOnSize(size());
    }

    public abstract int size ();
}

class Child extends Parent
{
    private String DBSelection;
    private String[] DBSelectionArgs;

    public Child (String selection, String... selectionArgs)
    {
        super();
        this.DBSelection = selection;
        this.DBSelectionArgs = selectionArgs;
    }

    @Override
    public int size()
    {
        //FAILS because Parent calls size before DBSelectionArgs is initialized
        String temp = "";
        for(String str : DBSelectionArgs)
           temp += str;
        return temp.length;

        //This function basically does a calculation that should not be
        //done before hand. I have posted the exact method below.
    }
}

class ClassDependentOnSize 
{
    public ClassDependentOnSize(int size)
    {

    }
}

虽然这不是我的完全类,但这是同样的问题。我写了这个来删除所有不必要的代码。

正如您所看到的,超类在子进程初始化之前尝试调用size()来构造依赖于大小的类。我很好奇过去有人如何解决这个问题。我确信每个人都知道,super()必须是子构造函数中的第一行。我已经把这些课程放了出来,这是一个糟糕的设计吗?我觉得这是一个必须发生的问题,但我找不到解决方案。

编辑: 这是确切的方法。它用于Android应用程序。

protected Cursor getCursor()
{
    if (songCursor == null)
    {
        songCursor = GET_SONGS_CURSOR(getContext(), MediaStore.Audio.Media.EXTERNAL_CONTENT_URI.toString(), selection, selectionArgs, selection);

        if (!songCursor.moveToFirst())
            Standard.Loge("|NewPlaylist.getCursor| Could not move to first.");
    }

    int count = songCursor.getCount();
    songCursor.close();
    return count;
}

3 个答案:

答案 0 :(得分:1)

针对您的特定情况的简单解决方案是将大小作为参数传递给父构造函数。

这当然假设您的真正问题具有相同的特征,即在调用构造函数时基类构造函数所需的所有信息都可用。

答案 1 :(得分:1)

我以前肯定遇到过这个问题。外卖课程是你永远不应该在Parent构造函数中调用非私有方法,所以这不会发生

答案 2 :(得分:1)

更改父级以将大小作为参数是一个选项:

abstract class Parent
{
    private ClassDependentOnSize classDependentOnSize;

    public final void init()
    {
        this.classDependentOnSize = new ClassDependentOnSize(size());
    }

    public abstract int size ();
}

...

public Child (String selection, String... selectionArgs)
{
    this.DBSelection = selection;
    this.DBSelectionArgs = selectionArgs;
    init();
}

另一个选项,有点像黑客,是有一个必须在构造后调用的init方法:

echo "<tr align='center'>";
echo "<td>".$record['YourName']."</td>";
echo "<td>".$record['FatherName']."</td>";
echo "<td>".$record['RegNum']."</td>";
echo "<td>".$record['Gender']."</td>";
echo "<td name='$i' >".$record['MobileNumber']."</td>";

echo "<td>".$record['Password']."</td>";
echo "<td>".$record['specialist']."</td>";
echo "<td>".$record['area']."</td>";
echo "<td>".$record['building']."</td>";
echo "<td>".$record['room']."</td>";
echo "<td><input type='checkbox' name='$i' value='Bike' align='center'></td>";
echo "</tr>";

$i++;

这里的正确答案可能会改变您的代码结构,但是,如果没有更具体的细节,我无法提供有关您希望如何进行的有意义的反馈。< / p>

相关问题