How to get rid of instance validation when using inheritance?

Suppose we have an Animal class, with subclasses like cat, eagle

Now I have a method:

public void process(Animal animal) {

   if (animal instanceof Cat) {
     if (!animal.meow()) {
        throw exception("cat does not meow");
     } else {
      animal.feedFish();
     }
   }

   if (animal instanceof eagle) {
      if (!animal.fly()) {
         throw exception("eagle does not fly");
      } else {
        animal.checkMaxFlightAltitude();
      }
   }
}

Here cat has 2 methods meowand feedfishthat are completely different from eagle methods flyandcheckmaxflight

Most design patterns revolve around the assumption that subclasses have a common method, such as a Shape draw()inherited by a circle drawand a square.draw

  • Is there a way to do checks in subclasses like cat and eagle without a check instance?

  • Any good design pattern (assuming subclasses don't use method in base class?)

+4
4

process Animal :

class Animal {
  protected abstract void process();
  public static void process(Animal a) { a.process(); }
}

class Cat {
  void process() {
    if (!meow()) throw exception("cat does not meow");
    else feedFish();
  }
  public boolean meow() { ... }
  public void feedFish() { ... }
}
+7

.

abstract class Animal {
    abstract public void process(Animal animal);
}
class Cat extends Animal {
    @Override
    public void process(Animal animal) {
        if (!this.meow()) {
            throw exception("cat does not meow");
        } else {
            this.feedFish();
        }
    }
}
class Eagle extends Animal {
    @Override
    public void process(Animal animal) {
        if (!this.fly()) {
            throw exception("eagle does not fly");
        } else {
            this.checkMaxFlightAltitude();
        }
    }
}
+1

, visitor.

:

public class Animal {
    public abstract void accept(AnimalVisitor v);

    public boolean meow() {return false;}
    public boolean fly() {return false;}
    public void feedFish() {};
    public void checkMaxFlightAltitude() {};

}

public class Cat extends Animal {
    public void accept(AnimalVisitor v) {
        v.visitCat(this);
    }

    public boolean meow() {return true;}
}

public class Eagle extends Animal {
    public void accept(AnimalVisitor v) {
        v.visitEagle(this);
    }
    public boolean fly() {return true;}
}

public interface AnimalVisitor {
    void visitEagle(Eagle eagle);
    void visitCat(Cat cat);
}

public class AnimalVisitorExample implements AnimalVisitor {
    public void visitEagle(Eagle eagle) {
        eagle.checkMaxFlightAltitude();
    }

    public void visitCat(Cat cat) {
        cat.feedFish();
    }
}

Animal animal = new Cat();
animal.accept(new AnimalVisitorExample());
+1

(1) , ?

, . "validate" ( "Animal" ) . (, /) validate "InvalidContentException" "ErrorHandler", .

(2), , : , . , - "Animal", ?

Validator, ( Animal). , Validator "" (, "" ), "Cat" "Eagle" ( ). , , , "Cat": Cat (, , ,...)

-> I think you should ask yourself if you want to be able to check animals in general. Having no idea about your problem area (which may have reasons not to do this), I would recommend using the "proven" method for the animal. You can also use the visitor template, but this requires that Animal have a method of “accept (AnimalVisitor visitor)” and a bit more code to write (presumably more than you want)

+1
source

Source: https://habr.com/ru/post/1665338/


All Articles