Downcast Ball ball; Sprite sprite; ball = sprite; ? Sprite Sometimes possible Lecture 12 → Must use explicit cast → May fail at runtime Programming for Inheritance or ball = (Ball) sprite; ball = sprite as Ball; Robi Malik DEPARTMENT OF COMPUTER SCIENCE TARI ROROHIKO © THE UNIVERSITY OF WAIKATO • TE WHARE WANANGA O WAIKATO Casting Brick brick; Ball ball; brick = ball; brick = (Brick)ball; C1 var1; C2 var2; Never possible Can we do: Then answer depends on the inheritance relationship between classes C1 and C2 COMP104-11S Lecture 12 2 x_, y_ width_, height_ Sprite Draw(Graphics graphics) Move() Ball Paddle Every ball is a sprite. © THE UNIVERSITY OF WAIKATO • TE WHARE WANANGA O WAIKATO Sprite COMP104-11S Lecture 12 5 Inheritance Sprite Always possible: © THE UNIVERSITY OF WAIKATO • TE WHARE WANANGA O WAIKATO Upcast 4 Cast across inheritance Brick Ball hierarchy not possible: A ball can never be an brick. var1 = var2; ??? Ball ball; Sprite sprite; sprite = ball; COMP104-11S Lecture 12 Never a Cast Can we convert one reference to another? Given: © THE UNIVERSITY OF WAIKATO • TE WHARE WANANGA O WAIKATO Brick Ball Draw(Graphics graphics) Move() LaunchBall() COMP104-11S Lecture 12 3 Paddle inherits all features of Sprite → 4 instance variables → 3 methods Paddle is-a Sprite “Override” © THE UNIVERSITY OF WAIKATO • TE WHARE WANANGA O WAIKATO COMP104-11S Lecture 12 6 1 Composition/Association Paddle Also Works with Interfaces interface IDrawable { public void Draw(); } Game 1 Draw(Graphics graphics) paddle_ Move() LaunchBall() score_ Tick() class Star : IDrawable { … } class Ship : IDrawable { … } Game owns/uses an instance of Paddle Star → Can call methods: paddle_.Move(); → Update association: paddle_ = new Paddle(); COMP104-11S Lecture 12 7 Polymorphism Sprite x_, y_ width_, height_ Draw(Graphics graphics) Move() Paddle Draw(Graphics graphics) Move() LaunchBall() COMP104-11S Lecture 12 10 A class can inherit from only one class But it can implement any number of interfaces score_ Tick() public class Ball : Sprite, IDrawable, ICloneable { … Subclass of Sprite, also } implements IDrawable and ICloneable Polymorphism = Composition + Inheritance © THE UNIVERSITY OF WAIKATO • TE WHARE WANANGA O WAIKATO © THE UNIVERSITY OF WAIKATO • TE WHARE WANANGA O WAIKATO Single or Multiple Inheritance Game * sprites_ Ship IDrawable[] items; foreach (IDrawable item in items) { item.Draw(); } Game has-a Paddle © THE UNIVERSITY OF WAIKATO • TE WHARE WANANGA O WAIKATO IDrawable COMP104-11S Lecture 12 8 © THE UNIVERSITY OF WAIKATO • TE WHARE WANANGA O WAIKATO COMP104-11S Lecture 12 11 Polymorphism in Action Overriding Game has a member of class Sprite Methods declared as abstract or virtual can be overridden in a subclass. → or Paddle → or Ball → or / Must use overridekeyword. Game calls: sprite_.Move() Must use same method name, parameters, and return type. This must execute the correct code: → Paddle.Move() → or Ball.Move() → or / © THE UNIVERSITY OF WAIKATO • TE WHARE WANANGA O WAIKATO Must use less restrictive access modifier. Can use base to call superclass method. COMP104-11S Lecture 12 9 © THE UNIVERSITY OF WAIKATO • TE WHARE WANANGA O WAIKATO COMP104-11S Lecture 12 12 2 Copy Constructors Deep Copy class Product { public Product(Product p) Product { code_ = p.code_; code_ description_ = description_ p.description_; price_ price_ = p.price_; } } class Book : Product { public Book(Book b) : base(b) Book { author_ = b.author_; author_ } } © THE UNIVERSITY OF WAIKATO • TE WHARE WANANGA O WAIKATO COMP104-11S Lecture 12 13 mesh :Mesh :Mesh triangles_ triangles_ :List :List contents_ copy contents_ public Mesh(Mesh mesh) { triangles_ = new List<Triangle>(); foreach (Triangle t in mesh.triangles_) triangles_.Add(new Triangle(t)); } © THE UNIVERSITY OF WAIKATO • TE WHARE WANANGA O WAIKATO COMP104-11S Lecture 12 16 The ICloneableInterface Shallow vs. Deep Copy class Mesh { Polymorphic Object Duplication private List<Triangle> triangles_; public Mesh(Mesh mesh) { triangles_ = mesh.triangles_; } } © THE UNIVERSITY OF WAIKATO • TE WHARE WANANGA O WAIKATO COMP104-11S Lecture 12 14 The Clone() method returns a duplicate of the object it is called for. May be shallow or deep copy depending on application. © THE UNIVERSITY OF WAIKATO • TE WHARE WANANGA O WAIKATO COMP104-11S Lecture 12 17 Implementing ICloneable Shallow Copy mesh public interface ICloneable { public object Clone(); } :Mesh :Mesh triangles_ triangles_ public class Flight : ICloneable { copy :List Using copy constructor public object Clone() { return new Flight(this); } contents_ Using memberwise clone: public Mesh(Mesh mesh) { triangles_ = mesh.triangles_; } © THE UNIVERSITY OF WAIKATO • TE WHARE WANANGA O WAIKATO COMP104-11S Lecture 12 15 public object Clone() { Flight flight = (Flight) MemberwiseClone(); flight.bookings_ = new List<Booking>(); return flight; } © THE UNIVERSITY OF WAIKATO • TE WHARE WANANGA O WAIKATO COMP104-11S Lecture 12 18 3 The this Reference Every method is applied to a particular object of its class. A reference to that object is stored in the special variable this. We can use this to pass the current object as an argument to another method. return new Flight(this); © THE UNIVERSITY OF WAIKATO • TE WHARE WANANGA O WAIKATO COMP104-11S Lecture 12 19 Universal Base Class object All classes are subclasses of object and inherit the following methods: public public public public public public object MemberwiseClone(); string ToString(); bool Equals(object obj); Type GetType(); int GetHashCode(); void Finalize(); © THE UNIVERSITY OF WAIKATO • TE WHARE WANANGA O WAIKATO COMP104-11S Lecture 12 22 The MemberwiseClone()Method Using a Dictionary public object MemberwiseClone(); A dictionary (or associative map) is used to map keys to values. Allocates memory for a new object Initialises the new object with the data from the object it is called on → by byte-wise copying Works like shallow copy © THE UNIVERSITY OF WAIKATO • TE WHARE WANANGA O WAIKATO COMP104-11S Lecture 12 20 Cloning vs. Copy Constructor Copy Constructors are class-specific. always return the proper type. → Usually the preferred solution Cloning works for all objects implementing ICloneable. returns an unspecified object, casting may be needed. → Only for polymorphic use © THE UNIVERSITY OF WAIKATO • TE WHARE WANANGA O WAIKATO COMP104-11S Lecture 12 21 Dictionary<string,string> dict = new Dictionary<string,string>(); dict.Add("cat", "domestic"); dict.Add("dog", "domestic"); dict.Add("kiwi", "New Zealand"); dict.Add("llama", "South America"); … string home = dict["kiwi"]; © THE UNIVERSITY OF WAIKATO • TE WHARE WANANGA O WAIKATO COMP104-11S Lecture 12 23 Hash Tables Dictionaries are implemented as hash tables. Keys and values are stored in an array of fixed size. When adding or looking up a key, a unique hash code is computed from the key's data and used as index in the table. → Obtained using GetHashCode(). → Typically random, but equal keys give equal hash codes. © THE UNIVERSITY OF WAIKATO • TE WHARE WANANGA O WAIKATO COMP104-11S Lecture 12 24 4 Hash Table Object Diagram "cat".GetHashCode() == 13 "dog".GetHashCode() == 5 "kiwi".GetHashCode() == 7 "llama".GetHashCode() == 5 :Dictionary contents_ 0 1 2 3 4 5 Equals()and GetHashCode() 6 7 8 9 10 11 :KeyValuePair 12 13 14 15 :KeyValuePair "dog" value_ "domestic" "cat" value_ "domestic" key_ key_ :KeyValuePair "kiwi" value_ "New Zealand" key_ All classes inherit the methods Equals() and GetHashCode() from object. The default implementation is based on object identity. → Equality of memory addresses. This is usually what you want. If you want to use objects as dictionary keys, you may have to override Equals() and GetHashCode(). → This is not easy! © THE UNIVERSITY OF WAIKATO • TE WHARE WANANGA O WAIKATO COMP104-11S Lecture 12 25 © THE UNIVERSITY OF WAIKATO • TE WHARE WANANGA O WAIKATO COMP104-11S Lecture 12 28 Hash Collisions About Hash Tables Occasionally two keys have the same hash code and are mapped to the same table cell. Hash tables provide constant-time insert and lookup operations based on keys O(1) → This is called a collision. Each table cell may contain more than one entry. → The so-called overflow list. To find the right key, the method Equals() is used. © THE UNIVERSITY OF WAIKATO • TE WHARE WANANGA O WAIKATO :Dictionary 2 3 4 5 6 7 8 9 10 11 12 13 14 15 :KeyValuePair :KeyValuePair key_ © THE UNIVERSITY OF WAIKATO • TE WHARE WANANGA O WAIKATO COMP104-11S Lecture 12 29 Reading C# for Students contents_ 1 the hash function gives an even distribution; the hash table is big enough. COMP104-11S Lecture 12 26 Hash Collision Object Diagram 0 assuming that: "kiwi" value_ "New Zealand" next_ null Chapter 24: Polymorphism pp. 408–418 key_ "dog" value_ "domestic" next_ :KeyValuePair key_ “llama" value_ “Peru" null next_ Murach’s C# 2008 :KeyValuePair "cat" value_ "domestic" next_ null key_ © THE UNIVERSITY OF WAIKATO • TE WHARE WANANGA O WAIKATO COMP104-11S Lecture 12 27 Chapter 14: How to work with inheritance pp. 411–448 © THE UNIVERSITY OF WAIKATO • TE WHARE WANANGA O WAIKATO COMP104-11S Lecture 3 30 5