Download presentation
Presentation is loading. Please wait.
Published byIrma McDowell Modified over 8 years ago
1
1 Tirgul 8 Inheritance and Polymorphism
2
2 Inheritance and Polymorphism An important part of Object Oriented Programming. Very often misused by beginners. Inheritance: If the parent can do something, so can the child. Allows for code re-use (not as important as other traits – there are other ways we ’ ve seen to re-use code) Polymorphism: The ability to write code that works for many types. Inheritance enables this. This is the main benefit. Examples will follow …
3
3 Class hierarchy example PrivateCar is a type of Car. It does anything Car does, and more. We say that PrivateCar extends Car. Car PrivateCar CommercialCar Mazda Toyota Subaru Mazda121 Mazda323 Mazda626 … … …
4
4 Extending a class public class Car {…} public class PrivateCar extends Car{…} You can only extend one class. The extended class is often called: Parent Class, Super Class, Ancestor, Base Class. The extending class is called: Child, Sub- Class, Descendent, Derived Class.
5
5 Inheritance When a class extends another class it automatically inherits all of its members (Both methods and fields). However, it can access only the public and protected members. Implication: Child class can handle any method call that Parent class can. There is no way to “ hide ” any of the inherited methods. Car car = new Car(); PrivateCar privCar = new PrivateCar(); If you can do car.honk(); You can also do privCar.honk();
6
6 Constructors and the keyword super The parent class has fields that must be initialized during creation of the child class. They may even be private and not accessible to the child. Therefore: any time a constructor of the child is called, the constructor of the parent is also called. Accomplished with: super() Must be the first statement in the constructor. If you do not use super() Java calls the default constructor of the parent. If there is no default, the code will not compile!
7
7 Private Public Protected Private Public Protected Extending a class Other Classes Parent Class Child Class
8
8 Example public class Person{ private final String _name; public Person(String name){ _name = name; } public String getName(){return _name;} } public class CSStudent extends Person{ private String _login; public CSStudent(String name, String login){ super(name); _login = login; } because it is final, initialization of _name must occur at creation time. No one except the class Person can initialize the field _name.
9
9 Upcasting We can always treat a child object as if it were a parent object Upcasting is converting from child type to parent type (always safe) PrivateCar prvCar = new PrivateCar(); Car car1 = (Car) prvCar; Car car2 = prvCar; car1.honk(); car2.honk(); explicit upcasting implicit upcasting
10
10 Downcasting Downcasting is converting from parent type to child type (not always safe!) Downcasting must always be explicit Car car1 = new PrivateCar(); PrivateCar prvCar = car1; PrivateCar prvCar1 = (PrivateCar) car1; Car car2 = new Car(); PrivateCar prvCar2 = (PrivateCar) car2; implicit upcasting implicit downcasting: compile error downcasting - OK This will cause a runtime ClassCastException: Car cannot be converted to PrivateCar
11
11 Why upcast? Suppose you want to built a data structure that could only hold Strings. What if we want to hold something else? Do we write a new structure for every type of object we create? Instead: write a structure that holds java.lang.Object use upcasting when putting in values, and downcasting when extracting.
12
12 Upcasting and Downcasting public class MyStructure{ private Object[] _data; public Insert(Object element){…} public Object Remove(){…} … } Somewhere else in the code: String str = “Hello”; struct.insert(str); //upcasting str = (String) struct.remove(); //downcasting Is it safe to downcast here?
13
13 instanceof What if we mix items of different types in the structure and wish to downcast correctly? We can check the exact type of the class using the keyword “ instanceof ” Object item = struct.remove(); if(item instanceof String){ String str = (String) item; //this is safe!... }
14
14 instanceof (a instanceof B) is true iff a is an instance of class B or any of its descendants Car car = new Car(); System.out.print(car instanceof Object); System.out.print(car instanceof Car); System.out.print(car instanceof PrivateCar); true false true
15
15 How not to use instanceof Our code should be designed so that adding new child classes does not necessitate changes to the parent class Do not do this: public class PrivateCar { public void print() { if (this instanceof Mazda) System.out.print(“Mazda”); if (this instanceof Toyota) System.out.print(“Toyota”); } } Instead: use method overriding …
16
16 Overriding methods Objects inherit methods from their parent, but may change the methods they inherit. Simply redefine them. The keyword super can be used to call methods from the parent class and thus reuse their code. public class CSStudent extends Person{ private String _login;... public String getName(){ return super.getName() + “ “+ _login; }
17
17 Polymorphism The inheritance mechanisms we ’ ve seen allow using objects that have a shared ancestor interchangeably We do not need to know the exact type of the object we are holding The “ correct ” implementation of overridden methods will be called at runtime
18
18 Polymorphic use of objects All the mechanisms we ’ ve just seen give us power to use objects that have a shared ancestor interchangeably. We do not need to know the exact type of object we are holding. Example: public class Animal(){ public void makeSound(){} … }
19
19 Subclasses of animal. public class Dog extends Animal{ public void makeSound() { System.out.println("Woof Woof"); } public class Cat extends Animal{ public void makeSound() { System.out.println("Meow"); } public class Bird extends Animal{ public void makeSound() { System.out.println(“Tweet Tweet"); }
20
20 public static void main(String[] args){ Animal[] animals = new Animal[3]; animals[0] = new Dog(); animals[1] = new Cat(); animals[2] = new Bird(); for(int i=0; i<animals.length; i++){ animals[i].makeSound(); } Output: Woof Meow Tweet This last bit of code can treat all kinds of animals. Even those that are not written yet.
21
21 Abstract classes & methods Abstract methods have no implementation. They must reside inside abstract classes If the child class is not abstract, it must implement all abstract methods. Abstract classes cannot be instantiated. Useful for things we don ’ t want an instance of. They may still have constructors. (What for?)
22
22 Abstract Animal We do not want anyone to create an object out of the Animal class. We make it abstract: public abstract class Animal(){ public abstract void makeSound(); … } We also turned makeSound() into an abstract method because we want all subclasses to implement it But cannot offer a “ default ” implementation that is inherited.
23
Abstract - Example abstract class Shape { abstract void draw() ; abstract void erase(); abstract double area(); } class Circle extends Shape { void draw() { System.out.println("Circle.draw()"); } void erase() { System.out.println("Circle.erase()"); } double area(){ System.out.println(“pi*r^2"); … } } 23 Notice the abstract method declaration
24
Abstract - Example (cont.) class Square extends Shape { void draw() { System.out.println("Square.draw()"); } void erase() { System.out.println("Square.erase()"); } double area(){ System.out.println(“base*height"); … } } class Triangle extends Shape { void draw() { System.out.println("Triangle.draw()");} void erase() { System.out.println("Triangle.erase()“);} double area() { System.out.println("Triangle area…"); … } 24
25
Random shapes generator // A "factory" that randomly creates shapes class RandomShapeGenerator { public Shape next() { int randNum=(int) Math.random()*3; switch(randNum) { case 0: return new Circle(); break; case 1: return new Square(); break; case 2: return new Triangle(); break; default: break; } } 25
26
Casting and arrays public class Shapes { private static RandomShapeGenerator gen = new RandomShapeGenerator(); public static void main(String[] args) { Shape[] s = new Shape[9]; // Fill up the array with shapes: for(int i = 0; i < s.length; i++) s[i] = gen.next(); // Make polymorphic method calls: for(int i = 0; i < s.length; i++) s[i].draw(); } } 26 We don’t know what shapes are created and inserted to s Polymorphism! (No explicit casting and no ‘instance of’ check are needed)
27
Polymorphism and arrays – typical run >> Square.draw() Circle.draw() Triangle.draw() Square.draw() Triangle.draw() Circle.draw() Square.draw() 27
28
28 Interfaces Not the same interface we talk about when we discuss API. Rather: a java construct (similar to a class).
29
29 Interfaces The most frequent use of polymorphism is usually via interfaces. They are like abstract classes with all methods abstract. The difference: An object can implement several interfaces.
30
30 Interface syntax public interface CanCopy { public Object copy(); } public interface Printable { public void print(); } public class Child extends Parent implements CanCopy, Printable { public Object copy() {…} public void print() {…} … } Place this in a file named CanCopy.java Place this in a file named Printable.java
31
31 public Interface Closeable{ public void close(); } public class Child extends Parent implements Closeable{ public void close(){} } Public class A extends B implements C,D,E{ … } Place this in Closeable.java. Notice there is no implementation of close() This class must implement all methods in the interface, or be abstract. Promises to implement several interfaces.
32
32 Example: Comparable public interface Comparable { /** Compares this object with the given object. Returns a negative integer, zero, or a positive integer if this object is smaller, equal, or larger than the given object. */ public int compareTo(Object obj); } This interface imposes an ordering on the objects of each class that implements it
33
33 Implementing Comparable public class Person implements Comparable { private int _weight; private String _name; public int compareTo(Object obj) { Person other = (Person) obj; if (_weight == other._weight) return 0; return _weight < other._weight ? -1 : 1; } … } We will compare people based on their weight What will happen if someone tries to compare a Person to an object which is not a Person?
34
34 Using Comparable: findMax /** Returns the maximal item in a given array */ public static Comparable findMax (Comparable[] items) { Comparable max = items[0]; for (int i=1; i<items.length; i++) { if (max.compareTo(items[i]) < 0) { max = items[i]; } return max; } What are this method ’ s assumptions? We can use this method on an array of any type of objects which implement the Comparable interface
35
35 Using findMax public static void printFattest(Person[] people) { Person fattest = (Person) findMax(people); System.out.print(“The fattest person is “ + fattest.getName() + “, weighing “ + fattest.getWeight() + “ kg!”); } What if we sometimes want to compare people based on different criteria?
36
36 Iterator Similarly to DigitsParser (from Ex. 3), we can define a general iterator. This iterator can iterate over a collection (and not only string). public interface Iterator { public Comparable next(); public boolean hasNext(); }
37
37 Implementing the interfaces: Now, every class that would like to implement iterator will have to “stick” the Iterator interface description. public class DigitsIterator implements Iterator{ public boolean hasNext() {...} public Comparable next() {...}... }
38
38 Now we can write code that fits any data structure: public static boolean isInside(Iterator iter, Comparable item){ while(iter.hasNext()){ if (iter.next(). compareTo (item)==0){ return true; } return false; } This will work for any iterator, regardless of the data structure it is linked to.
39
39 The Comparator interface public interface Comparator { /** Compares two objects. Returns a negative integer, zero, or a positive integer if obj1 is smaller, equal, or larger than obj2. */ public int compare(Object obj1, Object obj2); } This interface will be implemented by objects that know how to compare other objects
40
40 Implementing Comparator (1) public class PersonWeightComparator implements Comparator { public int compare(Object obj1, Object obj2) { Person person1 = (Person) obj1; Person person2 = (Person) obj2; int weight1 = person1.getWeight(); int weight2 = person2.getWeight(); if (weight1 == weight2) return 0; return weight1 < weight2 ? -1 : 1; } This class compares people based on their weight
41
41 Implementing Comparator (2) public class PersonNameComparator implements Comparator { public int compare(Object obj1, Object obj2) { Person person1 = (Person) obj1; Person person2 = (Person) obj2; String name1 = person1.getName(); String name2 = person2.getName(); return name1.compareTo(name2); } This class compares people based on their name Class String implements the java.lang.Comparable interface, comparing strings lexicographically
42
42 findMax using Comparator /** Returns the maximal item in a given array */ public static Object findMax (Object[] items, Comparator comp) { Object max = items[0]; for (int i=1; i<items.length; i++) { if (comp.compare(max, items[i]) < 0) { max = items[i]; } return max; } Now this method may give different results for the same array, based on the given Comparator
43
43 Using findMax with a Comparator public static void printFattest(Person[] people) { Comparator comp = new PersonWeightComparator(); Person fattest = (Person) findMax(people, comp); System.out.print(“The fattest person is “ + fattest.getName() + “, weighing “ + fattest.getWeight() + “ kg!”); }
44
44 Using findMax with a Comparator public static void printFirst(Person[] people) { Comparator comp = new PersonNameComparator(); Person first = (Person) findMax(people, comp); System.out.print(“The person whose name “ + “comes first alphabetically is “ + first.getName()); }
45
45 Misc. Notes on Inheritance
46
46 Interfaces can extend interfaces We can have inheritance within interfaces. public interface A{... } public interface B extends A{...} public class C implements B{...} Now, everyone that implements B, must also implement all of A ’ s methods. C obj = new C(); B obj2 = obj; //upcasting A obj3 = obj;//upcasting
47
47 Reminder: Casting and arrays Arrays can be cast to parent types and back. public static void main(String[] args){ Object[] objArr = new String[5]; objArr[0] = "Hi"; System.out.println(objArr instanceof String[]); String[] strArr = (String[]) objArr; System.out.println(strArr[0]); } Upcasting Downcasting
48
48 final classes and methods A final method cannot be overridden. A final class cannot be extended. For example, you may want to declare methods that are called from a constructor final, so they are not changed by accident by extending classes.
49
49 Static methods are inherited but aren ’ t polymorphic! public class Parent { public static void myMethod(){ System.out.println("Parent"); } public class Child extends Parent { public static void myMethod(){ System.out.println(“Child"); } public static void main(String[] args){ Parent obj = new Child(); obj.myMethod(); } Output: Parent
50
50 When to extend and when to reference? Sometimes we have objects that use other objects. Sometimes we have objects that extend other objects. When do we use each method? public class Person{ public Person(String name){…} public String getName(){…} public Person[] getListOfFriends(){…} }
51
51 When to extend and when to reference? public class Car { private Person _driver; public Car(Person driver, double topSpeed){ _driver = driver; } public String getDriverName(){…} public double getTopSpeed(){…} } public class Car extends Person{ public Car(String driverName, double topSpeed){ super(driverName); _topSpeed = topSpeed; } public double getTopSpeed(){…} } Can both classes do the same things? Yes! Which is better? Car Person Car _driver
52
52 When to extend and when to reference? Extend mostly when you want to use objects interchangeably. Otherwise you may inherit methods that are not sensible No way to hide methods … Usually, you should reference.
53
53 Collection interface Collection is an abstract representation of a … collection/group of items/elements – an object that holds other objects (also called container). Typically, collections are iterable. Elements in a collection have no specific order. Queue, stack, arrays, sets and many other more data structures (to be learnt in the next semester/year) can be implemented using the collection interface. Check the interface for the Collection type in Java. (http://java.sun.com/j2se/1.4.2/docs/api/java/util/Collection.html )interface for the Collection http://java.sun.com/j2se/1.4.2/docs/api/java/util/Collection.html
54
54 Partial interface for collection Public interface Collection { public boolean add (Object o); public boolean contains(Object o); public boolean isEmpty(); public boolean remove(Object o); public Iterator iterator(); public Object[] toArray(); } There are no guarantees concerning the order in which the elements are returned (unless this collection is an instance of some class that provides a guarantee) Elements are returned in the same order of the iterator
55
55 Call by Reference vs. Call by Value – Test Yourselves Which of these is useless? public void swap0(int a, int b){ int temp = a; a = b; b = temp; } public void swap1(int[] a, int[] b){ int[] temp =a; a = b; b = temp; }
56
56 Call by Reference vs. Call by Value – Test Yourselves Which of these is useless? public void swap2(int[] a, int[] b){ int[] temp =a.clone(); a = b.clone(); b = temp; } public void swap3(int[] a, int[] b){ for(int i=0; i<a.length; i++){ int temp = a[i]; a[i] = b[i]; b[i] = temp; }
Similar presentations
© 2024 SlidePlayer.com. Inc.
All rights reserved.