Java继承:";铸造;抽象类中的变量为静态变量

Java继承:";铸造;抽象类中的变量为静态变量,java,inheritance,static,abstract,Java,Inheritance,Static,Abstract,我正在努力减少Android项目中的冗余代码。让我告诉你我已经有了什么 我有两种主要观点。一个称为MapView,它是一个包含位图的视图,可以缩放、平移等。另一个称为StepInfoView,它是一个包含静态数据的视图,例如坐标数组和关于这些坐标的信息。此视图的缩放和平移方式与地图视图相同,但是,缩放因子和平移量需要独立于地图视图 StepInfoView由几个不同的类(总共6个)扩展,所有这些类都需要同步(坐标在一个类上绘制,坐标之间的线在另一个类上绘制,等等) 下面是我目前代码的要点: pu

我正在努力减少Android项目中的冗余代码。让我告诉你我已经有了什么

我有两种主要观点。一个称为MapView,它是一个包含位图的视图,可以缩放、平移等。另一个称为StepInfoView,它是一个包含静态数据的视图,例如坐标数组和关于这些坐标的信息。此视图的缩放和平移方式与地图视图相同,但是,缩放因子和平移量需要独立于地图视图

StepInfoView由几个不同的类(总共6个)扩展,所有这些类都需要同步(坐标在一个类上绘制,坐标之间的线在另一个类上绘制,等等)

下面是我目前代码的要点:

public class MapView extends View
{
    protected float scale = 1;

    protected class ScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener
    {
        @Override
        public boolean onScale(ScaleGestureDetector detector)
        {
            scale *= detector.getScaleFactor());
            return true;
        }

    }

    }
... 

public class StepInfoView extends View
{
    static protected float scale = 1;
    protected class ScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener
    {
        @Override
        public boolean onScale(ScaleGestureDetector detector)
        {
            scale *= detector.getScaleFactor());
            return true;
        }

    }
}
...
public class StepView extends StepInfoView
{  
    // Custom onDraw, same scale as PathView
}
public class PathView extends StepInfoView
{
    // Custom onDraw, same scale as StepView
}
正如你所看到的,尺度是相同的。我想创建一个抽象类来保存scaling函数,我们称之为RootView。MapView和StepInfoView都有比例,但我不能在RootView中使比例为静态,因为MapView比例必须独立于StepInfoView。我知道这是一个可行的解决方案,但我不喜欢杂乱无章的getter和setter:

abstract class RootView extends View
{
    abstract protected float getScale();

    abstract protected void setScale(float s);
    protected class ScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener
    {
        @Override
        public boolean onScale(ScaleGestureDetector detector)
        {
         setScale(getScale() * detector.getScaleFactor());
         return true;
        }
    }
}
...
public class MapView extends RootView
{
    public float scale = 1;
    protected float getScale(){
        return scale;
    }

    protected void setScale(float s){
        scale = s;
    }
}

public class StepInfoView extends RootView
{
    public static float scale = 1;
    protected float getScale(){
        return scale;
    }

    protected void setScale(float s){
        scale = s;
    }
}
public class StepView extends StepInfoView
{  
    // Custom onDraw, same scale as PathView
}
public class PathView extends StepInfoView
{
    // Custom onDraw, same scale as StepView
}
这正是我希望它的工作方式,但同样存在重复的相同代码(getter和setter以及MapView和StepInfoView中的“scale”变量)

我希望我能做的是在RootView中声明一个非静态量表,并在StepInfoView中将其“强制转换”为静态量表。那不太可能


你能帮我吗?

为什么不将
scale
字段移动到
RootView
类中


更新:刚刚收到。我认为有一个聚合的地方:为stepinfo
scale
value创建一些对象容器,并传递StepInfoView


不管怎样,我认为最简单的方法是使用getter。

一个浮点值大约需要4个字节。拥有另一个类将使用比这个多得多的内存。由于对象通常是8字节对齐的,因此它甚至可能不会使对象变小

如果您想避免复杂性,我会将字段保留为非静态

你本来可以的

class RootView {
    protected final float[] scale;

    RootView() {
        scale = new float[] { 1.0f };
    }

    protected RootView(float[] scale) {
        this.scale = scale;
    }

    public boolean onScale(ScaleGestureDetector detector) {
        scale[0] *= detector.getScaleFactor();
        return true;
    }
}

class StepInfoView extends RootView {
    static final float[] scale = { 1.0f };

    StepInfoView() {
        super(scale);
    }

将scale字段移动到侦听器,并提供get和set

在视图中,保留对侦听器的引用,以便可以访问比例

对于MapView,为每个视图实例注册不同的侦听器,以便它们具有不同的比例


对于StepInfoView,为每个视图实例注册相同的侦听器,以便它们具有相同的比例。您可以将侦听器的引用存储在静态字段中。

我需要在StepInfoView中缩放为静态。如果我在根视图中将其设置为静态,则StepInfoView和MapView将不会彼此独立地进行缩放。“为StepInfoScale值创建一些对象容器,并传递StepInfoView的“对不起,我不完全理解您的建议。我不关心此应用程序的内存。如果将字段保留为非静态字段,则需要在比例发生变化时分别更新扩展StepBaseInfo的所有类。因此,这对于仅缩放非常有效,但我还有一个变量“位置”,即MapView和StepInfoView的平移量,其处理方式与缩放相同(对于Map为非静态,对于StepInfo为静态). 我可以在MapView和StepInfoView中都使用super.pan(x,y)吗?你可以这样使用
新点(x,y)
。我真的不想只在构造函数中完成所有工作。我希望能够在不创建新的StepInfoView的情况下更新比例。我慢慢开始看到丑陋的现实。如果有两个对象通信,则需要允许它们通信的方法。由于您只有一个值可以从侦听器与视图进行通信,因此您可以在这两个值之间共享一个字段(正如您所看到的那样,该字段很脆弱并会导致重复),或者使用一个函数将值推送到视图(setter),或者使用一个函数从侦听器中提取值(getter或公共字段). 从同一个侦听器中提取多个视图比将侦听器推送到多个视图简单。