【问题标题】:How to declare extended model class in extended activity?如何在扩展活动中声明扩展模型类?
【发布时间】:2017-01-31 10:29:37
【问题描述】:

我有一个 Android 应用来帮助收集动物观察数据。它有一个活动 ObserveAnimal 和一个具有普通 getter 和 setter 的模型 Animal。

我正在创建具有扩展功能和扩展数据的应用程序的不同风格,用于鸟类观察。 ObserveBird 扩展 ObserveAnimal 和 Bird 扩展 Animal。 ObserveBird 添加了一些额外的方法。

public class Animal {
    private String species;
    // there are more fields and public getters and setters ...
}

public class Bird extends Animal {
    private int wingLength;
    // public getters and setters ...
}

问题是我找不到正确的方法来声明和初始化 Bird。我尝试了几种方法,例如:

public class ObserveAnimal extends AppCompatActivity {
    protected Animal a = new Animal();
}

public class ObserveBird extends ObserveAnimal {
    protected Bird a = new Bird();
}

ObserveAnimalAnimal a 可以很好地协同工作。

但是在ObserveBirdBird a 声明中隐藏了Animal a 声明,我最终得到了两个不同的实例。实例Animal aObserveAnimal 中的代码获取其species 字段集,实例Bird aObserveBird 中的代码获取其wingLength 字段集。

我试图在ObserveBird 中设置一个Bird a 实例,其中speciesObserveAnimal 中的代码设置,wingLengthObserveBird 中的代码设置。

当我开始活动 ObserveBird 时,我想要一个实例 Bird a(并且没有其他 Animal 实例)。

如何在不将大量代码从 ObserveAnimal 复制到 ObserveBird 的情况下做到这一点?

【问题讨论】:

  • 显示AnimalBird 的声明的样子。
  • Java 中只能扩展一个类,但如果需要,可以实现多个接口See this link
  • 活动不是模型,不要试图这样对待它
  • @MarcinOrlowski 我添加了动物和鸟类声明。
  • @TimCastelijns 活动和模型是分开的。这些活动有更多的代码,如 OnCreate(),一个带有视图等的布局,我认为与问题无关。活动使用 Animal 和 Bird 的 getter 和 setter。我添加了模型声明以澄清问题。

标签: java android


【解决方案1】:

如何在不将大量代码从 ObserveAnimal 复制到 ObserveBird 的情况下做到这一点?

您很可能会从使用abstract class 中受益,并且根据逻辑Animal 应该是这样的类,Bird 应该只是扩展Animal。这样公共代码和逻辑就保留在Animal

编辑

我将创建 Animal 和 Birt 都必须实现的接口(即AnimalContract)或首先为我的模型创建抽象基类:

public class Animal implements AnimalContract {
    private String species;
   // there are more fields and public getters and setters ...
}

public class Bird extends Animal {
    private int wingLength;
    // public getters and setters ...
}

然后,无论何时我需要任何动物,无论是鸟、狗还是我想要的任何东西,只要AnimalContract,同时仍然能够需要某些物种(即Bird当明确需要时)。

然后我就有了观察事物的基类:

abstract public class ObserveBase extends AppCompactActivity {
    abstract AnimalContract getModel();

    protected AnimalContract a;

    protected void init() {
        a = getModel();
    }

    ... all the common code here...

}

并调用init()(或与onCreate()合并)。接下来我会让getModel() 返回我的模型,就像子类一样:

public class ObserveAnimal extends ObserveBase {
    @Override
    public AnimalContract getModel() {
       return new Animal();
    }
}

public class ObserveBird extends ObserveBase {
    @Override
    public AnimalContract getModel() {
      return new Bird();
    }
}

【讨论】:

  • Animal 不能是抽象类,因为ObserveAnimal 需要Animal 的实例。
  • 当然,这实际上很好,也很正常。但现在我真的不明白你的问题是什么。如果 Bird 扩展了 Animal,那么如果一切都正确,则应该没有重复的代码。当前的new Bird()new Animal() 实例化对您有什么问题?
  • 谢谢你,很有启发性,它工作正常。我只需要在活动ObserveBirdonCreate() 中添加Bird b = (Bird) a;,就可以访问像setWingLength() 这样的Bird 方法。
  • 确定这是正确的方法,因为您可以始终安全地将Bird 的实例转换为AnimalContract。但是您应该小心以其他方式进行操作,因为并非所有实现AnimalContract 的类都是Bird 的实例——只有Bird 本身及其子类。如果你投Animal,你将面对ClassCastException。不过,如果您只需要基本代码中的任何内容,最好将其转换为 AnimalContract,因为您不在乎它是 BirdDog,因为此时这无关紧要。
【解决方案2】:

类似

public class Observe<A extends Animal> extends AppCompatActivity {
    protected A a;
    public Observe(Class<A> clazz) {
        a = clazz.newInstance();
    }
}

然后调用

Observe<Animal> animalActivity = new Observe<Animal>(Animal.class);
Observe<Bird> birdActivity = new Observe<Bird>(Bird.class);

【讨论】:

  • 这是一个有趣的方法。但据我了解,这需要我放弃ObserveAnimalObserveBird 活动中的功能分离,并将其全部放在一个活动Observe 中。未来我计划添加更多的口味,如观察蝴蝶、蜘蛛、哺乳动物等。拥有不同的活动和不同的模型会很好,既扩展了基础 ObserveAnimal 活动,又扩展了基础 Animal 模型。
猜你喜欢
  • 2017-02-12
  • 2021-05-03
  • 1970-01-01
  • 2018-05-25
  • 2019-11-06
  • 2012-09-10
  • 1970-01-01
  • 2020-05-15
  • 1970-01-01
相关资源
最近更新 更多