object oriented programming, interfaces, callbacks delegates and events dr. mike spann...

43
Object Oriented Programming Interfaces , , Callbacks Delegates and Events Dr. Mike Spann Dr. Mike Spann [email protected] [email protected]

Upload: verity-griffin

Post on 11-Jan-2016

226 views

Category:

Documents


2 download

TRANSCRIPT

Page 1: Object Oriented Programming, Interfaces, Callbacks Delegates and Events Dr. Mike Spann m.spann@bham.ac.uk

Object Oriented Programming

Interfaces, , Callbacks Delegates and Events

Dr. Mike SpannDr. Mike Spann

[email protected]@bham.ac.uk

Page 2: Object Oriented Programming, Interfaces, Callbacks Delegates and Events Dr. Mike Spann m.spann@bham.ac.uk

Contents

Introduction to interfacesIntroduction to interfaces Example – An Example – An IMeasureableIMeasureable interface interface Callback functionsCallback functions DelegatesDelegates Events and event handlersEvents and event handlers SummarySummary

Page 3: Object Oriented Programming, Interfaces, Callbacks Delegates and Events Dr. Mike Spann m.spann@bham.ac.uk

Introduction to interfaces We have already seen how an abstract base class links We have already seen how an abstract base class links

related related derived class through inheritance derived class through inheritance

The overridden virtual methods of the abstract base The overridden virtual methods of the abstract base class must be implemented in the derived classesclass must be implemented in the derived classes

There are also occasions when we want There are also occasions when we want unrelatedunrelated classes to exhibit similar behaviourclasses to exhibit similar behaviour

For example we may want to be able to implement For example we may want to be able to implement a sorting algorithm on unrelated classesa sorting algorithm on unrelated classes

Page 4: Object Oriented Programming, Interfaces, Callbacks Delegates and Events Dr. Mike Spann m.spann@bham.ac.uk

Introduction to interfaces

For example, we may want to sort objects of class Square on the basis of the length of their side

We could easily do this through We could easily do this through polymorphism by implementing an abstract polymorphism by implementing an abstract base class base class SortableSortable and using similar and using similar generic programming techniques we looked generic programming techniques we looked at in the last lectureat in the last lecture But, C# (along with Java) doesn’t But, C# (along with Java) doesn’t

support multiple inheritancesupport multiple inheritance

Page 5: Object Oriented Programming, Interfaces, Callbacks Delegates and Events Dr. Mike Spann m.spann@bham.ac.uk

Introduction to interfaces

Shape

Square

Sortable

Page 6: Object Oriented Programming, Interfaces, Callbacks Delegates and Events Dr. Mike Spann m.spann@bham.ac.uk

Introduction to interfaces

An interface is simply a list of public methods that any class which implements that interface must provide implementations of

Unrelated classes can implement a single interface In our example, we can define a ISortable

interface such that objects of any class which implements this interface can be sorted on the basis of some comparative measure

Our Square class can implement the ISortable interface using the length of side as the comparative measure

Page 7: Object Oriented Programming, Interfaces, Callbacks Delegates and Events Dr. Mike Spann m.spann@bham.ac.uk

Introduction to interfaces

public interface ISortable{ int compareTo(ISortable s);}

Our ISortable interface contains a single public method compareTo() which defines how the comparison is made This method is overridden in classes which

implement this interface

Page 8: Object Oriented Programming, Interfaces, Callbacks Delegates and Events Dr. Mike Spann m.spann@bham.ac.uk

Introduction to interfaces

compareTo(ISortable b) returns –1,0 or 1 depending on whether some chosen instance field f of a ISortable object is such that : this.f<b.f this.f==b.f this.f>b.f

We can implement this method in class Square to sort on the basis of length of side

Page 9: Object Oriented Programming, Interfaces, Callbacks Delegates and Events Dr. Mike Spann m.spann@bham.ac.uk

Introduction to interfacespublic class Square : Shape, ISortable{ private int side;

public Square(int s) { side = s; }

public override void draw() { }

public override double area() { return side * side; }

public int compareTo(ISortable s) { Square sq=(Square)s;

if (side<sq.side) return -(1); if (side > sq.side) return 1;

return 0; }}

Page 10: Object Oriented Programming, Interfaces, Callbacks Delegates and Events Dr. Mike Spann m.spann@bham.ac.uk

Introduction to interfaces

We can provide a ShellSort() method which implements the shell sort algorithm on arrays on ISortable objectsThe compareTo() method of the objects

implementing the interface is called inside ShellSort()

Page 11: Object Oriented Programming, Interfaces, Callbacks Delegates and Events Dr. Mike Spann m.spann@bham.ac.uk

Introduction to interfacespublic class ArrayAlg{ public static void shellSort(ISortable[] a) { int n = a.Length; int incr = n / 2; while (incr >= 1) { for (int i = incr; i < n; i++) { ISortable temp = a[i]; int j = i; while (j >= incr && temp.compareTo(a[j - incr]) < 0) { a[j] = a[j - incr]; j -= incr; } a[j] = temp; } incr /= 2; } }}

Page 12: Object Oriented Programming, Interfaces, Callbacks Delegates and Events Dr. Mike Spann m.spann@bham.ac.uk

Introduction to interfaces

To test our program we simply create an array of Square objects and pass it into the ShellSort() methodBecause of the cast in the compareTo()

method in Square, the correctly implemented compareTo() method is called through polymorphism

Page 13: Object Oriented Programming, Interfaces, Callbacks Delegates and Events Dr. Mike Spann m.spann@bham.ac.uk

Introduction to interfaces

public class SortablesTest{ static void Main(string[] args) { Square[] s = new Square[3]; s[0] = new Square(3); s[0] = new Square(2); s[0] = new Square(1);

ArrayAlg.shellSort(s);// Sorts on length of side }}

Page 14: Object Oriented Programming, Interfaces, Callbacks Delegates and Events Dr. Mike Spann m.spann@bham.ac.uk

An An IMeasureableIMeasureable interface interface

Suppose we have a DataSet class which computes simple statistics of numbers read from an input streamFor example, the average and maximum

DataSetaverage

maximum

Input stream

Page 15: Object Oriented Programming, Interfaces, Callbacks Delegates and Events Dr. Mike Spann m.spann@bham.ac.uk

public class DataSet{ public DataSet() { sum = 0.0; maximum = 0.0; count = 0; }

public void add(double x) { sum += x; if (count == 0 || maximum < x) maximum = x; count++; }

public double getAverage() { if (count == 0) return 0; else return sum / count; }

public double getMaximum() { return maximum; }

private double sum, maximum; private int count;}

Page 16: Object Oriented Programming, Interfaces, Callbacks Delegates and Events Dr. Mike Spann m.spann@bham.ac.uk

An An IMeasureableIMeasureable interface interface

Clearly we would have to modify the DataSet class if we wanted to get the average of a set of bank account balances or to find the coin with the highest value amongst a set DataSet is not re-useable as it stands However, if all classes that DataSet objects

operate on implement an IMeasurable interface, then the class becomes more flexible

Page 17: Object Oriented Programming, Interfaces, Callbacks Delegates and Events Dr. Mike Spann m.spann@bham.ac.uk

An An IMeasureableIMeasureable interface interface

Thus getMeasure() for BankAccount objects return the balance and for Coin objects returns the coin value

public interface IMeasureable{

double getMeasure(); }

Page 18: Object Oriented Programming, Interfaces, Callbacks Delegates and Events Dr. Mike Spann m.spann@bham.ac.uk

An An IMeasureableIMeasureable interface interface

public class BankAccount: IMeasureable{

private double balance;private int accountNumber;

.

.double getMeasure() { return balance;}

}

public class Coin: IMeasurable{ private double value;

.

.double getMeasure() { return value;}

}

Page 19: Object Oriented Programming, Interfaces, Callbacks Delegates and Events Dr. Mike Spann m.spann@bham.ac.uk

An An IMeasureableIMeasureable interface interface

The IMeasurable interface expresses the commonality amongst objectsThe fact that each measurable objects can

return a value relating to its size DataSet objects can then be used to analyse

collections of objects of any class implementing this interface with minor modifications to the code

Page 20: Object Oriented Programming, Interfaces, Callbacks Delegates and Events Dr. Mike Spann m.spann@bham.ac.uk

public class DataSet{ public DataSet() { sum = 0.0; count = 0; } public void add(IMeasureable x) { sum += x.getMeasure(); if (count == 0 || maximum.getMeasure() < x.getMeasure()) maximum = x; count++; }

public double getAverage() { if (count == 0) return 0; else return sum / count; }

public double getMaximum() { return maximum.getMeasure(); }

private IMeasureable maximum; private double sum; private int count;

}

Page 21: Object Oriented Programming, Interfaces, Callbacks Delegates and Events Dr. Mike Spann m.spann@bham.ac.uk

An An IMeasureableIMeasureable interface interface

class MeasureablesTest{ static void Main(string[] args) { DataSet d=new DataSet(); Coin c1=new Coin(10); Coin c2=new Coin(20); d.add(c1); d.add(c2); double maxCoin=d.getMaximum(); System.Console.WriteLine("coin max= " + maxCoin); }}

Page 22: Object Oriented Programming, Interfaces, Callbacks Delegates and Events Dr. Mike Spann m.spann@bham.ac.uk

Callback functionsCallback functions

The DataSet class is useful as a re-usable class but is still limited The IMeasurable interface can only be

implemented by user defined classes We can’t, for example, find the maximum of a

set of Rectangle objects as Rectangle is a pre-defined class

We can only measure an object in one way. For example, in the case of BankAccount objects, we can only measure it in terms of the balance

Page 23: Object Oriented Programming, Interfaces, Callbacks Delegates and Events Dr. Mike Spann m.spann@bham.ac.uk

Callback functionsCallback functions

The solution is to delegate the measuring to a separate class rather than being the responsibility of the objects we are measuring We can create a separate IMeasurer interface

and implement a measure() method in objects implementing this interface

public interface IMeasurer{

double measure(Object anObject);

}

Page 24: Object Oriented Programming, Interfaces, Callbacks Delegates and Events Dr. Mike Spann m.spann@bham.ac.uk

public class DataSetpublic class DataSet{{

public DataSet(IMeasurer m)public DataSet(IMeasurer m){{

measurer=m;measurer=m;}}

public void add(Object x)public void add(Object x){{

sum=sum+measurer.measure(x);sum=sum+measurer.measure(x);if (count==0 || if (count==0 || mamaximum<measurer.measure(x))ximum<measurer.measure(x))

maximum=measurer.measure(x);maximum=measurer.measure(x);count++;count++;

}}

public double getMaximum()public double getMaximum() {{ return maximum;return maximum; }}

private private IIMeasurer measurer;Measurer measurer; private double sum;private double sum; private int count;private int count; private double maximum;private double maximum;}}

Callback functionsCallback functions

Page 25: Object Oriented Programming, Interfaces, Callbacks Delegates and Events Dr. Mike Spann m.spann@bham.ac.uk

Callback functionsCallback functions

A DataSet object makes a callback to the measure() method of an object implementing the IMeasurer interface when it needs to measure an object (such as checking a bank balance) This is in contrast to calling the getMeasure()

method of an object implementing the IMeasurable interface

We are now free to design any kind of measures on an object of any class For example, we can measure Square objects

by area We require a SquareMeasurer class which

implements the IMeasurer interface

Page 26: Object Oriented Programming, Interfaces, Callbacks Delegates and Events Dr. Mike Spann m.spann@bham.ac.uk

Callback functionsCallback functions

public class Square : Shape{ private int side;

public Square(int s) { side = s; }

public override void draw() { }

public override double area() { return side * side; }

}

public class SquareMeasurer : IMeasurer{

public double measure(Object anObject){

Square sq=(Square) anObject; return sq.area();

}}

Page 27: Object Oriented Programming, Interfaces, Callbacks Delegates and Events Dr. Mike Spann m.spann@bham.ac.uk

Callback functionsCallback functions

class MeasurersTest{ static void Main(string[] args) { IMeasurer m = new SquareMeasurer(); DataSet data = new DataSet(m);

// Add squares to the data set data.add(new Square(5)); // Callback to m.measure() data.add(new Square (30)); // Callback to m.measure()

// Get maximum double max = data.getMaximum(); }}

Page 28: Object Oriented Programming, Interfaces, Callbacks Delegates and Events Dr. Mike Spann m.spann@bham.ac.uk

Callback functionsCallback functions

Adding square objects to data enforces callbacks to the measure() method of the SquareMeasurer object to be made

We have flexibility over our implementation of SquareMeasurer so that any feature of Square objects can be measured Or even defining several measurer classes to measure

different features Callbacks are used extensively in building graphical user

interfaces A callback function is added to an event object which is

called when the event is triggered A managed way of doing this is to encapsulate the

callback function into a delegate object

Page 29: Object Oriented Programming, Interfaces, Callbacks Delegates and Events Dr. Mike Spann m.spann@bham.ac.uk

Delegates

A delegate object holds a reference to a method with a pre-defined signature A signature is simply the argument list and

return type of the method The keyword delegate specifies that we are

defining a delegate object For example we can define a delegate object

myDelegate which holds a method which returns void and takes an int and a double as arguments

public delegate void myDelegate(int arg1, double arg2)

Page 30: Object Oriented Programming, Interfaces, Callbacks Delegates and Events Dr. Mike Spann m.spann@bham.ac.uk

Delegates A delegate object is initialized with a

(callback) method The method signature must match the

delegate signature

public delegate void myDelegate(int arg1, double arg2);

public class App{

public static void Main(){

myDelegate call = new myDelegate(aMethod);

// We can now treat call as a simple object and pass // it around as such

}

static void aMethod(int k, double x) {}}

Page 31: Object Oriented Programming, Interfaces, Callbacks Delegates and Events Dr. Mike Spann m.spann@bham.ac.uk

Delegates

Delegate objects can be initialized with several method calls using the += operator The method calls can then be invoked in a chain by

passing the correct arguments to the delegate object Essentially it amounts to calling methods through a

proxy object and is a powerful mechanism for event handling as we shall see

Passing method calls into objects is then equivalent to passing delegate objects

Page 32: Object Oriented Programming, Interfaces, Callbacks Delegates and Events Dr. Mike Spann m.spann@bham.ac.uk

Delegates

myDelegate(int,double)

call

aMethod()

anotherMethod()

Invoked bycall(1,2.0)

aMethod(1,2.0)

anotherMethod(1,2.0)

Page 33: Object Oriented Programming, Interfaces, Callbacks Delegates and Events Dr. Mike Spann m.spann@bham.ac.uk

Delegates

public delegate void myDelegate(int arg1, double arg2);

public class App{

public static void Main(){

myDelegate call = new myDelegate(aMethod); call += new myDelegate(anotherMethod); call(1, 2.0);

}

static void aMethod(int k, double x) { System.Console.WriteLine("aMethod " + k + " " + x); }

static void anotherMethod(int k, double x) { System.Console.WriteLine("anotherMethod " + k + " " + x); }}

Page 34: Object Oriented Programming, Interfaces, Callbacks Delegates and Events Dr. Mike Spann m.spann@bham.ac.uk

Delegates

Page 35: Object Oriented Programming, Interfaces, Callbacks Delegates and Events Dr. Mike Spann m.spann@bham.ac.uk

Events and event handlers C# has built in support for event handling Event handling is usually used in GUI’s such

as to notify an application when a mouse click or button press has occurred

But any type (not just graphical types) can use events to allow notification of any kind

A type must register its interest in handling a specific event with an event handler with a pre-defined signatureThis is achieved using a delegate object

Page 36: Object Oriented Programming, Interfaces, Callbacks Delegates and Events Dr. Mike Spann m.spann@bham.ac.uk

Events and event handlers

A type can define an event and a corresponding event handler which is a delegate object

public class MyType{

public delegate void EventHandler(int arg1, int arg2);

public event EventHandler myEvent; // defines myEvent // and corresponding // event handler

.}

Page 37: Object Oriented Programming, Interfaces, Callbacks Delegates and Events Dr. Mike Spann m.spann@bham.ac.uk

Events and event handlers

An application can then register its interest in an event by adding an initialized delegate object to the event using the += operator

public class App{

public static void Main(){

MyType m = new MyType();m.myEvent += new MyType.EventHandler(myHandler);

}

public static void myHandler(int i1, int i2) {

// Event handler code }

}

Page 38: Object Oriented Programming, Interfaces, Callbacks Delegates and Events Dr. Mike Spann m.spann@bham.ac.uk

Events and event handlers

Equivalent code is very common in GUI development where applications register their own event handlers to respond to events generated by graphical components such as button clicks Normally such code is automatically generated

if we are using visual programming techniques (‘drag and drop’)

However, it is still important to understand how it all works

Page 39: Object Oriented Programming, Interfaces, Callbacks Delegates and Events Dr. Mike Spann m.spann@bham.ac.uk

Events and event handlers

For example the following code snippet registers a graphical applications event handler to respond to button clicks

public class MyGraphicalApp{

Button button = new Button();button.Click += new EventHandler(HandleButtonClick);

public void HandleButtonClick(Object sender EventArgs e) {

// Event handler code }

}

public class Button{

public delegate void EventHandler(.....);

public event EventHandler Click;..

}

Page 40: Object Oriented Programming, Interfaces, Callbacks Delegates and Events Dr. Mike Spann m.spann@bham.ac.uk

Events and event handlers

For example, we can generate our own SafeArray class which fires an event on trying to access it beyond its bounds

We pass the array index into the event handler In our simple application, the event handler

simply prints out an error message In an embedded system application, the array

could be re-allocated to be a larger size in the event handler

Page 41: Object Oriented Programming, Interfaces, Callbacks Delegates and Events Dr. Mike Spann m.spann@bham.ac.uk

Events and event handlerspublic class SafeArray{ public delegate void OutOfBoundsEventHandler(int arg1); public event OutOfBoundsEventHandler myOutOfBoundsEvent; private int[] data; private int numberOfElements=0;

public SafeArray(int n) { numberOfElements = n; data = new int[numberOfElements]; }

public int access(int elem) { if (elem < numberOfElements) return data[elem]; else myOutOfBoundsEvent(elem); // Fire an event

return 0; }}

Page 42: Object Oriented Programming, Interfaces, Callbacks Delegates and Events Dr. Mike Spann m.spann@bham.ac.uk

Events and event handlers

public class App{

public static void Main(){

SafeArray s = new SafeArray(10);

s.myOutOfBoundsEvent += new SafeArray.OutOfBoundsEventHandler(myHandler);

s.access(7);

s.access(11); // Out of bounds event generated!

}

public static void myHandler(int i1) {

System.Console.WriteLine("Index " + i1 + " out of bounds "); }}

Page 43: Object Oriented Programming, Interfaces, Callbacks Delegates and Events Dr. Mike Spann m.spann@bham.ac.uk

Summary

We have seen how objects of unrelated classes can exhibit similar behaviour by implementing an interface

Interfaces support generic programming and avoid multiple inheritance

We looked at a detailed example involving a IMeasurable interface We also introduced callbacks by having a separate measurer

object implementing an IMeasurer interface A callback function was made to a measure() method which

returned some measure on the object passed to it We have seen how delegates are objects which encapsulate

method calls These method calls can be chained using the += operator

We have seen how we can create types which can generate events and how applications can register their interest in events by initializing a delegate object with their own event handler