Introduction to Object Oriented Programming, 3rd Ed

Timothy A. Budd

Chapter 4

Classes and Methods

Outline

  1. Roadmap
  2. Same Ideas, Different Terms
  3. Encapsulation and Instantiation
  4. Internal and External Views
  5. Behavior and State
  6. Class Definitions
    1. A Typical Example, Class Definition n C++
    2. Visibility Modifiers
    3. A C# Class Definition
    4. A Java Class Definition
      1. Static and Final
    5. Pascal Dialects
      1. A Class Definition in Apple Object Pascal
      2. A Class Definition in Delphi Pascal
    6. A Class Definition in Smalltalk
  7. Methods
    1. An Example, from C#
    2. Constructors
    3. Accessor (or getter) methods
      1. Why use an Accessor?
      2. Setters (or mutators)
      3. Constant Data Fields
    4. Order of Methods
    5. Separation of Definition and Implementation
      1. Consderations in Method Definitions
  8. Variations on Classes
    1. Methods without Classes in Oberon
    2. Interfaces in Java
    3. Properties
      1. Properties in C#
    4. Inner or Nested Classes
    5. Class Data Fields
  9. Chapter Summary

Other Material

Intro OOP, Chapter 4, Outline

Roadmap

Chapters 4 and 5 present two sides of OOP:

Both are important, and both chapters should be understood before you begin further investigation of object-oriented programming
Intro OOP, Chapter 4, Slide 1

Same Ideas, Different Terms

All OOP languages have the following concepts, although the terms they use may differ:

Intro OOP, Chapter 4, Slide 2

Encapsulation and Instantiation

Classes provide a number of very important capabilities:

Intro OOP, Chapter 4, Slide 3

Internal and External Views

two views of software

As we noted in the last chapter, encapsulation means there are two views of the same system. The outside, or service view, describes what an object does. The inside, or implementation view, describes how it does it.

Intro OOP, Chapter 4, Slide 4

Behavior and State

A class can also be viewed as a combination of behavior and state.
Intro OOP, Chapter 4, Slide 5

Class Definitions

We will use as a running example the class definition for a playing card abstraction, and show how this appears in several languages.

(Not all languages are shown in the overhead slides, more are provided in the textbook and on the web pages for the book).

Languages we will consider in this book include Java, C++, C#, Delphi Pascal, Apple Pascal, Ruby, Python, Eiffel, Objective-C and Smalltalk.

Intro OOP, Chapter 4, Slide 6

A Typical Example, Class Definition in C++


class PlayingCard {
public:
    enum Suits {Spade, Diamond, Club, Heart};

    Suits suit () { return suitValue; }
    int   rank () { return rankValue; }

private:
    Suits suitValue;
    int   rankValue;
};

Note syntax for methods, data fields, and visibility modifiers. (Will see more on syntax later).

Intro OOP, Chapter 4, Slide 7

Visibility Modifiers

The terms public and private are used to differentiate the internal and external aspects of a class.

Typically methods are public and data fields are private, but either can be placed in either category.

Intro OOP, Chapter 4, Slide 8

A C# Class Definition


enum Suits {Spade, Diamond, Club, Heart};

class PlayingCard {
    public Suits suit () { return suitValue; }
    public int   rank () { return rankValue; }

    private Suits suitValue;
    private int   rankValue;
}

C# class definitions have minor differences, no semicolon at end, enum cannot be nested inside class, and visibility modifiers are applied to methods and data fields individually.
Intro OOP, Chapter 4, Slide 9

Java Class Definition


class PlayingCard {
    public  int suit () { return suitValue; }
    public  int rank () { return rankValue; }

    private int suitValue;
    private int rankValue;

    public static final int Spade = 1;
    public static final int Diamond = 2;
    public static final int Club = 3;
    public static final int Heart = 4;
}

Java also applies visibility modifiers to each item indivually. Does not have enumerated data types, uses symbolic constants instead.
Intro OOP, Chapter 4, Slide 10

Static and Final

Notice how symbolic constants are defined in Java:

Intro OOP, Chapter 4, Slide 11

Pascal Dialects

We will consider two dialects of Pascal, both descended from the earlier language.


Many similaries due to the common heritage, but some important differences.

(We consider only the language aspects of Delphi, there are many other features related to its visual interface that we will not describe).

Intro OOP, Chapter 4, Slide 12

Class Definition in Apple Object Pascal


type
    Suits = (Heart, Club, Diamond, Spade);

    PlayingCard = object
        suit : Suits;
        rand : integer;
    end;

No explicit visibility modifiers. (Will later see syntax for methods).
Intro OOP, Chapter 4, Slide 13

Delphi Pascal


type
    Suits = (Heart, Club, Diamond, Spade);

    TPlayingCard = class (TObject)
        public
            constructor Create (r : integer; s : Suits);

            function suit : Suits;
            function rank : int;

        private
            suitValue : Suits;
            rankValue : integer;
    end;

Slightly different syntax, must name parent class, has visibility modifiers and constructors (more on those later).
Intro OOP, Chapter 4, Slide 14

Smalltalk

Smalltalk doesn't have a textual description for classes, but instead you define classes in a visual interface. (Revolutionary idea in 1980, but now Visual Basic and Delphi programmers are used to similar facilities).

Intro OOP, Chapter 4, Slide 15

Methods

Although syntax will differ depending upon language, all methods have the following:
Intro OOP, Chapter 4, Slide 16

An Example, from C#


class PlayingCard {
		// constructor, initialize new playing card
	public PlayingCard (Suits is, int ir) 
		{ suit = is; rank = ir; faceUp = true; }

		// operations on a playing card
	public boolean isFaceUp  ()           { return faceUp; }
	public int     rank      ()           { return rankValue; }
	public Suits   suit      ()           { return suitValue; }
	public void    setFaceUp (boolean up) { faceUp = up; }
	public void    flip      ()           { setFaceUp( !faceUp);}
	public Color   color     ()           { 
		if ((suit() == Suits.Diamond) || (suit() == Suits.Heart)) 
			return Color.Red;
		return Color.Black;
	}
		// private data values
	private Suits suitValue;
	private int rankValue;
	private boolean faceUp;
}

Intro OOP, Chapter 4, Slide 17

Constructor


class PlayingCard {
		// constructor, initialize new playing card
	public PlayingCard (Suits is, int ir) 
		{ suit = is; rank = ir; faceUp = true; }
	...

}

A constructor is a method that is used to initialize a newly constructed object. In C++, Java, C# and many other languages it has the same name as the class. We will talk about constructors more in the next chapter.
Intro OOP, Chapter 4, Slide 18

Accessor (or getter) Methods

An accessor (or getter) is a method that simply returns an internal data value:

class PlayingCard {
	...
		// operations on a playing card
	public int     rank      ()           { return rankValue; }
	public Suits   suit      ()           { return suitValue; }
	...
	private int rankValue;
}

Intro OOP, Chapter 4, Slide 19

Why Use an Accessor?

There are many reasons why an accessor is preferable to providing direct access to a data field.

Some conventions encourage the use of a name that begins with get, (as in getRank()), but this is not universally followed.

Intro OOP, Chapter 4, Slide 20

Setters (or mutators)

A setter (sometimes called a mutator method) is a method that is used to change the state of an object:

class PlayingCard {

		// operations on a playing card
	public void    setFaceUp (boolean up) { faceUp = up; }
		...
		// private data values
	private boolean faceUp;
}

Mutators are less common than accessors, but reasons for using are similar.
Intro OOP, Chapter 4, Slide 21

Constant Data Fields

Some languages allow data fields to be declared as constant (const modifier in C++, final in Java, other languages have other conventions).

Constant data fields can be declared as public, since they cannot be changed.


class PlayingCard { // Java example
	...
    public static final int Spade = 1;
    public static final int Diamond = 2;
    public static final int Club = 3;
    public static final int Heart = 4;
}

Intro OOP, Chapter 4, Slide 22

Order of Methods

For the most part, languages don't care about the order that methods are declared. Here are some guidelines:

Remember that class definitions will often be read by people other than the original programmer. Remember the reader, and make it easy for them.

Intro OOP, Chapter 4, Slide 23

Separation of Definition and Implementation

In some languages (such as C++ or Object Pascal) the definition of a method can be separated from its implementation. They may even be in a different file:

class PlayingCard {
public:
	...
	Colors  color     () ;
	...
};

PlayingCard::Colors PlayingCard::color ( ) 
{		
		// return the face color of a playing card
	if ((suit == Diamond) || (suit == Heart))
		return Red;
	return Black;
}

Notice need for fully-qualified names.
Intro OOP, Chapter 4, Slide 24

Considerations in Method Definitions

In C++ you have a choice to define a method in the class interface, or separately in an implementation file. How do you decide?
Intro OOP, Chapter 4, Slide 25

Variations on Classes

We will consider a few of the mostly language-specific variations on the idea of a class.
Intro OOP, Chapter 4, Slide 26

Methods without Classes in Oberon

Oberon does not have classes, per se, but allows methods to be defined as a funny type of function:

TYPE
	PlayingCard = POINTER TO PlayingCardDesc;

	PlayingCardDesc = RECORD
		suit : INTEGER;
		rank : INTEGER;
		faceUp: BOOLEAN;
	END

PROCEDURE (aCard: PlayingCard) setFaceUp (b : BOOLEAN);
BEGIN
	aCard.faceUp = b;
END

Intro OOP, Chapter 4, Slide 27

Interfaces in Java

An interface is like a class, but it provides no implementation. Later, another class can declare that it supports the interface, and it must then give an implementation.

public interface Storing {
	void writeOut (Stream s);
	void readFrom (Stream s);
};

public class BitImage implements Storing {
	void writeOut (Stream s) {
		// ...
	}
	void readFrom (Stream s) {
		// ...
	}
};

We will have much more to say about interfaces later after we discuss inheritance.
Intro OOP, Chapter 4, Slide 28

Properties

Properties are a way to define getters and setters, but allow them to be used as if they were simple assignments and expressions:

writeln ('rank is ', aCard.rank); (* rank is property of card *)
aCard.rank = 5; (* changing the rank property *)

Intro OOP, Chapter 4, Slide 29

Properties in C#


public class PlayingCard {
	public int rank {
		get 
		{
			return rankValue;
		}
		set 
		{
			rankValue = value;
		}
	}
	...
	private int rankValue;
}

Omitting a set makes it read-only, omitting a get makes it write-only.
Intro OOP, Chapter 4, Slide 30

Inner or Nested Classes

Some languages (C++ or Java) allow a class definition to be given inside another class definition. Whether the inner class can access features of the outer class is different in different languages.

class LinkedList {

	...
	private class Link { // inner class
		public int value;
		public Link next;
	}
}

Intro OOP, Chapter 4, Slide 31

Class Data Fields

Idea is that all instances of a class can share a common data field. Simple idea, but how to resolve the following paradox. All instances have the same behavior: Different languages use a variety of mechanisms to get around this. See text for details.
Intro OOP, Chapter 4, Slide 32

Chapter Summary

In this chapter we have examined the static, or compile time features of classes:
Intro OOP, Chapter 4, Slide 33