Object Oriented ProgrammingLecture II Classes, Objects, Abstract Data Types, Representation Invariants, Mutables and Immutables
Terminology of Classes and Objects • The Class construction • The structure for representation of objects of similar kind • Methods – how to compute on data (Algorithms) • Constructor – init the state of an object • Variables – the state of an object (Data) • Objects • An object has a unique identity, a state and a representation • We instantiate objects out of classes and use them together in a program
Definition of Object Equality • Objects are equal when they have the same state (usually comparing variables) • Objects are identical when they share class identity • For objects, the expression r1 == r2 tests identity, NOTequality • identity comparison made by ’==’ operator in Java • Equality is tested by the equals() method • object equality is defined by the programmer
References in Java • Java uses message passing • all objects are passed by reference • but primitive types are passed by value • Advice • be careful when objects and especially data collections are shared (such ”problems” will appear in the lab project)
Wrapper Classes • What is a wrapper and why is it needed? • Primitives are not objects, therefore object oriented techiques cannot be applied on primitive types • Wrapper classes are ”type” containers for primitives • Examples are: Integer, Float, Byte... etc. • These are all of immutable type, and arithmetic operators can not directly be applied • To calculate, we need to unwrap... and then wrap again. If a, b, c are Integer type, then • c = new Integer(a.intValue() + b.intValue());
Accessing Object Internals The state of an object can be mutable or immutable. • mutable, when internal values (variables) can be changed • immutable, when internal values are not changed • Accessors • methods that doesn’t change any values, only return values • public int getVal() {return value;} • Mutators • Methods that can change the value of the state variables • public void setVal(int scalar){value = scalar;}
Example: The Point Class PublicClass Point{ int x,y; Point(int x1,int y1){ x = x1, y = y1; } publicvoid move(int x1,int y1){ x = x1; y = y1; } publicint getX(){return x;} publicint getY(){return y;} }
Example Cnt’d Public Class Point{ int x,y; Point(int x1,int y1){ x = x1, y = y1; } public void move(int x1,int y1){ x = x1; y = y1; } public int getX(){return x;} public int getY(){return y;} public boolean repOk(){x != null && y != null;} } State representation State initializer Mutator Accessors
Representation Invariant • The representation invariant of a class is • a state condition that always is guaranteed to be legal, for allobjectinstances, whenever the object is in its stable state • Conditions for the representation invariant • 1. The invariant must be established when creating a new object • 2. Mutators must always preserve the invariant • For simple testing of an invariant • implement a method booleanrepOk()
Abstract Data Types • Consider the following problem: • we need to express and compute on rational numbers like: 1/3, 2/3, 11/6...etc. • we want to be able to formulate arithmetic expressions, such as • 1/3+2/3 = 3/3 (= 1) • 2/3+4/5 = (2*5/3*5) + (4*3/5*3) = 22/15 • Question: How can we do this?
The Abstract Type Rational Constructors: Rational(), Rational(int), Rational(int,int); Arithmetic operations: plus(Rational a, Rational b) minus(Rational a, Rational b) div(Rational a, Rational b) times(Rational a, Rational b) Other methods: toString(),equals(Object x),compareTo(Object x)
Computing with Rational public static void main(String[] args){ Rational sum = 0; for(int i;i<100;i++){ sum += 1/i; } System.out.println(sum); } We can’t overload objects with primitive types! We need to define toString();
A Second Try with Rational Public static void main(String[] args){ Rational sum = new Rational(); for(int i = 1;i<100;i++){ sum = Rational.sum(sum,new Rational(1,i)); } System.out.println(sum); }
Representation Invariant for Rational • Before implementation, we need to make a few decisions • 1. What are legal values for a Rational? • all integer fractions a/b, where b ≠ 0 • 2. We also decide to allow Rationals to have either positive or negative • How do we handle sign representation? • 3. Let the numerator carry the (-) sign
Lets do some implementation... Public Class Rational{ private num,den; public Rational(){ this(0,1); } public Rational(int num){ this.(num,1); } public Rational(int num, int den){ this.num = num; this.den = den; } } The state of Rational is ”hidden” (private) Hey, wait a minute...
Taking Care of the Invariant Public Rational(int num,int den){ if(den == 0){ throw new ArithmeticException(”zero denominator is illegal”); }else{ this.num = den<0 ? –num:num; this.den = Math.abs(den); simplify(); } } Numerator carries the sign! Auxillary method for deriving canonical representation of Rationals
What about this Simplify thing? • Simplify() is a private help method to compute the Greates Common Divisor (GCD) of a rational number. Private void simplify(){ int d = gcd(num,den); num = num/d; den = den/d; } Private static gcd(int a, int b){ if (a==0) return b; else return gcd(b%a,a); }
Static Methods We want to use Rational Arithmetic anywhere in our programs. A solution is to make methods static. public static Rational plus(Rational a, Rational b){ return new Rational(...); } Rational Arithmetics can now be used anywhere without instantiating Rational.
Extending Our Number Represenation • What about complex numbers? • A complex number has two components • a real and an imaginary part • Interesting observation, each component can be expressed by a rational...
Designing Complex Class • What operators do we need to support? • {+, -, *, /} • What is the representation invariant? • real and imaginary component ≠ null • When are two complex numbers equal? • We define this to be when magnitude and direction of a = magnitude and direction of b
Complex Interface Constructors: Complex(); Complex(Rational re, Rational im); Arithmetic operations: plus(Complex a, Complex b); minus(Complex a, Complex b); times(Complex a, Complex b); div(Complex a, Complex b); Auxillary: conjugate(Complex c); Overload the arithmetic operators in Rational Helpful when computing division!!
class Complex{ private Rational real; private Rational imag; Complex(){ this(new Rational(), new Rational()); } Complex(Rational real, Rational imag){ this.real = real; this.imag = imag; } } ? The Complex Constructor
Complex Arithmetic
Exercise 1 & 2 • 1. Implement the Class Rational • 2. Implement the Class Complex