When you need a class for inheritance and polymorphism, but you don't want to instantiate the class itself, only its subclasses, abstract classes come in handy. They're frequently used when you want to provide a template for a group of subclasses that have some common implementation code, but you also want to ensure that the superclass's objects aren't created.
Let's imagine you need to make stuff for a dog, a cat, a hamster, and a fish. They share characteristics like as colour, size, and leg count, as well as behaviour, therefore you establish an Animal superclass. What colour, on the other hand, is an Animal? What is the number of legs on an Animal object? In this situation, instantiating an object of type Animal rather than its subclasses makes more sense.
Polymorphism is another advantage of abstract classes: you can use the type of the (abstract) superclass as a method argument or a return type. Instead of writing a method for each subtype of Animal, if you had a PetOwner class with a train() method, you could define it as taking in an object of type Animal, e.g. train(Animal a).