Tirgul 10 OOP 1 Feedback from ex 6

Tirgul 10 - OOP 1

Feedback from ex 6 n n Use “this(…)” to invoke one constructor from another. Prevents code repetition. Names of variables and methods: make sure they’re not too short (“vl” instead of “val” or “value”), and not too long (“that. Particular. Value. That. Was. Returned” ). Pay attention to private / public data-members in a class. Redundant data-members: for example, in a rectangle it’s enough to keep only one Point + width + height. There’s no need to store additional Point objects since they don’t contribute anything new… n Preventing data redundancy is an important principle. 2

Principles of object-oriented programming n n Abstraction: objects (classes) are characterized/defined by their functionality, not their implementation encapsulation: data is protected from “external” users polymorphism: the same function call may invoke different code, depending on context inheritance: properties and methods defined for a certain structure can be used by all structures defined as direct offspring 3

What is the difference? interface Comparable { int compare. To(Object other); } And interface Comparable<T> { int compare. To(T other); } 4

Summary: Interface and polymorphism n n n A Java interface is a collection of constants and abstract methods that a class must implement A class formally implements an interface by n stating so in the class header n providing implementations for each abstract method in the interface An interface name can be used as the type of an object reference variable Comparable comp. Obj; n The comp. Obj reference can be used to point to any object of any class that implements the Comparable interface Interface reference is polymorphic comp. Obj. compare. To(comp. Obj 2); may execute different methods at different times if the object that comp. Obj points to changes 5

Before moving to inheritance lets do an (easy) exam question 6

• Recall the Comparator<T> interface: • You are given the following method, which can be found in java. utils. Arrays: 7

• Assume we have a class called Person, and each Person has a first and last name. • You are provided with two Comparator objects: 8

• Implement a function sort. Persons. By. Full. Name that sorts an array of Person objects by their names: • First by last name, and if two or more people share the same last name, they are sorted by their first names. • public static void sort. Persons. By. Full. Name(Person[] arr) 9

• Define a new comparator: • Use the comparator: 10

Inheritance and Polymorphism n n n An important part of Object Oriented Programming. Very often misused by beginners. Inheritance: If the parent can do something, so can the child. n n 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. n n Inheritance enables this. This is the main benefit. Examples will follow… 11

Class hierarchy example Car Private. Car Toyota Mazda Commercial. Car … Subaru … Mazda 121 Mazda 323 … Mazda 626 Private. Car is a type of Car. It does anything Car does, and more. We say that Private. Car extends Car. 12

Extending a class public class Car {…} public class Private. Car extends Car{…} n n n 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. 13

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. n Implication: Child class can handle any method call that Parent class can. n There is no way to “hide” any of the inherited methods. Car car = new Car(); Private. Car priv. Car = new Private. Car(); n If you can do car. honk(); n You can also do priv. Car. honk(); n 14

Constructors and the keyword super n The parent class has fields that must be initialized during creation of the child class. n n n Therefore: any time a constructor of the child is called, the constructor of the parent is also called. Accomplished with: super() n n They may even be private and not accessible to the child. Must be the first statement in the constructor. If you do not use super() Java calls the default constructor of the parent. n If there is no default, the code will not compile! 15

Extending a class Other Classes Public Protected Private Parent Class Child Class 16

Example No one except the class Person can initialize the field name. public class Person{ private final String name; protected int height; public Person(String name, int height){ this. name = name; because it is final, this. height = height; initialization of name } must occur at public String get. Name(){ return name; } creation time. } public class Cs. Student extends Person{ private String login; private int avg. Grade; public Cs. Student(String name, int height, String login, int avg){ super(name, height); this. login = login; this. avg. Grade = avg; } public int get. Avg. Grade() { return avg. Grade; } 17 }

Upcasting n n 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) Private. Car prv. Car = new Private. Car(); explicit upcasting Car car 1 = (Car) prv. Car; implicit upcasting Car car 2 = prv. Car; car 1. honk(); car 2. honk(); 18

Downcasting n n Downcasting is converting from parent type to child type (not always safe!) Downcasting must always be explicit Car car 1 = Private. Car Car car 2 = Private. Car new Private. Car(); implicit upcasting prv. Car = car 1; implicit downcasting: compile error prv. Car 1 = (Private. Car) car 1; new Car(); downcasting - OK prv. Car 2 = (Private. Car) car 2; This will cause a runtime Class. Cast. Exception: Car cannot be converted to Private. Car 19

Overriding methods n Objects inherit methods from their parent, but may change the methods they inherit. n n Simply redefine them. The keyword super can be used to call methods from the parent class and thus reuse their code. public class Cs. Student extends Person{ private String login; . . . public String get. Name(){ return super. get. Name() + “ “+ login; } } 20

Polymorphism n n n 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 21

Polymorphic use of objects Example: public class Animal(){ public void make. Sound(){ System. out. println(“Default animal sound!”); } // This method is common to all animals: public void eat(Stack<Food> food) { Food to. Eat = food. pop(); //removes food from stack // Here, perform operation of eating the food. . . } } 22

Subclasses of animal. public class Dog extends Animal{ public void make. Sound() { System. out. println("Woof"); } } public class Cat extends Animal{ public void make. Sound() { System. out. println("Meow"); } } public class Bird extends Animal{ public void make. Sound() { System. out. println(“Tweet"); } } 23
![public static void main(String[] args){ Animal[] animals = new Animal[3]; animals[0] = new Dog(); public static void main(String[] args){ Animal[] animals = new Animal[3]; animals[0] = new Dog();](http://slidetodoc.com/presentation_image_h2/e68df6484865deeae5a4e9b508d68446/image-24.jpg)
public static void main(String[] args){ Animal[] animals = new Animal[3]; animals[0] = new Dog(); animals[1] = new Cat(); animals[2] = new Bird(); Stack<Food> food = get. Food(); for(int i=0; i<animals. length; i++){ animals[i]. make. Sound(); animals[i]. eat(food); } } Output: Woof Meow Tweet This last bit of code can treat all kinds of animals. Even those that are not written yet. n 24

Abstract classes & methods n Abstract methods have no implementation. n n n 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 still have constructors. (What for? ) 25

Abstract Animal n When we do not want anyone to create an instance out of some class. We can make it abstract (we can do this even if there are no abstract methods): public abstract class Animal(){ public abstract void make. Sound(); public void eat(Stack<Food> food) {…}; } n We also made make. Sound() abstract. n n Because we want all subclasses to implement it But cannot offer a “default” implementation that is inherited. 26

The Iterator pattern 27

Iterator n n The idea: given a data structure that contains values, we would like to go over all the items currently contained in the structure. Examples: n n Go over all the values of pixels in a 2 D image. Go over all key-value pairs in a Map. 28

Iterator n In order to go over all these values we need 2 main capabilities: n n n To get the ‘next’ value. A way to know if we have more values. The idea: we will create an object that will be used to go over the data structure and will have the 2 capabilities above. 29

Iterator Java has two interfaces: n n For an iterator (in java. util) For data structures that have iterators (in java. lang) public interface Iterator<E> { public E next(); public boolean has. Next(); public void remove(); } public interface Iterable<T> { public Iterator<T> iterator(); } Optional 30

Iterable & “foreach” loops n Any object that implements Iterable<T> can be used in a for-each loop: import java. util. Array. List; import java. util. List; public class Iterable. Example { public static void main(String[] args) { List<String> list = new Array. List<String>(); list. add("Hello!"); The type in the for loop must match list. add("Goodbye!"); the type <T> in the Iterable used. Iterable<String> iterable = list; for(String str : iterable) { System. out. println(str); } } We could also simply write: for(String str : list) { … } } 31

We can write code that fits any data structure: public static boolean is. Inside(Iterator<E> iter, E item){ while(iter. has. Next()){ if (iter. next()==item){ return true; } } return false; } This will work for any iterator, regardless of the data structure it is linked to. No assumptions on data (no sorting, etc. ) => Complexity O(n) 32

Benefits of Iterators n n n Allow to ‘read’ inside an object without revealing its internal structure, and without allowing changes to it (encapsulation). We can write general code for anything that has iterators. We can extend iterators to do more: n n n go back, remove the current item, insert item at current location, etc. 33

Misc. notes 34

Interfaces can extend interfaces n 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 obj 2 = obj; //upcasting A obj 3 = obj; //upcasting 35

Casting and arrays n Arrays can be cast to parent types and back. public static void main(String[] args){ Object[] obj. Arr = new String[5]; Upcasting obj. Arr[0] = "Hi"; obj. Arr[1] = new Object(); // <- causes an Array. Store. Exception at runtime! System. out. println(obj. Arr instanceof String[]); String[] str. Arr = (String[]) obj. Arr; Downcasting System. out. println(str. Arr[0]); } 36

Final classes and methods n n n 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. 37

Static methods are inherited but aren’t polymorphic! public class Parent { public static void only. Parent(){ System. out. println("Parent"); } } public class Child extends Parent { } public static void main(String[] args){ Parent. only. Parent(); Child. only. Parent(); } Output: Parent 38

Static methods are inherited but aren’t polymorphic! public class Parent { public static void both(){ System. out. println("Parent"); } public class Child extends Parent { } public static void both(){ System. out. println(“Child"); } } public static void main(String[] args){ Parent p = new Parent(); Child c 1 = new Child(); Parent c 2 = new Child(); p. both(); c 1. both(); c 2. both(); ((Parent) c 1). both(); } Output: Parent Child Parent 39

Some Constructor Examples public class A { public A(int some. Arg) { System. out. println(“A with arg ” + some. Arg); } public A() { System. out. println(“A”); } } public class B extends A { // no constructor } public class Driver { public static void main(String[] args) { B b = new B(); } } Output: A 40

Some Constructor Examples public class A { public A(int some. Arg) { System. out. println(“A with arg ” + some. Arg); } // no default constructor } public class B extends A { // no constructor } public class Driver { public static void main(String[] args) { B b = new B(); } } Output: Compilation Error 41

Some Constructor Examples public class A { public A(int some. Arg) { System. out. println(“A with arg ” + some. Arg); } public A() { System. out. println(“A”); Output: } A B } public class B extends A { public B() { super(); System. out. println(“B”); } } public class Driver { public static void main(String[] args) { B b = new B(); } } 42

Some Constructor Examples public class A { public A(int some. Arg) { System. out. println(“A with arg ” + some. Arg); } public A() { System. out. println(“A”); Output: A } B } public class B extends A { public B() { System. out. println(“B”); } } public class Driver { public static void main(String[] args) { B b = new B(); } } 43

Some Constructor Examples public class A { public A(int some. Arg) { System. out. println(“A with arg ” + some. Arg); } public A() { System. out. println(“A”); Output: } A with arg 5 } B public class B extends A { public B() { super(5); System. out. println(“B”); } } public class Driver { public static void main(String[] args) { B b = new B(); } } 44

A polymorphism question from exam 45


/** * Merges all objects in the given array in order * * @param objects array of objects to merge in order. * @param merger the merger instance to use. * @return a merged object from the array: the first element in the array is merged with the second; the result of this is merged with the third element, and so on. */ public static Object merge. Array(Object[] objects, Merger merger) { Object obj = objects[0]; for (int i = 1; i < objects. length; ++i) { obj = merger. merge(obj, objects[i]); } return obj; } 47

(' נק 4). ב ומייצגת Resistor ( את הממשק implements) המממשת Simple. Resistor כתבו מחלקה : ( המחלקה צריכה להיות constructor) חתימת בנאי. נגד חשמלי יחיד בעל התנגדות כלשהי public Simple. Resistor(double resistance) /** * A simple resistor. */ public class Simple. Resistor implements Resistor { private double resistance; public Simple. Resistor(double resistance) { this. resistance = resistance; } public double resistance() { return resistance; } } 48


/** * A resistor composed of two resistors. */ public abstract class Compound. Resistor implements Resistor{ protected Resistor resistor 1, resistor 2; public Compound. Resistor(Resistor resistor 1, Resistor resistor 2){ this. resistor 1 = resistor 1; this. resistor 2 = resistor 2; } } 50

//Two resistors connected serially. public class Serial. Resistor extends Compound. Resistor { public Serial. Resistor(Resistor resistor 1, Resistor resistor 2) { super(resistor 1, resistor 2); } public double resistance() { return resistor 1. resistance() + resistor 2. resistance(); } } Notice that this solution may use recursion when computing the resistance! 51

//Two resistors connected in parallel. public class Parallel. Resistor extends Compound. Resistor { public Parallel. Resistor(Resistor resistor 1, Resistor resistor 2) { super(resistor 1, resistor 2); } public double resistance() { double r 1 = resistor 1. resistance(); double r 2 = esistor 2. resistance(); return (r 1 * r 2) / (r 1 + r 2); } } 52

(' נק 6). ה המממשות Serial. Resistor. Merger, Parallel. Resistor. Merger כתבו שתי מחלקות . בהתאמה , וממזגות שני רכיבים בעלי התנגדות ע"י חיבורם בטור או במקביל Merger את הממשק במחלקות הנ"ל מועברים כפרמטרים אובייקטים המממשים merge מותר להניח שבכל קריאה לשיטה . Resistor את הממשק public class Serial. Resistor. Merger implements Merger { public Object merge(Object obj 1, Object obj 2) { return new Serial. Resistor((Resistor) obj 1, (Resistor) obj 2); } } public class Parallel. Resistor. Merger implements Merger { public Object merge(Object obj 1, Object obj 2) { return new Parallel. Resistor((Resistor) obj 1, (Resistor) obj 2); } } 53

(' נק 6). ו : כתבו שתי שיטות סטטיות המחברות מערך של רכיבים בעלי התנגדות בטור או במקביל public static Resistor connect. Series(Resistor[] resistors) public static Resistor connect. Parallel(Resistor[] resistors). ' על השיטות הנ"ל להשתמש בשיטה שכתבתם בסעיף א public static Resistor connect. Series( Resistor[] resistors) { return (Resistor) merge. Array(resistors, new Serial. Resistor. Merger()); } public static Resistor connect. Parallel( Resistor[] resistors) { return (Resistor) merge. Array(resistors, new Parallel. Resistor. Merger()); } 54
![: להלן דוגמה לקטע תוכנית המשתמש בשיטות הנ"ל Simple. Resistor[] r 1 = {new : להלן דוגמה לקטע תוכנית המשתמש בשיטות הנ"ל Simple. Resistor[] r 1 = {new](http://slidetodoc.com/presentation_image_h2/e68df6484865deeae5a4e9b508d68446/image-55.jpg)
: להלן דוגמה לקטע תוכנית המשתמש בשיטות הנ"ל Simple. Resistor[] r 1 = {new Simple. Resistor(2. 0), new Simple. Resistor(6. 0)}; Simple. Resistor[] r 2 = {new Simple. Resistor(3. 0), new Simple. Resistor(1. 0), new Simple. Resistor(2. 0)}; System. out. println(connect. Parallel(r 1). resistance()); System. out. println(connect. Series(r 2). resistance()); : הפלט של קטע זה הוא 1. 5 6. 0 55
- Slides: 55