programming ii. inheritance interfaces exceptions generics event handling recursion szabó zsolt,...

84
Programming II. Inheritance Interfaces Exceptions Generics Event handling Recursion Szabó Zsolt, Óbudai Egyetem, 2011 [email protected]

Upload: russell-sparks

Post on 29-Dec-2015

219 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Programming II. Inheritance Interfaces Exceptions Generics Event handling Recursion Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu

Programming II.

InheritanceInterfacesExceptionsGenericsEvent handlingRecursion

Szabó Zsolt, Óbudai Egyetem, 2011 [email protected]

Page 2: Programming II. Inheritance Interfaces Exceptions Generics Event handling Recursion Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu

Programming II.

InheritanceInterfacesExceptionsGenericsEvent handlingRecursion

Szabó Zsolt, Óbudai Egyetem, 2011 [email protected]

Page 3: Programming II. Inheritance Interfaces Exceptions Generics Event handling Recursion Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu

V 1.0

Topics of the practice• Inheritance syntax• OO principles: encapsulation, data hiding• Type polymorphism• Method polymorphism• Virtual and non-virtual methods• Abstract classes and methods

3Szabó Zsolt, Óbudai Egyetem, 2011 [email protected]

Page 4: Programming II. Inheritance Interfaces Exceptions Generics Event handling Recursion Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu

V 1.0

• Base classes can be specified using the character „:” (only single inheritance in c#)

• This way we can extend the base class with new fields/methods

4

Inheritance in C#

class Animal{ int age; public Animal( ) { ... } public void Eat( ) { ... }}

class Mammal : Animal{ public Mammal GiveBirth( ) { ... }}

class Cat : Mammal{ string name; public void Hiss( ) { ... }}

Age : int

Animal()Eat()

Animal

GiveBirth() : Mammal

Mammal

Name : String

Hiss()

Cat

Szabó Zsolt, Óbudai Egyetem, 2011 [email protected]

Page 5: Programming II. Inheritance Interfaces Exceptions Generics Event handling Recursion Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu

V 1.0

• Constructrors are not inherited– We can (should) call the base class’ constructor using the „base” keyword

(the proper constructor will be called according to the given parameters)• Connecting the constructors

– By default, the parameter-less constructor of the base is called– If it is not present, then we have to manually connect one of the base

constructors with the subclass’ constructor

5

Inheritance of constructors

class A{ public A( ) { ... }}

class B : A{ public B( ) { ... }}

class C : A { public C(int x) { ... }}

class E : C{ public E(int y) : base (y) { ... }}

class F : C{ public F( ) : base (5) { ... }}

Szabó Zsolt, Óbudai Egyetem, 2011 [email protected]

Page 6: Programming II. Inheritance Interfaces Exceptions Generics Event handling Recursion Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu

V 1.0

• Non-virtual methods– Early binding– In C#, this is the default (nonexistant in Java)

• Virtual methods– Late binding– Special syntax

• In the first class where they appear, they must be marked with the keyword „virtual”• In the descendant classes the same methods must be marked with the „override” keyword

(we can, but we should not hide methods)• The base method can still be accessed

6

Virtual and non-virtual methods

class A{ public virtual int Method( ) { ... }}

class B : A{ public override int Method( ) { ... }}

Szabó Zsolt, Óbudai Egyetem, 2011 [email protected]

Page 7: Programming II. Inheritance Interfaces Exceptions Generics Event handling Recursion Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu

V 1.0

• If we declare a non-virtual method with the same name– Compiler warning, unless we mark the method with the „new” keyword– The base method can still be accessed

• Hiding virtual methods– „new virtual” new virtual method chain, overcomplicated(?)– Usually method hiding is not connected to virtual methods, it can happen if

two methods happen to have the same name „by accident”

7

Hiding methods

class A{ public int MethodX( ) { ... } public virtual int MethodY( ) { ... }}

class B : A{ public new int MethodX( ) { ... } public new virtual int MethodY( ) { ... }}

Szabó Zsolt, Óbudai Egyetem, 2011 [email protected]

Page 8: Programming II. Inheritance Interfaces Exceptions Generics Event handling Recursion Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu

V 1.0

• Treat an object as it was of another type– Implicit: automatic type conversion (e.g. intfloat, no extra syntax)– Explicit: conversion using the standard (newtype) operator

• Animal x; Cat y = (Cat)x; ((Cat)x).Nyávog();• „is” operator

– Usage: „VARIABLE is TYPE” , returns with boolean– Returns with true if the given variable can be used as the given type (= same

type or derived type)• „as” operator

– Usage: „VARIABLE as TYPE”– Conversion (only usable with reference types)– No exception on failure!

8

Type conversion (type casting)

Szabó Zsolt, Óbudai Egyetem, 2011 [email protected]

Page 9: Programming II. Inheritance Interfaces Exceptions Generics Event handling Recursion Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu

V 1.0

• They must be marked with the „abstract” keyword– Usage of classes for purely inheritance purposes– A class with even one abstract method must always be abstract– We cannot create instances from abstract classes– Abstract methods must be implemented in the derived classes

9

Abstract classes / methods

abstract class Figure{ public abstract double Area( ); public abstract double Circumference( );}

class Rectangle : Figure{ int a; int b; public override double Area( ) { return a * b; } public override double Circumference( ) { return 2 * (a + b); }}

Szabó Zsolt, Óbudai Egyetem, 2011 [email protected]

Page 10: Programming II. Inheritance Interfaces Exceptions Generics Event handling Recursion Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu

V 1.0

• Must be marked with the „sealed” keyword• Sealed classes cannot be used as base class• Sealed methods cannot be overridden

10

Sealed class / method

sealed class Rectangle : Figure{ int a; int b; public override double Area( ) { return a * b; } public override double Circumference( ) { return 2 * (a + b); }}

Szabó Zsolt, Óbudai Egyetem, 2011 [email protected]

Page 11: Programming II. Inheritance Interfaces Exceptions Generics Event handling Recursion Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu

V 1.0

• The root class of the class tree, the base class for everything• If we do not specify our own base class, then System.Object will

be used as a base• Some methods:

– public Type GetType()Returns the type object

– public virtual bool Equals(object obj) Equality based on the content

– public virtual int GetHashCode()Calculates a hash based on the content

– public virtual string ToString()Converts the instance into a string

– public static bool ReferenceEquals(object objA, object objB) Equality based on the references

– public static bool Equals(object objA, object objB) Equality based on the contents

11

Object base class

Szabó Zsolt, Óbudai Egyetem, 2011 [email protected]

Page 12: Programming II. Inheritance Interfaces Exceptions Generics Event handling Recursion Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu

V 1.0

• Shape Circle, Shape Rectangle

Square• Solve the following:

– Store 50 shapes in an array– Determine the one with the

biggest area– List those with the biggest

circumference– List those where the area is

bigger than the circumference– List those where the area is

a prime number– Select the one where the

circumference number has thebiggest number of divisors

12

Inheritance example

Szabó Zsolt, Óbudai Egyetem, 2011 [email protected]

Page 13: Programming II. Inheritance Interfaces Exceptions Generics Event handling Recursion Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu

Programming II.

InheritanceInterfacesExceptionsGenericsEvent handlingRecursion

Szabó Zsolt, Óbudai Egyetem, 2011 [email protected]

Page 14: Programming II. Inheritance Interfaces Exceptions Generics Event handling Recursion Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu

V 1.0

• We must use the „interface” keyword– Interfaces can contain method/property/event declarations

• When creating a class that uses interface(s), we must use the same „:” character (extends vs implements)– Multiple interfaces can be implemented in one class– We cannot create interface instances, but it can be used as a type

14

Interfaces in C#

interface IReceiveMessages{ bool Available { get; set; } void Send(string msg);}

class ChatPartner : Person, IReceiveMessages{ public bool Available { get {...} set {…} } public void Send(string msg) { ... }}

IÜzenetFogadó x = new ChatPartner();

Available: BooleanSend(String)

<<interface>>IReceiveMessages

ChatPartner IReceiveMessages

Szabó Zsolt, Óbudai Egyetem, 2011 [email protected]

Page 15: Programming II. Inheritance Interfaces Exceptions Generics Event handling Recursion Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu

V 1.0

• Abstract class can also implement interfaces– Optionally we can implement the interface methods or mark them as

abstract methods descendants must implement those

• They can look the same, but they serve different purposes• Both can make other classes implement some methods, but

abstract classes are used in inheritance and they can contain actual methods/fields as well

15

Abstract class vs interfaces

interface ICanBeSold{ bool Price { get; set; } void Sell( );}

abstract class Product : ICanBeSold{ public abstract bool Price { get; set; } public abstract void Sell( );}

Szabó Zsolt, Óbudai Egyetem, 2011 [email protected]

Page 16: Programming II. Inheritance Interfaces Exceptions Generics Event handling Recursion Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu

V 1.0

• Similar to object inheritance (using the „:” letter)– An interface can extend multiple interfaces– A class implementing a interface must implement all methods defined by

the given interface and all other interfaces that given interface extends

16

Extending interfaces

interface ICanBeSold{ bool Price { get; set; } void Sell( );}interface ICanBeOnSale : ICanBeSold{ void ExecuteSpecialSale(double discount);}public class Product: ICanBeOnSale{ public bool Price { get; set; } public void Sell ( ) { ... } public void ExecuteSpecialSale(double discount) { ... }}

Szabó Zsolt, Óbudai Egyetem, 2011 [email protected]

Page 17: Programming II. Inheritance Interfaces Exceptions Generics Event handling Recursion Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu

V 1.0

• If more than one interface contains the same method (with the same signature), then the class can be created so that it fulfils the interface method using one actual method

• In this case it does not matter what reference we use for the object instance, that one method will be executed when called

17

Implicit interface implementation

interface IManageFiles{ string Delete( );}interface IManageDocuments{ string Delete( );}public class TextFile : IManageFiles, IManageDocuments{ public string Delete( ) { … }}

Szabó Zsolt, Óbudai Egyetem, 2011 [email protected]

Page 18: Programming II. Inheritance Interfaces Exceptions Generics Event handling Recursion Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu

V 1.0

• If we choose to implement a separate method for separate interfaces

• The executed method depends on the variable/reference type

18

Explicit interface implementation

interface IManageFiles { string Delete(); } interface IManageDocuments { string Delete(); } public class TextFile : IManageFiles, IManageDocuments { string IManageFiles.Delete() { return "FILES"; } string IManageDocuments.Delete() { return "DOCUMENTS"; } public string Delete() { return "TEXTFILE"; } } class Program { static void Main(string[] args) { TextFile a = new TextFile(); a.Delete(); (a as IManageFiles).Delete(); (a as IManageDocuments).Delete(); Console.ReadLine(); } }

Szabó Zsolt, Óbudai Egyetem, 2011 [email protected]

Page 19: Programming II. Inheritance Interfaces Exceptions Generics Event handling Recursion Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu

V 1.0

• Create a class that can store students (random name + random credit number), make a sortable array from the class instances The class must implement the IComparable interface– Generic and non-generic versions from that interface, we use

the non-generic now– int CompareTo(Object obj)

<0 – the current instance is before obj0 – the current instance and the obj are at the same spot>0 – the current instance is after obj

– Use IComparable + Array.Sort(Array)

19

Exercise #1

Szabó Zsolt, Óbudai Egyetem, 2011 [email protected]

Page 20: Programming II. Inheritance Interfaces Exceptions Generics Event handling Recursion Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu

V 1.0

• We want to create a car race• Car Name, protected Speed, protected Rnd, public Position

+ ctor + ToString

• ICanAccelerate, ICanBreakDown

• BMW : Car, ICanAccelerate (every third time)• Porsche : Car, ICanBreakDown (1:X chance)• Jaguar : Car, ICanAccelerate, ICanBreakDown (1:5 chance for both)

• Program class: Init() + Main() + IsOver()

20

Exercise #2

Szabó Zsolt, Óbudai Egyetem, 2011 [email protected]

Page 21: Programming II. Inheritance Interfaces Exceptions Generics Event handling Recursion Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu

Programming II.

InheritanceInterfacesExceptionsGenericsEvent handlingRecursion

Szabó Zsolt, Óbudai Egyetem, 2011 [email protected]

Page 22: Programming II. Inheritance Interfaces Exceptions Generics Event handling Recursion Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu

V 1.0

• Three-layer architecture (not necessarily three-tier)

• Typically– Every layer performs one distinct task, and serves data to the layer above– Even if they are deployed as a one-tier application, the logical separation is

highly advised– Easier to mange and change and scale the code– Reusable code!!!

22

Multi-layer architectures

View Controller(ViewModel, Presentation)

Model(Resource)

Szabó Zsolt, Óbudai Egyetem, 2011 [email protected]

Page 23: Programming II. Inheritance Interfaces Exceptions Generics Event handling Recursion Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu

V 1.0

Topics of the practice• Events vs Exceptions• Steps of creating exceptions• Exception hierarchy• DivideByZeroException, FormatException, OverflowException• Exception base class• NullReferenceException, IndexOutOfRangeException• ArgumentException, ArgumentNullException,

ArgumentOutOfRangeException

23Szabó Zsolt, Óbudai Egyetem, 2011 [email protected]

Page 24: Programming II. Inheritance Interfaces Exceptions Generics Event handling Recursion Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu

Programming II.

InheritanceInterfacesExceptionsGenericsEvent handlingRecursion

Szabó Zsolt, Óbudai Egyetem, 2011 [email protected]

Page 25: Programming II. Inheritance Interfaces Exceptions Generics Event handling Recursion Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu

V 1.0 25

Aim• Aim: create a set that can store people, using the least

possible person-dependent lines (e.g., ZERO)• What type should be used as a storage?

– Person – The whole thing has to be rewritten for a set of dogs

– Common ancestor for Person and Dog – not possible in many circumstances... Nothing is common...

– Object (global ancestor) – possible solution ArrayList in .NET1, typecasting forever

– Define the type as a paremeter, and define the actual type later

Szabó Zsolt, Óbudai Egyetem, 2011 [email protected]

Page 26: Programming II. Inheritance Interfaces Exceptions Generics Event handling Recursion Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu

V 1.0 26

Generics• Template classes in C++• During the definition, we specify generic type(s) that will be

defined later• During the definition, we only reference a type as simply „T”, and

this „T” type will be actually defined later, when the instance is created

• Definition:class MyGenericClass<T> { }

• Declaration and instance creation MyGenericClass<int> mgcINT = new MyGenericClass<int>();

• MyGenericClass<Person> mgcP = new MyGenericClass<Person>(); • Typical usage: built-in collections!

Szabó Zsolt, Óbudai Egyetem, 2011 [email protected]

Page 27: Programming II. Inheritance Interfaces Exceptions Generics Event handling Recursion Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu

V 1.0 27

Collections• ArrayList stores objects, typecasting is needed, deprecated

• List<T>: Add(), Insert(), Remove(), RemoveAt(), Reverse(), [],Clear(), Contains(), Count

• Queue<T>: Enqueue(), Dequeue(), Peek(),Clear(), Contains(), Count

• Stack<T>: Push(), Pop(), Peek(),Clear(), Contains(), Count

• Multiple generic type parameters: class something<T,U> { }• Dictionary<T, U>: Add(), Remove(), TryGetValue(), Keys, Values,

Clear(), ContainsKey(), ContainsValue(), CountSzabó Zsolt, Óbudai Egyetem, 2011 [email protected]

Page 28: Programming II. Inheritance Interfaces Exceptions Generics Event handling Recursion Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu

V 1.0 28

Using generic classes

Szabó Zsolt, Óbudai Egyetem, 2011 [email protected]

Page 29: Programming II. Inheritance Interfaces Exceptions Generics Event handling Recursion Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu

V 1.0 29

Initializing generic types• object reference=null; int value=0; string immutable=””;• T something = ????• No idea about the exact type, no idea about the exact way to

initialize• default expression

– Returns with null or bitwise zero

T something = default(T);

Szabó Zsolt, Óbudai Egyetem, 2011 [email protected]

Page 30: Programming II. Inheritance Interfaces Exceptions Generics Event handling Recursion Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu

V 1.0 30

Constraints / Restrictions• One thing is sure: type T descends from System.Object• Thus, only the usual methods are accessible (ToString(), ....)• We can specify constraints to enforce some rules: the developer

cannot use anything as T, only those types...

– Descendant of... (where T : Person)– Implements... (where T: IComparable)– Value type (where T: struct)– Reference type (where T: class)– With constructor (where T: new())

Szabó Zsolt, Óbudai Egyetem, 2011 [email protected]

Page 31: Programming II. Inheritance Interfaces Exceptions Generics Event handling Recursion Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu

V 1.0 31

class MyClass2<T> where T : IEnumerable<T>{ public void Iterate(T data) { foreach (object item in data) {

Console.WriteLine(item); } }}

Interface restriction: foreachclass MyClass2<T> { public void Iterate(T data) { foreach (object item in data) {

Console.WriteLine(item); } }}

Can I use foreach on type „T”?(The foreach loop can only work on a type if it implements Ienumerable, this will be detailed later)

OKSame way: we can use Interfaces / Base classes to enforce the existance of some method/property

Szabó Zsolt, Óbudai Egyetem, 2011 [email protected]

Page 32: Programming II. Inheritance Interfaces Exceptions Generics Event handling Recursion Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu

V 1.0 32

Operator restriction

class Arithmetic<T>{ public T Cubed(T number){ return number * number * number; }}

class Arithmetic<T> where T : System.Int32{ public T Cubed(T number){ return number * number * number; }}

Can we multiply „T” ?

Primitive / value types cannot be used as constraints!

When using generics, we cannot use most of the basic operators, we always have to use methods!

Szabó Zsolt, Óbudai Egyetem, 2011 [email protected]

Page 33: Programming II. Inheritance Interfaces Exceptions Generics Event handling Recursion Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu

V 1.0 33

No standard operators

class Program2{ public T Min<T>(T a, T b)

where T : IComparable<T> { if (a<b)return a; elsereturn b; }}

class Program{ public T Min<T>(T a, T b)

where T : IComparable<T> { if (a.CompareTo(b)<0)return a; elsereturn b; }…}

Szabó Zsolt, Óbudai Egyetem, 2011 [email protected]

Page 34: Programming II. Inheritance Interfaces Exceptions Generics Event handling Recursion Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu

V 1.0 34

Generic method• Independent from generic classes: generic classes can contain

non-generic methods; non-generic classes can contain generic methods

• A method is generic if it has generic type parameters

Szabó Zsolt, Óbudai Egyetem, 2011 [email protected]

Page 35: Programming II. Inheritance Interfaces Exceptions Generics Event handling Recursion Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu

V 1.0 35

Calling generic methods• Calling generic methods: the parameter types specify „T” :

int i=Min(2, 3); //integersfloat f=Min(2.0f, 3.0f); //floats

• !IMPORTANT! we can’t have two methods w the same signature• What if T=int? • When there is a conflict, always the non-generic version is called• If there are two methods with generic parameters Method(T arg),

Method(U arg), and T and U happen to be the same, then the method call will be unavailable („ambiguous call”)

Szabó Zsolt, Óbudai Egyetem, 2011 [email protected]

Page 36: Programming II. Inheritance Interfaces Exceptions Generics Event handling Recursion Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu

V 1.0 36

Static fields

class MyGenericClass<T>{ private static int counter = 0; public MyGenericClass() { counter++; } public static void Count() { Console.WriteLine(counter); }}

Szabó Zsolt, Óbudai Egyetem, 2011 [email protected]

Page 37: Programming II. Inheritance Interfaces Exceptions Generics Event handling Recursion Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu

V 1.0 37

Accessing static fields/methods• To access static members, an actual type must be used:

MyGenericClass<int>.Count();• Different static fields belong to different types• The static constructor is automatically called

Szabó Zsolt, Óbudai Egyetem, 2011 [email protected]

Page 38: Programming II. Inheritance Interfaces Exceptions Generics Event handling Recursion Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu

V 1.0 38

Generics and inheritance• Generic classes can be derived from both generic and non-generic

class• Generic classes can be the ancestor of both generic and non-

generic classes• However , the type parameter must always be accessible or set!

• If Derived<T> : BaseGeneric<T> , and new Derived<int>() type T will be int in both classes.

• If Derived : BaseGeneric<T>, and new Derived() type T in the base class is not defined, NOT ALLOWED

• If Derived<T> : BaseGeneric<U>, and new Derived<int>() type U in the base class is not defined, NOT ALLOWED

Szabó Zsolt, Óbudai Egyetem, 2011 [email protected]

Page 39: Programming II. Inheritance Interfaces Exceptions Generics Event handling Recursion Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu

V 1.0 39

Generics and inheritance

Melyik eset lehetséges?

Szabó Zsolt, Óbudai Egyetem, 2011 [email protected]

Page 40: Programming II. Inheritance Interfaces Exceptions Generics Event handling Recursion Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu

V 1.0 40

Generics and inheritance• The restrictions must be repeated in the descendant classes, the

descendant class can introduce new constraints• Generics are accessible in all managed CLR-based language• Generics are stored in the MSIL level, the actual type replacement

is done during the JIT compile

Szabó Zsolt, Óbudai Egyetem, 2011 [email protected]

Page 41: Programming II. Inheritance Interfaces Exceptions Generics Event handling Recursion Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu

Programming II.

InheritanceInterfacesExceptionsGenericsEvent handlingRecursion

Szabó Zsolt, Óbudai Egyetem, 2011 [email protected]

Page 42: Programming II. Inheritance Interfaces Exceptions Generics Event handling Recursion Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu

V 1.0

• Three-layer architecture (not necessarily three-tier)

• Typically– Every layer performs one distinct task, and serves data to the layer above– Even if they are deployed as a one-tier application, the logical separation is

highly advised– Easier to mange and change and scale the code– Reusable code!!!

42

Multi-layer architectures

View Controller(ViewModel, Presentation)

Model(Resource)

Szabó Zsolt, Óbudai Egyetem, 2011 [email protected]

Page 43: Programming II. Inheritance Interfaces Exceptions Generics Event handling Recursion Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu

V 1.0

Topics of the practice• Events vs Exceptions• Steps of creating events using interfaces• Steps of creating events using delegates

43Szabó Zsolt, Óbudai Egyetem, 2011 [email protected]

Page 44: Programming II. Inheritance Interfaces Exceptions Generics Event handling Recursion Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu

V 1.0 44

• In the examples there will be two classes, the event creator and the event handler class. This is usually the case, but events (just like exceptions) can be created and handled within one single class

• Aim: signal events (information) to other modules/classes• Possibilities: Function/method pointers (DOS), delegates (C#),

interfaces (JAVA)

Event handling

Szabó Zsolt, Óbudai Egyetem, 2011 [email protected]

Page 45: Programming II. Inheritance Interfaces Exceptions Generics Event handling Recursion Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu

V 1.0 45

• We have to create an interface ISomething that describes the signature and the name of the method that will handle our event

• The event creator/sender class must maintain a private list of ISomething instances

• Using public accessors, another class (the event handler class) can add or remove itself (or other classes) to this list (subscribe, unsubscribe)

• Elements in the list have the type ISomething they all contain the method described in the interface, and this method will handle the event

• The event creator class simply loops through the subscribed classes found in the list, and calls the same method for every instance

Using interfaces for events

Szabó Zsolt, Óbudai Egyetem, 2011 [email protected]

Page 46: Programming II. Inheritance Interfaces Exceptions Generics Event handling Recursion Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu

V 1.0 46

• A type that allows us to „store” methods in a variable• In the declaration we must specify the signature of the methods

that the given delegate can store:

delegate double MyDelegate(int param1, string param2);– Name: MyDelegate– Return type: double– Parameters: int+string

• Important: this is only a type declaration – Not usable without a variable/field of this type– Reference type– Like class/enum: cannot be declared in a method; it must be

declared in a namespace or inside a class

Delegate

Szabó Zsolt, Óbudai Egyetem, 2011 [email protected]

Page 47: Programming II. Inheritance Interfaces Exceptions Generics Event handling Recursion Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu

V 1.0 47

delegate double MyDelegate(int param1, string param2);

double funct(int first, string second) { return first + second.Length;

}

• Unicast delegate: MyDelegate del; del = new MyDelegate(funct); Console.WriteLine(del(5, "hello"));

Using delegates

Szabó Zsolt, Óbudai Egyetem, 2011 [email protected]

Page 48: Programming II. Inheritance Interfaces Exceptions Generics Event handling Recursion Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu

V 1.0 48

delegate double MyDelegate(int param1, string param2);

double funct(int first, string second) { return first + second.Length;

}• Declaring a delegate field:

– MyDelegate del; • Multicast delegate:

– del += funct;Console.WriteLine(del(5, "hello"));

– As long as the delegate is empty, its value will be NULL we must always check it before calling the delegate

– Multiple methods can be put into the same delegate

Using delegates

Szabó Zsolt, Óbudai Egyetem, 2011 [email protected]

Page 49: Programming II. Inheritance Interfaces Exceptions Generics Event handling Recursion Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu

V 1.0 49

delegate bool MyComparer(object left, object right);

class SimpleExchangeSorter

{

public static void Sort(object[] Arr, MyComparer bigger)

{

for (int i = 0; i < Arr.Length; i++)

for (int j = i + 1; j < Arr.Length; j++)

if (bigger(Arr[j], Arr[i]))

{

object temp = Arr[i];

Arr[i] = Arr[j];

Arr[j] = temp;

}

}

}

Delegate-parameter

Szabó Zsolt, Óbudai Egyetem, 2011 [email protected]

Page 50: Programming II. Inheritance Interfaces Exceptions Generics Event handling Recursion Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu

V 1.0 50

Delegate-parameter Example

class student

{

public string name;

public int credits;

public diak(string newname, int newcredits)

{

name = newname; credits = newcredits;

}

public override string ToString()

{

return name + " - " + credits;

}

}

student[] group = new student[] { new student("Első Egon", 52), new student("Második Miksa", 97), new student("Harmadik Huba", 10), new student("Negyedik Néró", 89), new student("Ötödik Ödön", 69)};

Szabó Zsolt, Óbudai Egyetem, 2011 [email protected]

Page 51: Programming II. Inheritance Interfaces Exceptions Generics Event handling Recursion Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu

V 1.0 51

Delegate-parameter code

bool mycomp(object first, object second)

{

return ((first as student).credits <(second as student).credits);

}

 

MyComparer del = new MyComparer(mycomp);

SimpleExchangeSorter.Sort(group, del);

 

OR

 

SimpleExchangeSorter.Sort(group, mycomp);Szabó Zsolt, Óbudai Egyetem, 2011 [email protected]

Page 52: Programming II. Inheritance Interfaces Exceptions Generics Event handling Recursion Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu

V 1.0

Events

52

• Until now: we can use delegates, store methods, call them• Aim: interaction between classes from the functional point of

view, the delegate is good, but with delegates, the key point is the signature of the methods, and not the encapsulating classes

• Practically, we need a public delegate in the event creator class ... With some restrictions!

• We use the „event” keyword to signal that this is an event-delegate– Can be put into an interface (normal delegate field cannot)– Can be called only from within the containing class (normal

public delegates can be called from anywhere)– Cannot use =, only += and -=– Signature: returns void, Sender + EventArgs as parameters

Szabó Zsolt, Óbudai Egyetem, 2011 [email protected]

Page 53: Programming II. Inheritance Interfaces Exceptions Generics Event handling Recursion Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu

V 1.0 53

• No need for lists and subscribe/unsubscribe ... We use delegates to store method references (not instance references!); we use += and -= from the event handler class to subscribe/unsubscribe

• When we call the delegate from the event creator class the method from the other class will be called

• Important:– When calling the event-delegate, we cannot be sure that an

event handler method was actually put into the event delegate or not

– So we always have to check for NULL values before calling the delegate

– It is possible to use multiple event handlers for one event, but in the design view of Visual Studio this is highly limited

Events

Szabó Zsolt, Óbudai Egyetem, 2011 [email protected]

Page 54: Programming II. Inheritance Interfaces Exceptions Generics Event handling Recursion Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu

V 1.0 54

Task Name Location

Event Parameter SomeEventArgs Namespace or creator class

Delegate SomeEventHandler Namespace or creator class

Event Some / SomeEvent Creator class

Method that calls the event delegate

OnSome Creator class

Subscribe to the event

--- Handler class

Method that handles the event

--- Handler class

Szabó Zsolt, Óbudai Egyetem, 2011 [email protected]

Page 55: Programming II. Inheritance Interfaces Exceptions Generics Event handling Recursion Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu

Programming II.

InheritanceInterfacesExceptionsGenericsEvent handlingRecursion

Szabó Zsolt, Óbudai Egyetem, 2011 [email protected]

Page 56: Programming II. Inheritance Interfaces Exceptions Generics Event handling Recursion Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu

V 1.0

• Programming theoremsint Total(int[ ] A, int N)bool Decide(int[ ] A, int N)int MaximumSelection(int[ ] A, int N)

• Binary Searchint BinarySearch(int[ ] A, int value, int lower, int upper)

• Backtrack– Typical examples: 8 queens puzzle, Job assignments– Can be used IF

• The main task can be divided into sub-tasks• About a sub-task, it is possible to decide if it can belong to a

good solution or not• The number of sub-tasks is not extremely high (e.g. 2D

knapsack)56

Programming theorems with recursion

Szabó Zsolt, Óbudai Egyetem, 2011 [email protected]

Page 57: Programming II. Inheritance Interfaces Exceptions Generics Event handling Recursion Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu

V 1.0

function FindSolution(level, ref EXISTS, E)i:=0loop

i:=i+1if (ft(level, i)) then

k:=1loop while (k<level AND fk(level, Rlevel,i, k, Ek))

k:=k+1loop endsif (k = level) then

Elevel:=Rlevel,iif (level=N) then

EXISTS:=trueelse

FindSolution(level+1, EXISTS, E)if ends

if endsif ends

while ((not EXISTS) AND i<Mlevel)function ends

57Szabó Zsolt, Óbudai Egyetem, 2011 [email protected]

Page 58: Programming II. Inheritance Interfaces Exceptions Generics Event handling Recursion Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu

V 1.0

• Suggested modifications to use BackTrack– Transform the 2D table into a series of sub-tasks– Assort the positions for fixed (pre-defined) numbers and for

empty slots– This way, we can use the same algorithm for this task that

was shown in the previous slide

58

Sudoku

1 2 33 5 2

4 8 12 4 1 8

3 1 3

Fix slots: (0,0) (0,2) (0,3) (1,0) …

Empty slots: (0,1) (0,4) (1,2) (1,3) …

Szabó Zsolt, Óbudai Egyetem, 2011 [email protected]

Page 59: Programming II. Inheritance Interfaces Exceptions Generics Event handling Recursion Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu

V 1.0

• Functions to implement– ft(level, number)

Returns with true if the given number can be used for empty slot level. (collisions must be checked with the fix slots)

– fk(level, number, k, knum)Returns with true if the given number can be used for empty slot level. (collision must be checked with the other empty slot k where the number knum is used)

– BackTrack(level, ref EXISTS, E)Implements the algorithm described two slides before this one

– SearchSolutionPublic method to set the input variables and start the recursion

59

Sudoku with Backtrack

Szabó Zsolt, Óbudai Egyetem, 2011 [email protected]

Page 60: Programming II. Inheritance Interfaces Exceptions Generics Event handling Recursion Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu

Programming II.

Graphs

Szabó Zsolt, Óbudai Egyetem, 2011 [email protected]

Page 61: Programming II. Inheritance Interfaces Exceptions Generics Event handling Recursion Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu

V 1.0 61

Graphs & Dijkstra algorithm & Kruskal algorithm• Graph: set of nodes and vertiexes (vertices) that connect

nodes• Currently: undirected, weighted graph• Aim: find the shortest (minimum weighted) path from

node 1 to node 5

• Dijkstra algorithm: determines the path with a minimum weight from a starting node to ALL nodes

• Greedy algorithm

Szabó Zsolt, Óbudai Egyetem, 2011 [email protected]

Page 62: Programming II. Inheritance Interfaces Exceptions Generics Event handling Recursion Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu

V 1.0 62

Dijkstra algorithm• Suppose we already store the graph and we have all the necessary

methods for the management of nodes• We use two arrays, both will have the same number of elements

as the number of nodes• The int typed PrevNode array will store the previous node in the

path: if we have a path from the starting node to node #i, then PrevNode[i] will sore the node in the path before node #i

• The double typed SumWeight array will store the cumulative weight of the path that goes to the different nodes

• Originally we should also split up the nodes into two sets: completed and incomplete nodes. We solve this by defining that node #i is incomplete, if SumWeight[i]<0

• Current starting node: #1 !

Szabó Zsolt, Óbudai Egyetem, 2011 [email protected]

Page 63: Programming II. Inheritance Interfaces Exceptions Generics Event handling Recursion Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu

V 1.0 63

Initialization• Reuired: starting node (Start)• Every other node #i should have the good value for SumWeight[i]:

– Negative values: every node is incomplete– Where there is a vertex between #i and Start: the weight of the

vertex– Otherwise: double.NegativeInfinity

• Every node #i should have the good value for PrevNode[i]:– For the start node, this is -1. For other nodes, set this to the

start node– For nodes that have an vertex, this is currently correct. For

other nodes, we can say: the previous node is the start node, the sum weight is infinity this will surely change

Szabó Zsolt, Óbudai Egyetem, 2011 [email protected]

Page 64: Programming II. Inheritance Interfaces Exceptions Generics Event handling Recursion Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu

V 1.0 64

After initialization

IDX PrevNode SumWeight

1 -1 0

2 1 -10

3 1 -∞

4 1 -5

5 1 -∞Szabó Zsolt, Óbudai Egyetem, 2011 [email protected]

Page 65: Programming II. Inheritance Interfaces Exceptions Generics Event handling Recursion Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu

V 1.0 65

Algorithm

Loop, while we have negative weights (i.e.: while we have any incomplete node)

1. Minimum=the node with the negative and smallest absolute weight; // the incomplete node with the smallest sum weight

2. SumWeight[minimum] = -SumWeight[minimum]; // completed

3. For every incomplete (negative weighted) node, we have to check if we get a better weight if we change the PrevNode: for every node #i we have to check if we get a better value than SumWeight[i] if we change PrevNode[i] to the “minimum” node. If yes, then we update SumWeight[i] and PrevNode[i]=Minimum

Loop ends

Szabó Zsolt, Óbudai Egyetem, 2011 [email protected]

Page 66: Programming II. Inheritance Interfaces Exceptions Generics Event handling Recursion Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu

V 1.0 66

Iteration #1

IDX PrevNode SumWeight

1 -1 0

2 1 -10

3 1 -∞

4 1 -5

5 1 -∞

SMALLEST ONE(ABS) 5

-8

-14

-16

4

4

4Szabó Zsolt, Óbudai Egyetem, 2011 [email protected]

Page 67: Programming II. Inheritance Interfaces Exceptions Generics Event handling Recursion Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu

V 1.0 67

Iteration #2

IDX PrevNode SumWeight

1 -1 0

2 4 -8

3 4 -14

4 1 5

5 4 -16

8

-9 2

Szabó Zsolt, Óbudai Egyetem, 2011 [email protected]

SMALLEST ONE(ABS)

Page 68: Programming II. Inheritance Interfaces Exceptions Generics Event handling Recursion Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu

V 1.0 68

Iteration #3

IDX PrevNode SumWeight

1 -1 0

2 4 8

3 2 -9

4 1 5

5 4 -16

SMALLEST ONE(ABS)

-10

9

3Szabó Zsolt, Óbudai Egyetem, 2011 [email protected]

Page 69: Programming II. Inheritance Interfaces Exceptions Generics Event handling Recursion Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu

V 1.0 69

Iteration #4

IDX PrevNode SumWeight

1 -1 0

2 4 8

3 2 9

4 1 5

5 3 -10 SMALLEST ONE(ABS)

10Szabó Zsolt, Óbudai Egyetem, 2011 [email protected]

Page 70: Programming II. Inheritance Interfaces Exceptions Generics Event handling Recursion Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu

V 1.0 70

Final state

IDX PrevNode SumWeight

1 -1 0

2 4 8

3 2 9

4 1 5

5 3 10

Every node can be accessed

from the starting node

The paths do not necessarily form a lineor a tree, this is unique

Szabó Zsolt, Óbudai Egyetem, 2011 [email protected]

Page 71: Programming II. Inheritance Interfaces Exceptions Generics Event handling Recursion Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu

V 1.0 71

Development• Graph class: int numNodes; double[,] weights; string[] labels;

– public Graphs(int n) adjacency list vs matrix– public void NewLabel(int n, string label)– public void NewVertex(int n, int m, double weight)– public int GetNode(string label)– public double GetWeight(int n, int m)

• Dijkstra algorithm methods:– private bool MinSearch(double[] d, out int min)

Returns bool (are there any incomplete nodes) and an int (the index of the best negative weight (minimum absolute value) )

– public List<int> GetPathDijkstra(int start, int target)We execute the algorithm

Szabó Zsolt, Óbudai Egyetem, 2011 [email protected]

Page 72: Programming II. Inheritance Interfaces Exceptions Generics Event handling Recursion Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu

V 1.0 72

Kruskal algorithm• Tree: loopless (acyclic), complete graph• Spanning tree: a tree that contains all graph nodes and the

vertices are a subset of the original graph’s vertices. If the graph had n nodes, then the spanning tree has n-1 vertices

• Minimal spanning tree: the one with the minimum sum weight

Szabó Zsolt, Óbudai Egyetem, 2011 [email protected]

Page 73: Programming II. Inheritance Interfaces Exceptions Generics Event handling Recursion Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu

V 1.0 73

Kruskal algorithm - example

Szabó Zsolt, Óbudai Egyetem, 2011 [email protected]

Page 74: Programming II. Inheritance Interfaces Exceptions Generics Event handling Recursion Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu

V 1.0 74

Kruskal algorithm - example

Szabó Zsolt, Óbudai Egyetem, 2011 [email protected]

Page 75: Programming II. Inheritance Interfaces Exceptions Generics Event handling Recursion Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu

V 1.0 75

Kruskal algorithm - example

Szabó Zsolt, Óbudai Egyetem, 2011 [email protected]

Page 76: Programming II. Inheritance Interfaces Exceptions Generics Event handling Recursion Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu

V 1.0 76

Kruskal algorithm - example

Szabó Zsolt, Óbudai Egyetem, 2011 [email protected]

Page 77: Programming II. Inheritance Interfaces Exceptions Generics Event handling Recursion Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu

V 1.0 77

Kruskal algorithm - example

Szabó Zsolt, Óbudai Egyetem, 2011 [email protected]

Page 78: Programming II. Inheritance Interfaces Exceptions Generics Event handling Recursion Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu

V 1.0 78

Kruskal algorithm - example

Szabó Zsolt, Óbudai Egyetem, 2011 [email protected]

Page 79: Programming II. Inheritance Interfaces Exceptions Generics Event handling Recursion Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu

V 1.0 79

Kruskal algorithm - example

Szabó Zsolt, Óbudai Egyetem, 2011 [email protected]

Page 80: Programming II. Inheritance Interfaces Exceptions Generics Event handling Recursion Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu

V 1.0 80

Kruskal algorithm – example

Szabó Zsolt, Óbudai Egyetem, 2011 [email protected]

Page 81: Programming II. Inheritance Interfaces Exceptions Generics Event handling Recursion Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu

V 1.0 81

Kruskal algorithm – development

1. We define the components array, where components[i] will store the component identifier for node #i. At the beginning, every value is different [0..X] no nodes in the spanning tree yet

2. double weights[,] List<MyVertex> vertices (MyVertex = {start point, end point, weight})

3. Sort the vertices according to weights, ascending4. Loop, while the spanning tree is not ready and we have vertices

a) Akt = the next vertex in the list where the start point and the end point are in different components

b) If we find a vertex like that, we add it to the spanning tree and we merge the two components

5. public List<MyVertex> Kruskal()

Szabó Zsolt, Óbudai Egyetem, 2011 [email protected]

Page 82: Programming II. Inheritance Interfaces Exceptions Generics Event handling Recursion Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu

Szabó Zsolt, Óbudai Egyetem, 2011 [email protected]

Page 83: Programming II. Inheritance Interfaces Exceptions Generics Event handling Recursion Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu

Szabó Zsolt, Óbudai Egyetem, 2011 [email protected]

Page 84: Programming II. Inheritance Interfaces Exceptions Generics Event handling Recursion Szabó Zsolt, Óbudai Egyetem, 2011 szabo.zsolt@nik.uni-obuda.hu

V 1.0

• http://www.supercoloring.com/wp-content/thumbnail/2009_01/onion-4-coloring-page.gif• http://www.kids-n-fun.com/coloringpages/ToonKleurPlaat.aspx?imageurl=eten/eten21.gif&TExt=Kids-n-Fun%20%7C%20Coloring%20pages:%20Butter

%20&kleurplaten=56• http://dclips.fundraw.com/zobo500dir/milk_bw.jpg• http://dir.coolclips.com/clipart/150/vgjm/tf05034/CoolClips_food0403.jpg• http://www.supercoloring.com/wp-content/main/2009_01/rice-6-coloring-page.gif• http://www.supercoloring.com/pages/big-piece-of-meat/• http://ngfl.northumberland.gov.uk/clipart/Food/images/onion_jpg.jpg• http://fc06.deviantart.net/fs70/f/2010/052/f/8/Chara_Egg_Base_by_drakangel614.png

84

Képek forrásai

Szabó Zsolt, Óbudai Egyetem, 2011 [email protected]