slanted W3C logo

Day 05 — Delegation

Today's class introduces some of the fundamental concepts of object-oriented programming. The idea of delegation and the mechanics of delegating to a utility class are discussed.

Client-View Programming

client
a customer or patron; someone who receives a service

In 1020, the client is you, the programmer of the main method. You are called a client because you will need to shop for components that can provide you with services that can help you solve a programming problem.

We have already used one component named System.out; that component provided us with services named print and println that let us send output to a console.

Delegation

to delegate
to entrust to another

As the client, you can choose to entrust computation to a component.

What are some advantages of delegating computation?

Delegating Computation

Suppose you want to know how to translate "hi" in French.

1. Find someone who is fluent in French.

2. Ask, "Celine, how do you say hi in French?"

3. Celine replies, "Salut."

To Delegate You Need:

To delegate computation you need:

  1. a component to perform the computation
    • Celine
  2. to name the task you want the component to perform
    • translate
  3. to provide the component with some information
    • "hi"

The component will:

  1. return the value of the computation (if necessary)
    • "salut"

Utility Class

In Java, a utility class is a component that groups together related tasks into a single place.

For example, the utility class java.lang.Math groups together a number of mathematical tasks. You can compute the square root of 2.0 by writing:

double irrational = Math.sqrt(2.0); 
  1. a component to perform the computation
    • Math
  2. name the task you want the component to perform
    • sqrt
  3. provide the component with some information
    • 2.0

The component will:

  1. return the value of the computation (if necessary)
    • 1.4142135623730951, which we store in the variable named irrational

static Methods

double irrational = Math.sqrt(2.0); 

sqrt is a static method that is a member of the utility class Math.

A method performs a task.

The parentheses enclose the information you want to give to the method. In this example, the information is the literal 2.0. Each piece of information is called an argument.

We say, "we invoke the sqrt method on the Math class passing 2.0 as the argument."

*Note that you do not have to use a literal as an argument. Any value whose type is compatible with double can be used as an argument for sqrt.

static Methods

Some methods require more than one argument to invoke. For example, the hypot method of Math computes the length of the hypotenuse of a right angle triangle.

public class Hypotenuse
{
   public static void main(String[] args)
   {
      double side1 = 3.0;
      double side2 = 4.0;
      double side3 = Math.hypot(side1, side2);
   }
}

Multiple arguments are passed to the method using a comma followed by a space to separate the arguments.

static Attributes

The Math utility also stores some mathematical constants, namely the values for e and π. Data stored by a class are called static attributes. Like variables, attributes have a name, type, and value.

Constant values are usually named using all capital letters. The constants in Math are called E and PI; they both have type double. You access them by using their name and no parentheses.

System.out.println(Math.E);
System.out.println(Math.PI);
double radius = 5.0;
double circleArea = Math.PI * radius * radius;

Looking Ahead: Non-Primitive Attributes

Attributes can be other components called objects, and the client can delegate to these objects. You invoke methods on an object much like you invoke methods on a class.

One example is the utility class named System. It has an attribute named out that we have been using to print strings to the screen.

System.out.println("Hello");

It also has an attribute named in that on a PC can be used by another component to read input from the keyboard.

import java.util.Scanner;

public class InputExample
{
   public static void main(String[] args)
   {
      Scanner input = new Scanner(System.in);

      System.out.println("Enter the temperature in Fahrenheit");
      int degF = input.nextInt();

      // convert degF to Celsius...
   }
}

Constants and Magic Numbers

Notice that by giving the mathematical constants a name (E and PI) it is very easy for the reader to tell what they represent. This might be a good idea for client code as well. For example, what does the following fragment do?

double c = 0.5555555555555556 * (f - 32);

Literals such as 0.5555555555555556 and 32 that appear in an expression are called magic numbers because it is often difficult to determine exactly what they represent (but they work!).

Constants and Magic Numbers

If we used some meaningful names, it becomes clearer that the expression converts from degrees Celsius to degrees Fahrenheit.

final double DEG_F_PER_DEG_C = 5.0 / 9;
final int ZERO_C_IN_F = 32;

double c = DEG_F_PER_DEG_C * (f - ZERO_C_IN_F);

The modifying keyword final means that we can only assign a value to the modified name once (i.e., DEG_F_PER_DEG_C and ZERO_C_IN_F are effectively constants).

Java convention and our coding style uses all capital letters and underscores for names of constants.

Our coding style says that the only magic numbers you may use outside of a final statement are -2, -1, 0, 1, and 2.

Features and UML Diagrams

The methods and attributes of a class that are available to ordinary clients are called the features of the class. One tool that software engineers use to concisely convey class features is the Unified Modelling Language (UML) class diagram.

For the Math utility class, you start by writing

« utility »
java::lang::Math

Features and UML Diagrams

You list the attributes in the next section. You give the attribute name, followed by a colon, followed by its type.

« utility »
java::lang::Math
E: double
PI: double

Features and UML Diagrams

You list the methods in the next section. You give the method name, the comma separated list of parameter types in parentheses, and the return type.

« utility »
java::lang::Math
E: double
PI: double
hypot(double, double): double
sqrt(double): double

Interfaces

A UML class diagram gives a concise description of the features of a class; however, as a client you probably need more information than the class diagram provides. For this, we introduce the notion of an interface.

A driver drives a car using a reasonably small number of controls and information displays:

The controls and displays form the driver's interface to the car.

The car's interface allows the driver to easily control the car without the driver needing to know how the car exactly works. Imagine how difficult it would be to drive a car if the driver had to synchronize the control of all of the individual car components.

Software Interfaces

As a client programming in Java, you are primarily interested in two features when using a component:

  1. what attributes of the component you can directly use
  2. what methods of the component you can directly invoke

The attributes and methods that are directly usable by a client are called public features of the component.

The public features are documented in the Application Programming Interface (API) of the component.

The API only describes what actions a component can perform, but not how the component actually performs the action.

Software Interfaces

The component can also have features that are hidden from the client. These private features are not part of the component's API (see the discussion on access modifiers on page 62 of the textbook). These hidden features are typically related to how the component provides its functionality.

Features that are labelled protected are part of the API, but are not directly accessible to normal clients. They are used by special clients (class implementers) when extending an existing class.

In 1020, we use the term encapsulation to describe the separation of the interface from the implementation.