Sealed classes and interfaces restrict which other classes or interfaces may extend or implement them.

public sealed interface IAnimal 
    permits AquaticAnimal, LandAnimal {
    String lifespan();
}

Notice the use of the sealed modifier and permits keyword. The sealed modifier indicates that the class or interface is restricted. The permit keyword indicates which classes (or interfaces) can implement (or extends) it. Thus, the sealed modifier and the permit keyword must be used together.

public sealed abstract class AquaticAnimal implements IAnimal permits SeaTurtle {
}

The class (or interface) that can implement (or extend) a sealed interface (or class) must have one of the following modifiers:

  • sealed
  • non-sealed
  • final
public non-sealed abstract class LandAnimal implements IAnimal {
}

Using the non-sealed modifier indicates that this class can be extended without restriction.

public sealed class Dog extends LandAnimal permits Boxer {
    @Override
    public String lifespan() {
        return "10 - 13 years";
    }
}

Limiting the hierarchy of Dog class to just Boxer class.

public final class Boxer extends Dog {
    @Override
    public String lifespan() {
        return "10 - 12 years";
    }
}

The final implementation of the Dog class.

public class Cat extends LandAnimal {
    @Override
    public String lifespan() {
        return "12 - 18 years";
    }
}

Since LandAnimal is non-sealed abstract class, it can be inherited without restriction.

public final class SeaTurtle extends AquaticAnimal {
    @Override
    public String lifespan() {
        return "Up to 50 years or more";
    }
}

SeaTurtle is the only class that can implement AquaticAnimal. Because this the only class permitted in the AquaticAnimal definition.