Object-Oriented Programming

UML Generalization

Michael L. Collard, Ph.D.

Department of Computer Science, The University of Akron

UML Class Relationships

Relationship Description
Dependency uses a
Generalization is a
Association has a
Aggregation (Association) has a
Composition (Association) has a

Generalization Terminology

Problems with Generalization

The purpose of generalization is to solve design problems. If you don’t have a design problem, don’t use generalization.

What design problems does generalization solve?

Scenario: Multiple Related Classes

Client Code

Problems

  • If new kinds of students are added, have to add more loops
  • Every new processing we add has to know about both undergraduate and graduate students
  • Have to remember to add new operations to both
  • Three different concepts:
    • Undergraduates
    • Graduates
    • Students - applies to both undergraduate and graduates

Solution

  • Client has an association with Student, but has no knowledge of Undergraduate/Graduate
  • Does Liskov hold? is_a relationship
    • An undergraduate is_a student
    • A graduate student is_a student
  • Single piece of code to manage students
  • New kinds of Students can be added without changing the client code

New Client Code

Bidirectional Association

This:

is this:

Code Implications

Problems with Bidirectional Associations

  • Code issues with declarations
  • Cannot be developed, tested, etc. separately
  • Cannot be used separately
  • Solution:
    • Extract only the parts of one of the participants that the other had

Solution

Solution Code

Advantages

  • Develop and test class CustomerBase individually
  • Develop and test classes Order & CustomerBase together
  • Develop and test classesCustomer & CustomerBase together
  • Often class CustomerBase would be very small and simple, mostly to define an interface

Polymorphism

  • In general

    the condition of occurring in several different forms

  • For design

    single interface to entities of different types

  • Same interface for different types
  • Which code is run depends on type

Static Polymorphism

  • Determined at compile time
  • static dispatch
  • In C++:
    • overloading (function and operator)
    • templates

Overloading Declarations

Without overloading:

with overloading:

Overloading Usage

overloading.cpp

Overloading

  • Advantages
    • Code is more flexible as types change
    • Easier to remember correct name
  • Disadvantages
    • Can disguise large differences in behavior
    • Can lead to bland and meaningless names, e.g., process()

Dynamic Polymorphism

  • Determined at run time
  • dynamic dispatch
  • Requires virtual methods
  • Advantages:
    • Flexibility
  • Disadvantages:
    • Slight speed disadvantage
    • Extra memory to support mechanism (vtables, vtable pointers)

Dynamic Polymorphism: Example Code

Dynamic Polymorphism: Example UML

Back To Students: What about Methods?

  • Of course, any Student object has costTuition()
  • Due to is_a relationship, so does any Undergraduate or Graduate object
  • Turn to the code

What if …

  • Undergraduate and Graduate need different implementations of costTuition()?
  • Could add the method to each (and implement differently)

Questions

  • Does it make sense to have a student who is neither an undergraduate or graduate?
  • Perhaps all students should be one or the other? (at least for now)
  • How do these get formed?
  • Back to the code: Code Example

Methods

  • non-virtual method
  • virtual method
  • pure-virtual method

Abstract Classes and Interfaces

  • Abstract Class
    • Consists of at least one pure-virtual method
    • Cannot create objects of that class type
    • Can only create objects of derived classes that implement all the pure-virtual methods
  • Interface
    • Mostly consists of all pure-virtual methods. However, many times used interchangably with Abstract Class
    • Sometimes, all empty methods

Design Choice

  • pure-virtual method

  • empty method