Creating a new object in an abstract class in Java

I have two objects that use really similar methods, keeping one line. For instance:

public class Cat extends Animal
public class Dog extends Animal

And they both use the method breedin an abstract class Animal. One calls new Dog(), and the other new Cat(). Right now, I just declared it as abstract public void breed();in Animal, but is there any way to generalize it, so I don't need to redefine the abstract method?

+5
source share
3 answers

There are many ways to do this, assuming that breedyou mean "create me children."

Reflection

. no-args , , Class.newInstance:

public Animal breed() {
    try {
        return (Animal) getClass().newInstance();
    } catch (Exception ex) {
        // TODO Log me
        return null;
    }
}

no-args , . , Cat(int, String) Dog(int, String), Class.getConstructor newInstance:

return (Animal) getClass().getConstructor(int.class, String.class).newInstance(0, "Unnamed");

int String , , . .

:

public interface Provider<T> {
    T create();
}

:

public abstract class Animal {
    private final Provider<Animal> animalProvider;

    protected Animal( ... , Provider<Animal> animalProvider) {
        // ...
        this.animalProvider = animalProvider;
    }

    public Animal breed() {
        return animalProvider.create();
    }
}

Provider<Animal> , :

public class Dog extends Animal {
    public Dog( ... ) {
        super( ... , new DogProvider());
        // ...
    }

    private static class DogProvider implements Provider<Animal> {
        public Animal create() {
            return new Dog( ... );
        }
    }
}

.

:, breed " ", , . , , :

public abstract class Animal {
    protected final Breed breed;

    protected Animal( ... , Breed breed) {
        // ...
        this.breed = breed;
    }

    public Breed getBreed() {
        return breed;
    }
}

get/set . Java bean, , . :

public class Dog extends Animal {
    public Dog( ... ) {
        super( ... , new Breed( ... ));
        // ...
    }
}
+3

, , . , , () :

public abstract class Animal{
    public Animal breed(){
      return getClass().newInstance();
    }
    //other methods
}

, Animal ( ).

Prototype Pattern. , .

Edit

@FrankPavageau , , , ,

public abstract class Animal{
    public Animal breed(){
      return getClass().getConstructor().newInstance();
    }
    //other methods
}

, InvocationTargetException, , , . @FrankPavageau .

+3

, . - , , .

,

public abstract Breed getBreed();

public Breed getBreed() {
    return new DogBreed();
}

cat.

Animal, . . .

public abstract class Animal {
    Breed breed;
...
}

public class Dog extends Animal {
    public Dog() {
        breed = new DogBreed();
    }
}

- Cat.

It may cost you as well as pass the breed to the dog / cat so that you can create objects of Dog of different breeds, and not limit your model to only one dog breed

I'm not sure that the rocks are necessarily modeled correctly in your example. Do you really want the new dog () to be a breed? Or do you mean type? In this case, it is just an animal, and the abstract method is to return the animals.

+2
source

All Articles