object orientation

66
1 Object Orientation James Brucker

Upload: paige

Post on 06-Jan-2016

32 views

Category:

Documents


4 download

DESCRIPTION

Object Orientation. James Brucker. History Questions. OO concepts of encapsulation, inheritance, and polymorphism are based on what language developed in the 1960's in Norway? What OO language introduced the notion of "message passing" between object? - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: Object Orientation

1

Object Orientation

James Brucker

Page 2: Object Orientation

2

History Questions

OO concepts of encapsulation, inheritance, and polymorphism are based on what language developed in the 1960's in Norway?

What OO language introduced the notion of "message passing" between object?

What modern OO language uses message passing?

you can try to invoke any method of any object at runtime. If the method is "private" you get a runtime exception.

Hint: used in mobile phones

Page 3: Object Orientation

3

Questions 2

In Java, what is escape analysis and what is its purpose?

What is the difference between a value type and a reference type?

In C#, how are value types implemented?

In C#, can you add a method to a class that already exists? How?

Page 4: Object Orientation

4

Objectives

Motivation for O-O Languages

Key Characteristics

Important Differences

Focus on C++, C#, Java, and JavaScript

Implementation of O-O Features

Organization of Data Members

Virtual Method Table (VMT)

Dynamic Binding

Page 5: Object Orientation

5

Designing a Stack

A basic data structure. What behavior is needed?

push( value ) Put a new value on top of stack.

pop( ) Pop and return the top of stack

isEmpty( ) Test if stack is empty.

isFull( ) Test if stack is full.

Pretty simple, huh?

Let's see how C handles this.

Stack

push( ): voidpop( ): valueisEmpty( ): boolisFull( ): bool

Page 6: Object Orientation

6

Stack in C (1): imperative style

Can you name some deficiencies in this code? (find 4)

void push( int value, int *stack, int *top, int size ) {

if ( *top >= size ) perror("Stack overflow");

stack[(*top)++] = value;

}

int pop( int *stack, int *top, int size ) {

if ( *top <= 0 ) perror("Stack underflow");

return stack[--(*top)];

}

int isEmpty( int *stack, int *top, int size) {

return (*top <= 0);

}

Page 7: Object Orientation

7

Stack in C (2): simplify the interface

What are the problems with this implementation?

int SIZE = 0;int *stack;int top = 0;int initStack( int size ) {

stack = (int *)malloc( size * sizeof(int) );if ( stack == null ) perror("InitStack failed");SIZE = size; top = 0;

}void push( int value ) {

if ( top >= SIZE ) perror("Stack overflow");stack[top++] = value;

}int pop( ) {

if ( top <= 0 ) perror("Stack underflow");return stack[--top];

}

int isEmpty( ) { return (top <= 0); }

Global variable for stack properties.

Page 8: Object Orientation

8

Stack in C (3): hide data members

What are the problems with this implementation?

static int SIZE = 0;static int *stack;static int top = 0;int initStack( int size ) {

stack = (int *)malloc(size*sizeof(int));if ( stack == null ) perror("InitStack failed");SIZE = size; top = 0;

}void push( int value ) {

if ( top >= SIZE ) perror("Stack overflow");stack[top++] = value;

}int pop( ) {

if ( top <= 0 ) perror("Stack underflow");return stack[--top];

}

int isEmpty( ) { return (top <= 0); }

Data Hiding: "static" variables have file scope.

Page 9: Object Orientation

9

Stack in Modula-2: abstraction

TYPE element = integer;MODULE Stack;IMPORT element;EXPORT push, pop, isFull, isEmpty;CONST size = 100;VAR data : array [1..size] of element;

top : integer;PROCEDURE push( value : element );BEGIN

if top = size THEN error("Stack overflow");else begin

top := top + 1;data[top] := value;

end;END push;

Module limits scope/accessibility of its members. Import/export external names.

Better: abstract data type, data hiding, less name space pollution. Problems?

(* Stack usage *)

push( data1 );

push( data2 );

y := pop( );

Page 10: Object Orientation

10

Stack Factory in Modula-2MODULE StackFactory;IMPORT element;EXPORT stack, push, pop, isFull, isEmpty;CONST size = 100;TYPE stack = RECORD

data : array [1..size] of element; top : integer;

END;PROCEDURE init_stack(var stk : stack);BEGIN

stk.top := 1;END init_stack;PROCEDURE push(var stk: stack; item: element);BEGIN

if stk.top >= size then error( );else stk.data[stk.top] := item;stk.top := stk.top + 1;

END push;

(* Stack is abstract type *)

var A, B: stack;

init_stack( A );

init_stack( B );

push( A, data1 );

push( B, data2 );

Page 11: Object Orientation

11

Three Pillars of O-O Programming Encapsulation

objects contain both data and methods that operate on the data

control over visibility (and access) to members Inheritance

one class can extend another class, inheriting its attributes and methods. Promotes code re-use.

Polymorphism the same behavior can be defined for different classes a reference variable can refer to different classes using a reference, a program can transparently invoke

a named behavior from different classes.

Page 12: Object Orientation

12

Other benefits of object-orientation

Reuse code using well-designed classes and inheritance. Limit complexity by dividing big project into classes. Better control over object creation (constructor) and

destruction (finalizer or destructor).

class DancingButton extends JButton {

public DancingButton( ImageIcon image ) {

___________( image ); // call parent constructor

this.image = image;

}

public void paint( Graphics g ) {

_______________( g ); // call parent's paint( )

dancer.dance( );

}

Page 13: Object Orientation

13

Stack class in C++ (1)using namespace std;class Stack {private:

int *stack;int size;int top;

public:Stack( int asize ) : size(asize) { // constructor

stack = new int[asize];top = 0;

}~Stack( ) { // destructor

delete [ ] stack;}void push(int value); // method prototypeint pop( );

}; semi-colon ends class definition.

Page 14: Object Orientation

14

Stack class in C++ (2)class Stack {public:

...void push(int value);int pop( );bool isEmpty( ) { return top <= 0; }bool isFull( ) { return top >= size; }

};

void Stack::push(int value) {if ( top >= size ) perror("Stack overflow");stack[top++] = value;

}int Stack::pop( ) {

if ( top <= 0 ) perror("Stack underflow");return stack[--top];

}

Methods defined outside of class.

Method prototype inside of class.

Page 15: Object Orientation

15

Stack class in C++: header file

#ifndef _STACK_H_#define _STACK_H_class Stack {private:

int *stack;int size;int top;

public:Stack(int size) { ... }void push(int value);int pop( );bool isEmpty( ) { return top <= 0; }bool isFull( ) { return top >= size; }

};#endif

stack.h

Page 16: Object Orientation

16

Stack class in C++: method definition

#include "stack.h"void Stack::push(int value) {

if ( top >= size ) perror("Stack overflow");stack[top++] = value;

}int Stack::pop( ) {

if ( top <= 0 ) perror("Stack underflow");return stack[--top];

}

stack.cc

Page 17: Object Orientation

17

Why 2 Files?

#include "stack.h"void Stack::push(int value) {

if ( top >= size ) perror("Stack overflow");stack[top++] = value;

}...

stack.cc

class Stack {public:

Stack(int size) { ... }void push(int value);int pop( );bool isEmpty( ) { return top <= 0; }bool isFull( ) { return top >= size; }

};

stack.h

Page 18: Object Orientation

18

What belongs in stack.h?

#ifndef _STACK_H_#define _STACK_H_class Stack {private:

int *stack;int size;int top;

public:Stack(int size) { ... }void push(int value);int pop( );bool isEmpty( ) { return top <= 0; }bool isFull( ) { return top >= size; }

};#endif

why code here?

Page 19: Object Orientation

19

Stack class in C++: application

#include "stack.h"int main( ) {

Stack mystack(20); // creates a Stack objectmystack.push(1);mystack.push(15);...

}

application.cc

Page 20: Object Orientation

20

Encapsulation (1)

C++: extends C, functions and variables can be global, file, or class scope.

int MAXSIZE = 1024;

char buf[MAXSIZE];

static int size = 0;

int fun( ) { ... }

class Stack {

private:

int size;

int top;

public:

void push(int x);

...

};

C# and Java: all functions and variables must be part of a class.

public class Stack {

private int top;

private int size;

private int *stack;

public void push(int x)

{ if (top>=size) ...;

stack[top++] = x;

}

public bool isEmpty( )

{ return top <= 0;

}

}

Page 21: Object Orientation

21

Encapsulation (2)

C++: members can be public, protected, or private, but not classes.

class Stack {private:

int top;int size;

protected:int *stack;

public:void push(int x);bool isEmpty( ) {

return top <= 0;}

};

C#: class can be public, private, or internal.

public class Stack {private int top;private int size;protected int *stack;public void push(int x){ if (top>=size) ...;

stack[top++] = x;}public bool isEmpty( ){ return top <= 0;}

}

Page 22: Object Orientation

22

Scope of Names

C++ and C#: namespace and "using namespace" control name visibility.

using System;

using System.Collections;

namespace MyCollection {

class Stack {

...

}

}

Java: package and "import".

package mycollection;

import java.io.File;

import java.util.*;

class Stack {

...

}

/* C++ */

using namespace System;

using namespace System::Collections;

Page 23: Object Orientation

23

Scope Resolution Operator

C++ uses "::" but "." for elements of a class.

C# uses "."

/* C# */class Stack :System.Collections.IEnumerator { void read( ) {

Console.ReadLine( ); }

}

Java uses "."

/* Java */class Stack implements java.util.Iterator {

java.util.Scanner in =new java.util.Scanner();void read( ) { in.nextLine( );}

}

Page 24: Object Orientation

24

Creating Objects

C++, C#, and Java all have constructors. A class may have multiple constructors.

In C++ declaring an object reference constructs it!

In C# and Java, must use "new" to create the object.

/* C++ */

Person p; // invokes default constructor

Person p("Joe"); // invokes Person::Person(string)

Person& q = p; // create object reference q

/* C# and Java */

Person p; // create object reference only

p = new Person("Joe");// invokes Person(String)

Page 25: Object Orientation

25

Inheritance

C++:

multiple inheritance

no universal base class

C#:

single inheritance

all classes are subclass of System.Object

a class can implement unlimited number of interfaces

Java:

single inheritance

all classes are subclass of java.lang.Object

a class can implement unlimited number of interfaces

Page 26: Object Orientation

26

Inheritance and Access Control

Class members can be public, private, or protected. Child class inherits everything but can only access

public and protected members.

/* C++ */class Stack {protected:

int top;int size;int *stack;

public:void push(int x);bool isEmpty( ) {

return top <= 0;}

};

/* C# */public class Stack {protected int top;protected int size;protected int *stack;public void push(int x) { ... }public bool isEmpty( ) {

return top <= 0;}

Page 27: Object Orientation

27

Access Control in C++

"Friend" classes can access protected and private members.

Child class can reduce visibility of inherited parts.

class CircularStack : private Stack {...friend class StackManager;friend int max( const Stack& );

};

Page 28: Object Orientation

28

Multiple inheritance in C++

Multiple inheritance allows subclasses to "mix in" the properties of several parent classes.

class iostream: public istream, public ostream {

public: iostream( streambuf* ); virtual ~iostream();

protected: iostream( );

}

istream ostream

iostream

Page 29: Object Orientation

29

Multiple inheritance in C++ If a subclass has multiple paths to a superclass, it may inherit more than one copy of superclass properties! This is called repeated inheritance. This can cause unwanted,

inconsistent behavior.

A

B C

D

A

class A { protected string name; ...};class B : public A {...};class C : public A {...};class D : public B, public C {...};...D dog(); // dog has 2 copies of A::namedog.setName("woof"); // set which name?

Page 30: Object Orientation

30

Shared inheritance in C++

Shared inheritance: instances of a derived class that have multiple access routes to superclass share the same instance of a superclass object:

A

B C

D

class A { protected string name; ...};class B : virtual public A {...};class C : virtual public A {...};class D : public B, public C {...};...D dog( ); // dog has only one A::name member

Page 31: Object Orientation

31

Polymorphism

Polymorphism enables flexible, extensible applications.

JButton button = new JButton(...);JTextField text = new JTextField(...);JSlider slider = new JSlider(...);container.add( button );container.add( text );container.add( slider );

Container

-components: Collection

+add( JComponent)

+paint(Graphics g)

JComponent

paint(Graphics g)setsize( Dimension )setPosition(Dimension)...

JButton

JSlider

JTextField

1 *

JPanel

Page 32: Object Orientation

32

Polymorphism (2)

Container can send same message to any JComponent.

/* tell all components to paint themselves */for( JComponent comp : components )

comp.paint( Graphics g );

Container

-components: Collection

+add( JComponent)

+paint(Graphics g)

JComponent

paint(Graphics g)setsize( Dimension )setPosition(Dimension)...

1 *

JavaVM will call the paint(Graphics) method of each object, not the paint method of the superclass (JComponent).

Page 33: Object Orientation

33

Liskov Substitution Principle

If a program uses an object from class A, then

the program should still work correctly if you

substitute an object from any subclass of A.

For this to work, the behavior of each public method in a class needs to be clearly defined.

This means documentation.

Java and C# include documentation right in the code.

Page 34: Object Orientation

34

Polymorphism in Java

class Person {protected String name;...public String toString( ){ return name; }

}class Student extends Person {

private String studentID;...public String toString( ) { return studentID; }

}

In Java, instance methods use dynamic binding so polymorphism is automatic.

Person p = new Student("Bill Gates", "11111111");System.out.println( "Welcome to KU " + p.toString() );

Page 35: Object Orientation

35

Static Binding in Java

class Person {private static int nextID;

public Person( ) { ... }final void setName( String newname ) { ... }private void initialize( ) { ... }public static getNextID( ) { return nextID; }

}

Static binding used for things that are never overridden: static and final methods private methods constructors.

Page 36: Object Orientation

36

Polymorphism in C++

class Person {protected: string name;public:

Person(string aname) : { name = aname; }string toString( ) { return name; }

}class Student : Person { /* Student extends Person */

protected: string id;public:

Student(string name, string id) : Person(name),id(id) { }

string toString( ) { return id; }}

All methods are statically bound unless virtual.

Student bill("Bill Gates", "11111111");Person &p = bill; cout << Welcome to KU " << p.toString() << endl;

Page 37: Object Orientation

37

Polymorphism in C++ virtual methods are dynamically bound. virtual can applied to classes, methods, and abstract methods.

class Person {protected: string name;public:

Person(string aname) : name(aname) { }virtual string toString( ) { return name; }

}

class Student : Person { /* Student extends Person */protected: string id;public:

Student(string name, string id) : Person(name),id(id) { }

string toString( ) { return id; }}

Page 38: Object Orientation

38

Polymorphism in C#

Static binding (default)

Use "new" to override.

class Person {public string who( ){ ... }

}class Student : Person {

new public string who(){ ... }

}

Dynamic binding: use virtual and override.

class Person {public virtual string

who( ){ ... }

}class Student : Person {

public override string who( )

{ ... }}

Person p = new Student("Bill Gates", "11111111");p.who( );

Example:

Page 39: Object Orientation

39

Why static binding?

Polymorphism is key to writing extensible, reusable O-O programs.

So, why don't C# and C++ always use dynamic binding?

don't require us to request it using "virtual"

Why does Java have "final" methods? eliminates future opportunity for overriding

Page 40: Object Orientation

40

Polymorphism and Run-time Binding

A key to polymorphism is that names are bound to methods dynamically.

How does the run-time environment know which method should be used?

public class Circle extends JComponent {void paint(Graphics g) { /* draw circle */ }...

}public class Square extends JComponent {

void paint(Graphics g) { /* draw square */ } ...

}public redraw( Graphics g ) {

JComponent [ ] parts = { new Square(), ... };parts[k].paint(g); // determined at run-time

Page 41: Object Orientation

41

Memory for Object Data Members

class Person {String name;Date birthday;char sex;... // methods String getName() ...

}

void test( ) {Person you =

new Person(...);you.name = "Mr. Java";you.getName( );}

you VMT ptr

name

birthday

'M'

memory

Virtual Method Table for Person

a String object

a Date object

Page 42: Object Orientation

42

Memory for Object Data Members

you VMT ptr

name

birthday

'M'

memory for Person

Virtual Method Table for Person

a String object

a Date object

The compiler uses known offsets from the start of object for each data member. For example:

you.name is (you)+4

you.sex is (you)+12

The VMT is for accessing methods (later).

Page 43: Object Orientation

43

Memory Layout with Inheritance

class Person {String name;Date birthday;private char sex;// methodsString toString( )...

}class Student

extends Person {String studentID;Course [] courses;void addCourse(...)

}s = new Student(...);

s VMT ptr

name

birthday

sex

memory for StudentVMT for Student

String

Date

studentID

courses

String

Array

Person

Page 44: Object Orientation

44

Virtual Method Table for Object

A Virtual Method Table is a table of addresses of the methods of a class. For the Object class...

clone

equals

finalize

getClass

...

toString

address of Object clone method

address of Object equals method

address of Object finalize methodMethods from Object's VMT

The compiler knows which method it wants based on signature. It can specify as offset in runtime VMT.

Page 45: Object Orientation

45

Virtual Method Table for Person A subclass can add methods or replace methods in its VMT. Only 1 VMT for each class (all objects share it).

clone

equals

finalize

getClass

...

toString

getName

setName

address of Object clone method

address of Person equals method

address of Object finalize method

Methods from Object's VMT

(maybe changed by Person class)

Methods added by Person class

address of Person toString method

Page 46: Object Orientation

46

Object Reference and Inheritance The information about an object is available through the object reference.

Person p = new Person(...);

p VMT ptr

name

birthday

sex

String

DatePerson

clone

equals

finalize

getClass

...

toString

getName

setName

memory for Person object VMT for Person class

Page 47: Object Orientation

47

Object Reference and Inheritance A subclass can override fields/methods or add new fields and methods.

Student s = new Student(...);

s VMT ptr

name

birthday

sex

String

Date

studentID

courses

String

Array

Person

clone

equals

finalize

getClass

...

toString

getName

setName

getCourse

addCourse

addedattributes

addedmethods

memory for Student object VMT for Student class

Page 48: Object Orientation

48

Object Reference and Inheritance If we assign an object to reference of superclass type, the extra information is still there, but

not used by superclass reference.

Person p2 = new Student();

p2 VMT ptr

name

birthday

sex

String

Date

studentID

courses

clone

equals

finalize

getClass

...

toString

getName

setName

getCourse

addCourse((Student)p2).getCourse();

Page 49: Object Orientation

49

Interfaces Separate the specification of behavior from the implementation

of the behavior. Interfaces can often replace multiple inheritance. Interfaces can extend other interfaces in Java and C#

Example: IComparable specifies "CompareTo" behavior.

/** C# IComparable interface **/namespace System {

public interface IComparable {int CompareTo( object other ) ;

}}

method signature onlymethods are automatically "public"

Page 50: Object Orientation

50

Interface Example

/** Person class implements IComparable **/using namespace System;public class Person : IComparable {

private string lastName;private string firstName;...int CompareTo( object other ) {

if ( other is Person ) {Person p = (Person) other;return lastName.CompareTo( p.lastName );

}else throw new ArgumentException(

"CompareTo argument is not a Person");}

}}

Why implement interface?

What is the benefit?

Page 51: Object Orientation

51

/* System.Array provides utilities for arrays */public class Student : Person { ... }public class Registrar {

...Student [ ] iup = new Student[100];Array.Sort( iup );Array.BinarySearch( iup, new Student("Shinawat") );Array.Reverse( iup );

Array+Sort( IComparable[ ] )+Reverse( IComparable[ ] )+BinarySearch( Array, Obj)

IComparable

+CompareTo( object ): int

Person

Student

*

Page 52: Object Orientation

52

Strategy Design Pattern

Context: A class requires a (complex) behavior, but there are many alternatives that can be used.

Solution: implement the behavior in a separate class, called the Strategist.

Create a Strategy interface to de-couple the context class from the Strategist.

Context

- strategy: Strategist

+setStrategy( Strategist )

Strategist

+doSomething( )...

ConcreteStrategy

+doSomething( )...

AnotherStrategy

+doSomething( )...

What are some examples of this?

Page 53: Object Orientation

53

Observer Design Pattern

Context: An object (the Subject) is the source of interesting events. Other objects (Observers) want to know when an event occurs.

Solution: (1) Subject provides a method for Observers to register themselves as interested in the event.

(2) Subject calls a known method (notify) of each Observer when event occurs.

Subject

- observers: Collection

+addObserver( Observer )

+removeObserver( ... )

Observer

+notify( event: Object )...

ConcreteObserver

+notify( event )...

AnotherStrategy

+notify( event )...

What are some examples of this?

Page 54: Object Orientation

54

Observer Pattern in Java

The hard part is writing the Subject class methods to manage and notify observers. Java does this for you: java.util.Observable

YourApplication

-event( )

...

Observer

+update( Observable, Object )

YourFriendsObserver

+notify( event )...

Observable

- observers: Collection+addObserver( Observer )+deleteObserver( ... )+notifyObservers( Object )

addObserver(this)

event( ) {setChanged( );notifyObservers(obj);

}

Page 55: Object Orientation

55

C# Delegates

Delegate is a type in the C# type system. It provides a way to pass a function name as argument. Can act as a collection for observers.

/** define a delegate that accepts string **/public delegate void TellMe( string msg );

/** create some delegates **/TellMe observers = new TellMe( out.WriteLine );observers += new TellMe( button.setText );observers += new TellMe( textarea.append );/** call all the observers at once! **/observers("Wake Up!");

Page 56: Object Orientation

56

Garbage Collection

C++ does not require automatic garbage collection. programmer must explicitly free memory that he

allocated with "new" use destructor to free resources inside of objects memory leaks are a problem

C# and Java have automatic garbage collection reduces need for destructor (Java: finalize) gc impacts performance... for better or worse

Page 57: Object Orientation

57

Operator Overloading

C++ lets you redefine operators for new types.

Example: Suppose you have a complex class for storing complex numbers.

We'd like to be able to operate on and compare complex objects just like double, float, ...

complex z1(2,1); // z1 is 2+1i

complex z2(1,4); // z2 is 1+4i

complex z3 = z1 + z2;

cout << "z3 = " << z3; // prints z3 = 3+5i

if ( z3 == 0 ) cout << "zero".

Page 58: Object Orientation

58

Operator Overloading

In C++ you can refer to any infix, prefix, or postfix operator as operatorop.

z1 + z2 is the same as:

z1.operator+(z2) // operator+ is a method

operator+(z1,z2) // operator+ is a function

In the first case, operator+(complex) is a member of the complex class, so it can access the private attributes.

In the second case, operator+ is not part of the class.

But you can declare it a "friend" function to give it access to private attributes.

Page 59: Object Orientation

59

Overload as Method or Function?

If you declare operator+(Complex z2) inside the class then its a method.

If you declare operator+(Complex z1, Complex z2) outside the class, then you're declaring a function.

Which way is better? in this case we'd like to able to write z+1.0 or 1.0+z when z is a complex number. "1.0+z" won't work as a method since 1.0 is a double, not a Complex object. So implementing as a function allows symmetric behavior. the advantage of implementing as a method is that the method has access to private attributes of the class.

z1.operator+(z2); // operator+ is a methodoperator+(z1,z2); // operator+ is a function

Page 60: Object Orientation

60

Operator Overloading Example (1)

class complex {private:

double real, imag; // real and imaginary partspublic:

complex(double re=0, double im=0) {real = re; imag = im;

}// define "+" as a methodcomplex operator+(const complex& z) {

return complex(real+z.real, imag+z.imag);}// define "==" as a methodbool operator==(const complex& z) {

return (real==z.real && imag==z.imag);}

Page 61: Object Orientation

61

Operator Overloading Example (2)

class complex {private:

double real, imag; // real and imaginary partspublic:

complex(double re=0, double im=0) {real = re; imag = im;

}// define "+" as a friend functionfriend complex operator+(const complex&,

const complex&);

For operations that (1) don't modify their arguments, or (2) the first argument may not be of the class type, it is simpler to define as an ordinary function (not part of class).

Page 62: Object Orientation

62

Operator Overloading Example (3)

// definition of "+" is outside of class:complex operator+(const complex& u,

const complex& v) {return complex(u.real+v.real, u.imag+v.imag);

}

Notice that in this case, both arguments to "+" are parameters to the function.

C++ will invoke this function for complex+complex, complex+double, and double+complex ... after converting double to complex.

Page 63: Object Orientation

63

C# Type System In C#, all data types are either objects or structs. int, double, bool, etc., are implemented as struct. struct are value data types. struct "inherit" from System.ValueType struct are compatible with Object root class

Object reference data typeheap dynamicgarbage collected inheritance and interfacesallocate with "new"polymorphic (maybe)

Structvalue data typeany memory areastack management applies interface, no subclassesallocated by variable declaratonnot polymorphic; op. overload

Page 64: Object Orientation

64

Fraction Struct

struct Fraction {long num; // numerator and denominatorlong denom; // could be "private" if we wantpublic Fraction(int num, int denom) {

this.num = num; this.denom = denom; // ToDo: gcd}public Fraction(int num) { this.num = num; denom = 1; }public static operator+(Fraction f1, Fraction f2) {

return new Fraction(f1.num*f2.denom+f1.denom*f2.num, f1.denom*f2.denom);

}// output Fractionpublic override string ToString( ) {

if (denom==0 && num==0) return "NaN";... // other cases go herereturn num.ToString() + "/" + denom.ToString();

}

Page 65: Object Orientation

65

Struct is value type, Object is reference

class FractionTest {void Test( ) {Fraction a = new Fraction(1,2);Fraction b = a;a.num = 7;Console.WriteLine("b={0}", b);

}

struct Fraction {int num, denom;... define struct

}

class Fraction {public int num, denom;... define class

}

What is the output in each case? struct Fraction class Fraction

Page 66: Object Orientation

66

How does a method get a value for "this"?