我有一些这样的课程:
class resourceA
{
public static String ResPath="c:/somethingA";
private double [] data;
public void load(String fileName)
{
//Load data[] from ResPath+"/"+fileName
}
public void save(String fileName)
{
//Save data[] to ResPath+"/"+fileName
}
public static String [] list()
{
return (new File(ResPath)).list();
}
}
class resourceB
{
public static String ResPath="c:/somethingB";
private int [] data;
public void load(String fileName)
{
//Load data[] from ResPath+"/"+fileName
}
public void save(String fileName)
{
//Save data[] to ResPath+"/"+fileName
}
public static String [] list()
{
return (new java.io.File(ResPath)).list();
}
}
还有3个类似的课程。请注意,每个类都有不同类型的私有数据,因此 save()和 load()是特定的。
所以我想用这样的继承来编写更少的代码:
class abstract resourceGeneric
{
public static String ResPath="c:/somethingB";
public abstract void load(String fileName);
public abstract void save(String fileName);
public static String [] list()
{
return (new java.io.File(ResPath)).list();
}
}
class resourceA extends resourceGeneric
{
private double [] data;
public void load(String fileName)
{
//Load data[] from ResPath+"/"+fileName
}
public void save(String fileName)
{
//Save data[] to ResPath+"/"+fileName
}
}
class resourceB extends resourceGeneric
{
private int [] data;
public void load(String fileName)
{
//Load data[] from ResPath+"/"+fileName
}
public void save(String fileName)
{
//Save data[] to ResPath+"/"+fileName
}
}
其他3个课程相同。
这样可以防止为每个类重写相同的 list()方法,同时具有一种通用接口或行为(所有继承的类都必须实现 load() 和保存()方法)
一切看起来都不错,但是当我执行此操作时出错:
resourceA.ResPath="A";
resourceB.ResPath="B";
resourceA.list();
在这种情况下, resourceA.list()正在搜索" B"相反" A"。因为 ResPath 是父类 resourceGeneric 的静态变量。
我可以为每个类声明 ResPath ,但在这种情况下 resourceGeneric.list()无法知道哪条路径(代码不可编译)
由于这没有按预期工作,如果可能的话,我想就如何解决它或如何为原始类编写更好的代码提出建议。
提前致谢!
答案 0 :(得分:0)
如果你想为类遵循这个结构,那么不要声明ResPath
static并在其中一个实现类构造函数中设置它的值,如下所示:
class abstract resourceGeneric
{
protected String ResPath; // Dont declare ResPath static
public abstract void load(String fileName);
public abstract void save(String fileName);
public static String [] list()
{
return (new java.io.File(ResPath)).list();
}
}
然后基类可以是:
class resourceA extends resourceGeneric
{
private double [] data;
public resourceA(String resPath){
this.ResPath = respath;
}
public void load(String fileName)
{
//Load data[] from ResPath+"/"+fileName
}
public void save(String fileName)
{
//Save data[] to ResPath+"/"+fileName
}
}
答案 1 :(得分:0)
由于静态变量是指向抽象类中单个位置的指针,因此您正在使用
进行操作resourceA.ResPath="A";
resourceB.ResPath="B";
resourceA.list();
实质上是在内存中设置相同的位置两次。 resourceA.ResPath和resourceB.ResPath指向内存中相同的位置。
通常不鼓励使用静态变量,访问和修改公共变量也是如此。但是如果你想坚持这种方法,这里有一个建议。
class abstract resourceGeneric
{
private static List<String> ResPaths=new ArrayList<String>();
private String ResPath;
public abstract void load(String fileName);
public abstract void save(String fileName);
public void setResPath(String ResPath)
{
ResPaths.add(ResPath);
this.ResPath = ResPath;
}
public static String [] list()
{
return ResPaths.toArray(new String[ResPaths.size()]);
}
}
现在你可以这样称呼:
resourceA.setResPath("A");
resourceB.setResPath("B");
resourceA.list();
它应该给你路径A和B.
答案 2 :(得分:0)
您不能拥有与类及其任何子类不同的公共静态数据。如果这是你想要达到的目的,你必须改为:
如果有意义,您甚至可以在使用泛型的父级中使用data
,load
和save
:
class abstract resourceGeneric<T>
{
T data[];
public void load(String fileName)
{
//Load T data[] from getResPath()+"/"+fileName
}
public void save(String fileName)
{
//Save T data[] to getResPath()+"/"+fileName
}
public String [] list() // can no longer be static
{
return (new java.io.File(getResPath())).list();
}
public abstract getResPath();
}
class resourceA extends resourceGeneric<Double>
{
private static ResPath = "c:/somethingA";
public getResPath() {
return ResPath;
}
}
class resourceB extends resourceGeneric<Integer>
{
private static ResPath = "c:/somethingB";
public getResPath() {
return ResPath;
}
}
但它强制用相应的拳击类替换内在数组。如果是这样,或者如果使load
和save
泛型不合适,只需将它们留在具体的子类中