java静态变量继承 - 如何改进代码?

时间:2015-05-15 21:11:21

标签: java

我有一些这样的课程:

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()无法知道哪条路径(代码不​​可编译)

由于这没有按预期工作,如果可能的话,我想就如何解决它或如何为原始类编写更好的代码提出建议。

提前致谢!

3 个答案:

答案 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)

您不能拥有与类及其任何子类不同的公共静态数据。如果这是你想要达到的目的,你必须改为:

  • 在每个子类中都有私有静态数据
  • 在抽象父类
  • 中使用抽象非静态getter(和optionaly setter)
  • 在子类中具有非静态覆盖getter(和optionaly setter)

如果有意义,您甚至可以在使用泛型的父级中使用dataloadsave

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;
    }
}

但它强制用相应的拳击类替换内在数组。如果是这样,或者如果使loadsave泛型不合适,只需将它们留在具体的子类中