Animals, inheritance and interfaces I am trying to fully understand interfaces and abstract classes in Java and from what I understood, I created a sample console application. Is there an error in the design or is this basically what interfaces and abstract classes are?

Animals.java (interface):

interface Animals {

    void callSound();
    int run();

}


Feline.java (abstract class):

abstract class Feline implements Animals {

    @Override
    public void callSound() {
        System.out.println("roar");
    }

}


Canine.java (abstract class):

abstract class Canine implements Animals {

    @Override
    public void callSound() {
        System.out.println("howl");
    }

}


Lion.java (class):

class Lion extends Feline {

    @Override
    public void callSound() {
        super.callSound();
    }

    @Override
    public int run() {
        return 40;
    }

}


Cat.java (class):

class Cat extends Feline {

    @Override
    public void callSound() {
        System.out.println("meow");
    }

    @Override
    public int run() {
        return 30;
    }

}


Wolf.java (class):

class Wolf extends Canine {

    @Override
    public void callSound() {
        super.callSound();
    }

    @Override
    public int run() {
        return 20;
    }

}


Dog.java (class):

class Dog extends Canine {

    @Override
    public void callSound() {
        System.out.println("woof");
        super.callSound();
    }

    @Override
    public int run() {
        return 10;
    }

}


Main.java:

public class Main {

    public static void main(String[] args) {
        Animals[] animals = new Animals[4];
        animals[0] = new Cat();
        animals[1] = new Dog();
        animals[2] = new Wolf();
        animals[3] = new Lion();

        for (int i = 0; i &lt; animals.length; i++) {
            animals[i].callSound();
        }
    }

}
Overall, it seems like your implementation is fine and accurately represents the relationships between the different classes and interface.  You could improve on your design however if you would consider some style guides.

Explicitness

The default modifier for your classes / interfaces will make them only visible from within your package.  While this may be what you intended, it's always better to be explicit and state the level of access you intend each portion of your code to have.  This reduces guess-work made by others who work with your code (which can help to reduce bugs made based on assumptions) and it improves the readability.

This has the additional benefit of making the rest of your code more consistent (since you do not use default modifiers for your methods).

Naming

EDIT

In the following section I borrow wisdom from .NET Land.  This would appear to be contrary to the style guide used by most JAVA developers. As illustrated in the links below:


https://stackoverflow.com/questions/541912/interface-naming-in-java
https://stackoverflow.com/questions/2814805/java-interfaces-implementation-naming-convention


That being said, it used to be convention to not have to dial an area code in the U.S. but after seeing the shortcomings, it was changed to always require area code.  My point is that conventions often change (and usually for pragmatic reasons in the programming community) and as a result be open to other schools of thought.  I think you'll find if you take both pieces of advice (creating interfaces based on attributes / behaviors) along with the "I" prefix, it makes the most sense.  Ultimately this is a SMALL piece of the review and as with the rest of it, feel free to take or not take the input.

END EDIT

Typically (in .NET and Eclipse) interfaces begin with the letter "I" to denote this fact.  So your interface Animals would be better named IAnimal (also without the plural unless you intend the interface to handle multiple animals).

Separation of Concerns

This is more of an esoteric critique, but generally speaking you'll want your interfaces to be well-segregated and more specific.  The current Animals interface doesn't really communicate what the interface is used for.  If I were making an application for example that only showed pictures of various animals, it is unclear whether or not I should use your interface on my new class.
Rather, it is better to split interfaces (usually) based on the behavior they add.  This forces them to be very targeted and succint, which in turn produces code that is more stable and typically easier to maintain since changes are very isolated.

For example, instead of:

interface Animals {

    void callSound();
    int run();

}


You might have:

interface IMakesSound {
    void callSound();
}

interface ICanMove {
    int move();
}

interface IWarmBlooded {
    int currentBodyTemperature();
    bool isOverheated();
}

abstract class Animal implements IMakesSound, ICanMove {
    abstract void callSound();
    abstract int move();
}

abstract class Mammal extends Animal implements IWarmBlooded {
    private int _bodyTemp;
    abstract void callSound(); // We don't know what ALL mammals sound like
    abstract int move(); // Some mammals run, others walk, some swim, and some do all of the above.
    public int currentBodyTemperature() {
        return _bodyTemp;
    }

    public bool isOverheated() {
        return _bodyTemp &gt; 98; // This can be overridden based on the child class if needed
    }
}

// Other classes here that inherit either from `Animal` or `Mammal`.


In the above example, I have separated out your interface into two separate interfaces and an abstract base type that combines them.  Using this structure, I can create something that makes a sound but isn't an animal (for example, a robot toy dog) that can still have all of the attributes of a "real" dog, but none of the inherited animal features.

This allows your code to be more flexible and more loosely coupled (which is the point of using an interface).  By having code dependent on these loosely typed constructs, it allows for more flexibility.

For example:

public class Main {

    public static void main(String[] args) {
        Animals[] animals = new Animals[4];
        animals[0] = new Cat();
        animals[1] = new Dog();
        animals[2] = new Wolf();
        animals[3] = new Lion();

        for (int i = 0; i &lt; animals.length; i++) {
            animals[i].move();
        }

        ShowPetSounds(animals);
    }

    public static void ShowPetSounds(IMakesSound[] petNoises) {
        for (int i = 0; i &lt; petNoises.length; i++) {
            petNoises[i].callSound();
        }
    }

}


This allows us to write code that only knows about pet sounds without having to worry about what kind of animal it is (or indeed that it is an animal).  This allows us to have imaginary pets like dragons (which we all love) or unicorns that would defy the "normal" inheritance hierarchy of an Animal type.

Ultimately both abstract classes and interfaces should be designed to be helpful abstractions, not abstraction for that sake of abstraction.  When you do this, you will find that as your code-base grows over time, it will respond much better to additional requirements and changes in the system.