Insight 19.10.1.
You need to understand that if a class is abstract, you can not directly make an object of that type. Other than that, there is nothing special you need to do while using them.
GeometricObject
class from the previous section, by doing something like GeometricObject g("black");
, we will get an error that says:
error: cannot declare variable ‘g’ to be of abstract type ‘GeometricObject@GeometricObject’
GeometricObject
promises that each GeometricObject
should have a getArea()
method, but does not actually provide one. Thus there is no way to make a GeometricObject
—it is lacking a needed function.
GeometricObject
constructor protected
to indicate that it should only be used from subclasses.)
GeometricObject
, it still serves an important role in our design. It can provide concrete code, like GeometricObject
does for getColor()
and toString()
, that subclasses will inherit. It also allows us to write code like checkObject
that can work with Rectangle
s, Circle
s, and any other GeometricObject
subclasses.
<<Abstract>>
. So GeometricObject
should be shown like this in a UML diagram to indicate that it is an abstract class:
classDiagram class Circle { +getArea() double } class Rectangle { +getArea() double } class `*GeometricObject*` { <<Abstract>> +getArea()* double } `*GeometricObject*` <|-- Circle `*GeometricObject*` <|-- Rectangle
print
in Listing 19.9.3).GeometricObject&
).
Printable
interface that declares a pure virtual print
function:
class Printable {
public:
virtual void print() const = 0;
}
Printable
must provide a definition for the print
function. We often call this “implementing an interface”.
printObject
that is able to print any object that has implemented the Printable
interface. That object could be a GeometricObject
, a Person
, or anything else that inherits Printable
:
class Printable {
public:
virtual void print() const = 0;
}
class GeometricObject : public Printable {
...other code...
public:
virtual void print() const {
cout << "GeometricObject: " << getColor() << endl;
}
};
class Person : public Printable {
...other code...
public:
virtual void print() const {
cout << "Person: " << getName() << endl;
}
};
void printObject(const Printable& obj) {
obj.print();
}
printObject
accepts a Printable
object. It knows that is-a Printable
must have a print
function that can be called, so obj.print()
is must be allowed. It does not need to know anything else about the specific type of object it is printing.
<<Interface>>
.
classDiagram class Circle { +getArea() double } class Rectangle { +getArea() double } class `*GeometricObject*` { <<Abstract>> +getArea()* double +print() void } class Person { +getName() string +print() void } class Student { +getMajor() string +print() void } class `*Printable*` { <<Interface>> +print()* void } `*GeometricObject*` <|-- Circle `*GeometricObject*` <|-- Rectangle `*Printable*` <|.. `*GeometricObject*` `*Printable*` <|.. Person Person <|-- Student