如何使用超类来减少代码?

2022-09-01 03:37:21

我想重构一些当前由一个超类和两个子类组成的代码。

这些是我的类:

public class Animal {
    int a;
    int b;
    int c;
}

public class Dog extends Animal {
    int d;
    int e;
}

public class Cat extends Animal {
    int f; 
    int g;
}

这是我当前的代码:

ArrayList<Animal> listAnimal = new ArrayList<>();

if (condition) {
    Dog dog = new Dog();
    dog.setA(..);
    dog.setB(..);
    dog.setC(..);
    dog.setD(..);
    dog.setE(..);   
    listAnimal.add(dog);

} else {
    Cat cat = new Cat();
    cat.setA(..);
    cat.setB(..);
    cat.setC(..);
    cat.setF(..);
    cat.setG(..);
    listAnimal.add(cat);
}

如何重构有关公共属性的代码?

我想要这样的东西:

Animal animal = new Animal();
animal.setA(..);
animal.setB(..);
animal.setC(..);

if (condition) {
    Dog anim = (Dog) animal; //I know it doesn't work
    anim.setD(..);
    anim.setE(..);  
} else {
    Cat anim = (Cat) animal; //I know it doesn't work
    anim.setF(..);
    anim.setG(..);
}

listAnimal.add(anim);

答案 1

你有一个类型的变量的想法很好。但是您还必须确保使用正确的构造函数:Animal

Animal animal; // define a variable for whatever animal we will create

if (condition) {
    Dog dog = new Dog(); // create a new Dog using the Dog constructor
    dog.setD(..);
    dog.setE(..);  
    animal = dog; // let both variables, animal and dog point to the new dog
} else {
    Cat cat = new Cat(); 
    cat.setF(..);
    cat.setG(..);
    animal = cat;
}

animal.setA(..); // modify either cat or dog using the animal methods
animal.setB(..);
animal.setC(..);

listAnimal.add(animal);

提示:如果动物总是猫或狗,请考虑制作动物。然后,每当您尝试执行.abstractnew Animal()


答案 2

构建猫或狗的过程很复杂,因为涉及很多领域。这是生成器模式的一个很好的例子。

我的想法是为每种类型的构建器编写一个构建器,并组织它们之间的关系。它可以是组合或继承。

  • AnimalBuilder构造一个通用对象并管理 、 、 字段Animalabc
  • CatBuilder获取(或扩展它)并继续构建一个管理 , 字段的对象AnimalBuilderCatfg
  • DogBuilder获取(或扩展它)并继续构建一个管理 , 字段的对象AnimalBuilderDogde

如果您不想创建构建器,请考虑引入一个静态工厂方法,每个子类都有一个有意义的名称:

Animal animal = condition ? Dog.withDE(4, 5) : Cat.withFG(6, 7);
// populate animal's a, b, c
listAnimal.add(animal);

它将简化构造,使其不那么冗长,更具可读性。


推荐