Предположим, у вас есть интерфейс IAnimal
, два абстрактных класса Mammal
и Bird
и два конкретных класса Dog
и Eagle
в пакете с именем animals
. Mammal
и Bird
реализуют интерфейс IAnimal
, в то время как Dog
расширяет Mammal
, а Eagle
расширяет Bird
. Эта ситуация будет выглядеть следующим образом (спасибо @BackSlash за его комментарий):
Интерфейс:
package animals;
public interface IAnimal {
void feed();
}
Абстрактные классы:
Млекопитающие:
package animals;
abstract class Mammal implements IAnimal {
/*
* This is the feeding method that every animal has to implement.
* The trick here is to force the inconcrete method feed() to use the
* mammal specific one that has to be implemented by concrete mammals
*/
@Override
public void feed() {
breastFeed();
}
/*
* This is how mammals feed,
* so every concrete mammal has to implement this method (even humans...)
*/
protected abstract void breastFeed();
}
Птицы
package animals;
public abstract class Bird implements IAnimal {
/*
* This time, force the inconcrete method feed() to use the
* bird specific one that has to be implemented by concrete birds
*/
@Override
public void feed() {
feedPrey();
}
/*
* Birds feed prey to their young, most likely due to a lack of breasts
*/
protected abstract void feedPrey();
}
Конкретные классы:
package animals;
public class Dog extends Mammal {
/*
* This is how dogs feed, the implementation of how mammals feed
*/
@Override
protected void breastFeed() {
System.out.println("currently breastfeeding... do not disturb!");
}
}
Вы можете проверить вывод по некоторому классу с помощью метода main
, например:
import animals.Dog;
import animals.Eagle;
import animals.IAnimal;
public class Test {
public static void main(String[] args) {
IAnimal dog = new Dog();
IAnimal eagle = new Eagle();
dog.feed();
eagle.feed();
}
}
и результат будет такой, как собака
(прошу прощения за биологическую неправильность, могут быть птицы, которые не кормят добычей своих детенышей. Эти примеры сделаны для явы, а не для природы ...)