I like the answers by
@Mark44 and
@jedishrfu, and also the link to the
Wikibooks article; in part because that article hints at a more general answer that I think could be fleshed out more. The hint is in statements such as this one:I am not the person to really explain this, because I haven't coded seriously in at least 10 years. But back when I did code, I was doing it partly for fun, and partly to support various projects in my work as contract a technical writer/editor; and for whatever reason I got heavily into reading about how OOP languages were meant to work from a philosophical POV, as well as how to build them from a "best practices" POV. So all this rings a very faint bell for me, from what seems a long time ago.
If you are just learning & doing coding by yourself, designing & building one-off programs, stuff like abstract classes may not seem important; but it becomes very important as projects get larger & you start to work in teams & the code itself starts to span many generations & implementations etc.; and/or will be ported to many platforms; etc. Old-style procedural code could and did turn into a horrible mess; and so will big OOP projects unless techniques & conventions are employed to prevent it. And I would consider abstract classes one of these devices.
So although I am sure someone else can explain it more accurately than I can, my guess is that in response to
@FallenApple's question about the "purpose" of abstract classes, we might say that one purpose is to aid in constraining & guiding the
design of the system (via using abstract classes for base classes), without constraining the
implementation. And the more complex the system, the more useful this approach will be.
Most of my books on good coding practice are now in boxes at another location, but by Googling I did find a journal article that talks about this sort of thing - one of a zillion I'm sure; also it's quite old - 1991! - so it uses
Smalltalk as its example language. The article is "
Designing Reusable Classes," by Ralph E. Johnson & Brian Foote,
Journal of Object-Oriented Programming, June/July 1988; here is the abstract; bold is mine; note much of what is described will seem somewhat dated:
Object-oriented programming is as much a different way of designing programs as it is a different way of designing programming languages. This paper describes what it is like to design systems in Smalltalk. In particular, since a major motivation for object-oriented programming is software reuse, this paper describes how classes are developed so that they will be reusable.
And here is a short excerpt specifically talking about abstract classes & their use in building frameworks:
A class that is not abstract is concrete. In general, it is better to inherit from an abstract class than from a concrete class. A concrete class must provide a definition for its data representation, and some subclasses will need a different representation. Since an abstract class does not have to provide a data representation, future subclasses can use any representation without fear of conflicting with the one that they inherited.
Creating new abstract classes is very important, but is not easy. It is always easier to reuse a nicely packaged abstraction than to invent it. However, the process of programming in Smalltalk makes it easier to discover the important abstractions. A Smalltalk programmer always tries to create new classes by making them be subclasses of existing ones, since this is less work than creating a class from scratch. This often results in a class hierarchy whose top-most class is concrete. The top of a large class hierarchy should almost always be an abstract class, so the experienced programmer will then try to reorganize the class hierarchy and find the abstract class hidden in the concrete class. The result will be a new abstract class that can be reused many times in the future.
3. Toolkits and Frameworks
One of the most important kinds of reuse is reuse of designs. A collection of abstract classes can be used to express an abstract design. The design of a program is usually described in terms of the program's components and the way they interact. For example, a compiler can be described as consisting of a lexer, a parser, a symbol table, a type checker, and a code generator.
An object-oriented abstract design, also called a framework, consists of an abstract class for each major component. The interfaces between the components of the design are defined in terms of sets of messages. There will usually be a library of subclasses that can be used as components in the design. A compiler framework would probably have some concrete symbol table classes and some classes that generate code for common machines. In theory, code generators could be mixed with many different parsers. However, parsers and lexers would be closely matched. Thus, some parts of a framework place more constraints on each other than others.
Etc. As I say no doubt much of this is dated, but it does suggest the larger concept; maybe someone else can give an example that is more current or illustrates the advantages more specifically, e.g. the difference between an abstract class & an interface in terms of design, etc. Also I gather that frameworks are still in use as a general organizing concept - here is the Wikipedia article on "Software frameworks":
https://en.wikipedia.org/wiki/Software_framework
---
P.S. Brian Foote's name as one of the authors of the paper sounded very familiar to me, so I tried to look him up in Wikipedia & found he was mentioned only in an article titled "
Big ball of mud" (!). A more general search finds that he is still active in the field, or at least he was as of 2009, and still writing & talking about larger patterns in software; here is a 2009 interview with him in
informIT, "
Brian Foote on the 15th Anniversary of Design Patterns." So probably I must have come across his name years ago & just don't remember where. A little bio on him goes w/ that interview: "
Brian Foote has been writing programs professionally for over twenty years and has been doing research on object-oriented programming, languages, frameworks, architecture, evolution, and refactoring since the mid 1980s. He is also a consultant who has been active in the patterns community since its inception and was program chair of the PLoP '96 conference." So yeah, abstract classes etc.