I like to use metaphors to explain things. Often, they aren’t very good. But once in awhile I come up with something that seems to work pretty well.
Inheritance in Object Oriented design isn’t the easiest thing to explain, particularly the idea of an “abstract” class. But if we think about classes as literal “buckets” of state, then what’s the equivalent of an abstract class? What about a bucket with a hole in it; a leaky bucket?
A leaky bucket isn’t very useful on its own, you have to plug the hole in one way or another. Depending on how you plug the hole, however, you’ll get different outcomes. Plug the hole with a hose and it can help you water your garden. Plug the hole with a piece of screen or cloth and you’ve built yourself a filter. Plug the hole with a bit of waterproof tape and, well, now the leaky bucket is just a bucket.
Each of these tools requires holding or collecting water, like the shared data and / or behavior present in an abstract class. But each of them requires its own, separate, implementation in order to work properly; this is the specialization of a concrete class.
Your mileage may vary, but I’ve found this to be a useful metaphor when I explain inheritance to students.