[英]Java: Overriding static variable of parent class?
我有以下类,我将其用作项目中所有模型的基础:
public abstract class BaseModel
{
static String table;
static String idField = "id";
public static boolean exists(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();
}
//snip..
}
然后我尝试通过以下方式扩展它:
public class User extends BaseModel
{
static String table = "user";
//snip
}
但是,如果我尝试执行以下操作:
if ( User.exists( 4 ) )
//do something
然后,而不是查询: "SELECT id FROM user WHERE id = ?"
,它正在生成查询:“SELECT id from null WHERE id = ?”。 因此,覆盖User
类中的table
字段似乎没有任何效果。
我该如何克服呢? 如果我在 BaseModel 中添加了一个setTable()
方法,并在User
的构造函数中调用了setTable()
,那么table
的新值是否也可用于User
类的所有方法?
您不能覆盖 Java 中任何类型的静态方法或字段。
public class User extends BaseModel
{
static String table = "user";
//snip
}
这将创建一个新字段User#table
恰好与BaseModel#table
同名。 大多数 IDE 都会对此发出警告。
如果您更改 BaseModel 中字段的值,它也将应用于所有其他模型类。
一种方法是让基本方法通用
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();
}
并在子类中使用
public static boolean exists(long id)
{
return exists("user", id);
}
如果您想使用字段方法,您必须创建一个BaseDAO
类并拥有一个相应地设置字段的UserDAO
(每个模型类一个)。 然后创建所有 daos 的单例实例。
因为 Java 不允许您覆盖static
成员,所以您基本上需要求助于稍微冗长但总体上更好的单例模式,其中您仍然在概念上编写“静态”代码,但您在技术上使用 (global/singleton /"static") 实例,因此您不受static
的限制。
(请注意,您还需要使用方法,因为字段不参与多态性,因此不能被覆盖)
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);
}
输出:
SELECT count(*) FROM user WHERE id = 123
SELECT count(*) FROM post WHERE id = 456
为了做你想做的事,不要在BaseModel
中使table
成为静态的。 然后在从BaseModel
继承的其他类中,您可以将默认构造函数中的table
设置为您想要的任何内容。
static {
table = "user";
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.