// Abstract class
abstract class Animal {
    protected String name;
    
    // Constructor
    public Animal(String name) {
        this.name = name;
    }
    
    // Concrete method (has implementation)
    public void sleep() {
        System.out.println(name + " is sleeping");
    }
    
    // Abstract method (no implementation)
    public abstract void makeSound();
    
    // Abstract method
    public abstract void move();
}

// Concrete subclass
class Dog extends Animal {
    public Dog(String name) {
        super(name);
    }
    
    // Must implement abstract methods
    @Override
    public void makeSound() {
        System.out.println(name + " barks");
    }
    
    @Override
    public void move() {
        System.out.println(name + " runs on four legs");
    }
}

// Another concrete subclass
class Bird extends Animal {
    public Bird(String name) {
        super(name);
    }
    
    @Override
    public void makeSound() {
        System.out.println(name + " chirps");
    }
    
    @Override
    public void move() {
        System.out.println(name + " flies");
    }
}

// Usage
Animal dog = new Dog("Buddy");
dog.sleep();      // Inherited concrete method
dog.makeSound();  // Overridden abstract method
dog.move();       // Overridden abstract method

Animal bird = new Bird("Tweety");
bird.sleep();    // Inherited concrete method
bird.makeSound(); // Overridden abstract method
bird.move();      // Overridden abstract method

// Cannot instantiate abstract class
// Animal animal = new Animal("Generic"); // Compile error