Concepts / Abstract Classes and Interfaces

Abstract Classes and Interfaces

Concrete classes are usable directly, while abstract classes describe what related types must provide.

  • Programming

Why Programs Need Their Own Types

Every piece of data a program works with has a type. The type tells the language what kind of thing the data is and which operations make sense on it. A language comes with some types already built in, but real programs usually model ideas that the language designers could not predict: an invoice, a sensor reading, a game character, a network connection. If a program can only use the built-in types, it has to describe these ideas with loose collections of plain values, and the code drifts away from the problem it is trying to solve.

What do you think happens?

A program needs to represent an invoice, which has a customer, line items, and a total. Which approach matches the program's vocabulary to the problem best?

  • Keep the invoice as a loose set of unrelated numbers and strings

  • Define a new type that represents an invoice as a single meaningful unit

Reveal answer
Answer:

Define a new type that represents an invoice as a single meaningful unit

C++ lets you define new types of your own, so the program's vocabulary can match the problem it solves. Types defined this way are called user-defined types.

This article follows one idea through the chapter. We will watch what a user-defined type contains, how the three families of user-defined type differ, and how they connect to one another. Keep an eye on two goals as you read: abstraction and resource management.

What a User-Defined Type Bundles Together

Definition

A user-defined type is a type that the programmer defines, so that the program's vocabulary can match the problem it solves.

The idea is more than naming a new kind of thing. A user-defined type bundles data together with the operations that are allowed on that data. The rest of the program can then treat the new type as one meaningful unit instead of a loose collection of values. Think of the bundle as having two parts: the data it holds, and the operations the outside world may perform on that data.

  1. 1
    Identify an idea in the problem, such as an invoice or a sensor reading.
  2. 2
    Define a type whose name matches that idea, so the program's vocabulary mirrors the problem.
  3. 3
    Decide what data the type holds and which operations are allowed on that data.
  4. 4
    Use the type as a single unit everywhere else in the program.

Abstraction and Resource Management

C++ supports two broad goals in this part of the course. The first is abstraction. Abstraction hides the messy details of how something works behind a simpler interface, so that a user of a type can focus on what it does rather than how it does it. The second is resource management. Resource management handles things a program must acquire and later give back, such as memory or other limited items, in a disciplined way.

User-defined types are the main tool that brings these goals together. The type decides what the outside world can see and do. It can also control how the resources behind it are handled. So when you read about the three families below, ask two questions about each one: how does it hide detail, and how does it handle the resources it depends on?

The Three Families of User-Defined Type

This overview introduces three families of user-defined type: concrete classes, abstract classes, and class hierarchies. It does not work through each one in full detail. Instead, it gives the basic properties of each, the general implementation techniques behind them, and the language features that support them. The three families are not separate islands. All of them belong under the umbrella of user-defined types, and a class hierarchy is the structure that ties several related types together.

User-defined typesConcrete classesusable directlyAbstract classesdescribe what related typesmust provideClass hierarchiestie related types togetherfamilyfamilyfamily
User-defined types sit at the top, and the three families appear beneath them. Class hierarchies tie related types together, so the tree shows how each family relates to the umbrella.

Tracing a Hierarchy from Abstract to Concrete

The source describes abstract classes as describing what related types must provide. To see this in a concrete setting, follow a small family of types that share a common idea. The names Shape, Circle, and Square below are generated for teaching; they are not taken from the source, but they show how the pieces of a class hierarchy fit together.

Shapeabstract classCircleconcrete classSquareconcrete classbase forbase for
Shape sits at the top as an abstract class. Circle and Square build on it as concrete classes, so each one is a related type that must provide what Shape describes.
Worked example

Reading the Shape Family

Given the Shape family, which types can a program create finished objects from, and what does Shape contribute?

  1. 1
    Apply the one question

    Ask whether you can create a finished object straight from each type.

  2. 2
    Check Shape

    Shape is the abstract class at the top. It describes what related types must provide, so it is not the type you create finished objects from.

  3. 3
    Check Circle and Square

    Both are concrete classes. They build on Shape and are usable directly, so finished objects can be created from them.

  4. 4
    Relate the families

    The hierarchy ties the family together: the abstract class sets the requirements, and the concrete classes meet them.

Result

Circle and Square can be used to create finished objects. Shape describes what they must provide, and the class hierarchy is the structure linking all three.

Concrete Classes Versus Abstract Classes

Concrete and abstract classes are easiest to tell apart by asking one question: can you create a finished object straight from this type? A concrete class passes this test. An abstract class does not. Concrete classes are usable directly, while abstract classes describe what related types must provide. The table compares the two on the points this overview covers.

QuestionConcrete classAbstract class
Can you create a finished object straight from it?YesNo
What role does it play?Usable directlyDescribes what related types must provide
How does it fit a hierarchy?Can build on a related type and be used directlySets the requirements that related types must meet

Concrete and abstract classes compared on the points covered in this overview.

Key point

Ask whether you can create a finished object straight from the type. If yes, it is a concrete class. If no, it is an abstract class that describes what related types must provide.

Mistakes Learners Make with the Three Families

  • Common mistake

    Treating every user-defined type as usable directly

    What it looks like

    Assuming Shape in the example above can be used to create a finished object just like Circle can.

    Why it fails

    The one question separates the families. An abstract class describes requirements rather than being a finished, usable type.

    Do this instead

    Ask whether you can create a finished object straight from the type before deciding how to use it.

  • Common mistake

    Thinking the three families are unrelated

    What it looks like

    Treating class hierarchies as a separate topic with no link to concrete or abstract classes.

    Why it fails

    All three belong under the umbrella of user-defined types, and a class hierarchy is the structure that ties related types together.

    Do this instead

    Place each family under user-defined types and look at how the hierarchy connects them.

  • Common mistake

    Forgetting the two goals when reading each family

    What it looks like

    Studying a family only for its syntax and ignoring what it does for the outside world and for resources.

    Why it fails

    User-defined types exist to support abstraction and resource management, and each family serves those goals in a different way.

    Do this instead

    For each family, ask how it hides detail and how it handles the resources behind it.

Check Your Understanding of the Families

EASY

A team is designing a program with three types: Vehicle, Car, and Truck. Vehicle describes what every kind of vehicle must provide, while Car and Truck are types the program creates finished objects from. Which family is Vehicle, which are Car and Truck, and how do they relate?

Hints
  • Ask whether you can create a finished object straight from Vehicle.
  • Think about what a class hierarchy does to related types.
  • Remember that all three families sit under user-defined types.

Key Takeaways

  • A user-defined type lets a C++ program define its own type, so the program's vocabulary matches the problem it solves, and it bundles data with the operations allowed on that data.
  • C++ supports two broad goals here: abstraction, which hides details behind a simpler interface, and resource management, which acquires and gives back limited items in a disciplined way.
  • The three families are concrete classes, abstract classes, and class hierarchies, all under the umbrella of user-defined types.
  • Concrete classes are usable directly, while abstract classes describe what related types must provide. Ask whether you can create a finished object straight from the type to tell them apart.
  • A class hierarchy is the structure that ties several related types together, linking abstract and concrete classes through derivation.

Related concepts

More concepts starting with A