简体   繁体   English

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

[英]Java inheritance: “Casting” variable in abstract class as static

I'm seeking to reduce redundant code in my Android project. 我正在寻求减少Android项目中的冗余代码。 Let me tell you what I already have. 让我告诉你我已经拥有的。

I have two main groups of views. 我有两种主要观点。 One is called MapView, which is a View containing a bitmap that can be zoomed, panned, etc. The other is called StepInfoView, which is a View that contains static data, such as an array of coordinates and information about those coordinates. 一个称为MapView,它是一个包含可以缩放,平移等位图的视图。另一个称为StepInfoView,它是一个包含静态数据(如坐标数组和有关这些坐标的信息)的View。 This View is also zoomed and panned in an identical way as the MapView is, however, the scale factors and amount panned needs to be independent from the MapView. 此视图也以与 MapView 相同的方式缩放和平移,但是比例因子和平移量必须与MapView无关。

StepInfoView is extended by several different classes (6 in total), all of which need to be in sync (coordinates are plotted on one, lines between coordinates are plotted on another, etc.). StepInfoView扩展了几个不同的类(总共6个),所有这些类都需要同步(将坐标绘制在一个上,将坐标之间的线绘制在另一个上,等等)。

So, here is the gist of my code, currently: 因此,这是我目前的代码要点:

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
}

As you see, the onScales are identical . 如您所见,onScales是相同的 I want to create an abstract class to hold the scaling function, let us call it RootView. 我想创建一个抽象类来保存缩放功能,让我们将其称为RootView。 Both the MapView and StepInfoView have scales, but I cannot make scale static in RootView because the MapView scale must be independent of the StepInfoView. MapView和StepInfoView都有比例尺,但是我无法在RootView中将比例尺设为静态,因为MapView比例尺必须独立于StepInfoView。 Here is a solution that I know would work, but I don't like the clutter of getters and setters: 我知道这是一个可行的解决方案,但我不喜欢使用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
}

That works exactly how I want it to work, but once again, there is duplicated identical code (getters and setters and a "scale" variable in MapView and StepInfoView). 这完全可以按照我希望的方式工作,但是再一次,重复了相同的代码(MapView和StepInfoView中的getter和setter以及“ scale”变量)。

What I wish I could do is declare a non-static scale in RootView and "cast" it as static in StepInfoView. 我希望可以做的是在RootView中声明一个非静态比例,并在StepInfoView中将其“投射”为静态。 That's not exactly possible... 那是不可能的...

Can ya help me out? 可以帮我吗?

A float costs about 4 bytes. 浮点运算大约需要4个字节。 Having another classes will use quite a bit more memory than this. 拥有另一个类将比这占用更多的内存。 As objects are typically 8 byte aligned, it may not even make the object smaller. 由于对象通常是8字节对齐的,因此它甚至可能无法缩小对象。

If you want to avoid complexity I would leave the field as non-static. 如果要避免复杂性,我会将该字段保留为非静态。

You could have 你可以有

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

Why not to move scale field into the RootView class? 为什么不将scale字段移到RootView类中?

update: just got it. 更新:就知道了。 I think there is a place for aggregation: make some object container for stepinfo scale value, and pass thru StepInfoView's. 我认为这里有一个聚合的地方:为stepinfo的scale值创建一些对象容器,并通过StepInfoView传递。

whatever, i think the simplest way it is to use getters. 不管怎样,我认为最简单的方法就是使用吸气剂。

Move the scale field to the listener, and provide get and set. 将scale字段移到侦听器,并提供get和set。

In the view, hold a reference to the listener so you can access the scale. 在视图中,持有对侦听器的引用,以便您可以访问音阶。

For the MapView, register a different listener for each view instance so they have different scales. 对于MapView,为每个视图实例注册一个不同的侦听器,以便它们具有不同的比例。

For the StepInfoView, register the same listener for each view instance so they have the same scale. 对于StepInfoView,为每个视图实例注册相同的侦听器,以便它们具有相同的比例。 You could store the reference the listener in a static field. 您可以将引用侦听器存储在静态字段中。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM