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 Rectangles, Circles, 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