Java: Overriding static variable of parent class?

橙三吉。 提交于 2019-11-29 09:12:49

You cannot override static methods or fields of any type in Java.

public class User extends BaseModel
{
    static String table = "user";
    //snip
}

This creates a new field User#table that just happens to have the same name as BaseModel#table. Most IDEs will warn you about that.

If you change the value of the field in BaseModel, it will apply to all other model classes as well.

One way is to have the base methods generic

protected static boolean exists(String table, long id) throws Exception
{
    Db db = Util.getDb();
    Query q = db.query();
    q.select( idField ).whereLong(idField, id).limit(1).get(table);

    return q.hasResults();
}

and use it in the subclass

public static boolean exists(long id)
{
    return exists("user", id);
}

If you want to use the field approach, you have to create a BaseDAO class and have a UserDAO (one for each model class) that sets the field accordingly. Then you create singleton instances of all the daos.

Because Java doesn't allow you to override static members, you basically need to resort to the slightly more verbose but overall nicer singleton pattern, wherein you're still conceptually writing "static" code, but you're technically using (global/singleton/"static") instances, so you're not restricted by the limitations of static.

(note that you also need to use methods because fields don't participate in polymorphism, and thus cannot be overridden)

public abstract class BaseTable {
    public abstract String table();
    public String idField() { return "id"; }

    public boolean exists(long id) {
        // don't build queries this way in real life though!
        System.out.println("SELECT count(*) FROM " + table() + " WHERE " + idField() + " = " + id);
        return true;
    }
}

public class UserTable extends BaseTable {
    public static final User INSTANCE = new UserTable();
    private UseTabler() {}

    @Override public String table() { return "user"; }
}

public class PostTable extends BaseTable {
    public static final Post INSTANCE = new PostTable();
    private PostTable() {}

    @Override public String table() { return "post"; }
}

public static void main(String[] args) {
    UserTable.INSTANCE.exists(123);
    PostTable.INSTANCE.exists(456);
}

Outputs:

SELECT count(*) FROM user WHERE id = 123
SELECT count(*) FROM post WHERE id = 456

In order to do what you are looking to do, don't make table static in the BaseModel. Then in the other classes that inherit from BaseModel, you can set table in the default constructor to whatever you wish.

static {
    table = "user";
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!