Lesson 3 Java and O-O Programming /Methods, Classes, Inheritance, Polymorphism, Interfaces/ AUBG ICoSCIS Team Assoc. Prof. Stoyan Bonev March, 23 - 24, 2013 SWU, Blagoevgrad Lesson Contents: Structured Programming – theory & practice OOP – theory & practice Java methods Java classes Inheritance Polymorphism Abstract classes and Interfaces 2 Structured Programming – theory Structured programming: A technique for organizing and coding computer programs in which a hierarchy of modules is used, each having a single entry point and a single exit point, and in which control is passed downward through the structure without unconditional branches to higher levels of the structure. Dividing a program into functions and modules . Thinking in Functions! Basic building construct – member function or 3 method OOP – theory Data Encapsulation & Data Hiding: Data and its functions are said to be encapsulated into a single entity Inheritance: The process of creating new classes or derived classes from existing classes or base classes. Inheritance as “is a kind of” relation btw classes. Polymorphism: Ability to redefine methods for derived classes. Giving different meaning to the same thing. Dividing a program into classes and objects . Thinking in Classes! Basic building construct – classes and objects 4 StrProg – problem to solve To develop – arithmetic operators processor A routine for each arithmetic operator is must Addition: int add(int p1, int p2) { return p1+p2;} Expand it with routines for all arithmetic operators: +, -, *, /, %, ^ Solution looks like this: public class StructProgArithCalc { public int add(int pa, int pb) { return pa + pb; } public static void main(String[] args) { System.out.println(" " + add(55, 66)); } } 5 OOP – problem to solve To develop – arithmetic operators processor A separate individual class with methods for each arithmetic operator is must Java, file OOPArithCalc.java package ooparithcalcjava; class ArithCalc { public int add(int pa, int pb) { return pa + pb; } } public class OOPArithCalc { public static void main(String[] args) { ArithCalc myCalc = new ArithCalc(); System.out.println(" " + myCalc.add(55, 66)); } } 6 OOP – problem to solve Build your own arithmetic operators processor. Expand it with methods for all arithmetic operators: +, -, *, /, %, ^ Name file as OOPArithCalc.java 7 More on Java syntax Methods or member functions Predefined and User defined methods 8 Predefined Methods Methods already written and provided by JRE Organized as a collection of classes (class libraries) To use: import <package>; Illustration: Math class, String class Java Programming: From Problem Analysis to Program Design, 9 4e 9 Predefined methods 10 Predefined Classes (continued) Java Programming: From Problem Analysis to Program Design, 11 4e 11 Predefined Classes (continued) Java Programming: From Problem Analysis to Program Design, 12 4e 12 Predefined Classes (continued) Java Programming: From Problem Analysis to Program Design, 13 4e 13 Some Commonly Used String Methods Java Programming: From Problem Analysis to Program Design, 14 4e 14 Some Commonly Used String Methods (continued) Java Programming: From Problem Analysis to Program Design, 15 4e 15 Some Commonly Used String Methods (continued) Java Programming: From Problem Analysis to Program Design, 16 4e 16 Some Commonly Used String Methods (continued) Java Programming: From Problem Analysis to Program Design, 17 4e 17 Some Commonly Used String Methods (continued) Java Programming: From Problem Analysis to Program Design, 18 4e 18 User-Defined Methods User-defined methods in Java are classified in two categories: Value-returning methods Methods have a return data type Methods return a value of specific data type using return statement Used in expressions, Calculate and return a value Can save value for later calculation or print value Void methods Methods that do not have a return data type Methods do not use return statement to return a value Java Programming: From Problem Analysis to Program Design, 19 4e 19 Opening Problem Find the sum of integers from 1 to 10, from 20 to 30, and from 35 to 45, respectively. int sum = 0; for (int i = 1; i <= 10; i++) sum += i; System.out.println("Sum from 1 to 10 is " + sum); sum = 0; for (int i = 20; i <= 30; i++) sum += i; System.out.println("Sum from 20 to 30 is " + sum); sum = 0; for (int i = 35; i <= 45; i++) sum += i; System.out.println("Sum from20 35 to 45 is " + sum); Solution public static int sum(int i1, int i2) { int sum = 0; for (int i = i1; i <= i2; i++) sum += i; return sum; } public static void main(String[] args) { System.out.println("Sum from 1 to 10 is " + sum(1, 10)); System.out.println("Sum from 20 to 30 is " + sum(20, 30)); System.out.println("Sum from 35 to 45 is " + sum(35, 45)); } 21 Creating/Defining Methods A method is a collection of statements that are grouped together to perform an operation. Define a method modifier method header return value type Invoke a method method name formal parameters int z = max(x, y); public static int max(int num1, int num2) { actual parameters (arguments) int result; method body if (num1 > num2) result = num1; else result = num2; return result; parameter list method signature return value } 22 Calling Methods •In creating a method, you give a definition of what the method is expected to do. •To use a method, you have to call it, or invoke it, or activate it in two ways depending on the method category: •As a value, (i.e. operand of an expression) Larger = max(20, 50); System.out.println(“Result is=“, max(20,50)); •As a statement System.out.println(“JAVA”); 23 Calling Methods, cont. pass the value of i pass the value of j public static void main(String[] args) { int i = 5; int j = 2; int k = max(i, j); public static int max(int num1, int num2) { int result; if (num1 > num2) result = num1; else result = num2; System.out.println( "The maximum between " + i + " and " + j + " is " + k); } return result; } 24 void method example This type of method does not return a value. The method performs some actions. public static void nPrintln(String message, int n) { for (int i = 0; i < n; i++) System.out.println(message); } Suppose you invoke the method using nPrintln(“Welcome to Java”, 5); What is the output? Suppose you invoke the method using nPrintln(“Computer Science”, 15); What is the output? 25 Passing parameters by Values When calling a method, the argument value is passed /copied/ to the formal parameter. The argument is not affected, regardless of the changes made to the parameter inside the method. 26 Overloading Methods Overloading the max Method public static double max(int num1, int num2) { if (num1 > num2) return num1; else return num2; } public static double max(double num1, double num2){ if (num1 > num2) return num1; else return num2; } 27 Arrays and Methods Passing Arrays to methods Through parameter passing mechanism by value Returning an Array from a Method Through return stmt 28 Arrays and Methods public static int[] arrayProcess(int[] par) { int j; int[] b = new int[par.length]; for (j=1; j<par.length; j++) b[j] = par[j] *10; return b; } Do you have any critical remark on the source text? 29 Arrays and Methods public static void main(String[] args) { int[] ar = new int[10]; for (i=0; i < ar.length; i++) ar[i] = i; int[] br; br = arrayProcess(ar); for (i=0; i < br.length; i++) System.out.print(br[i] + " "); } // end of main 30 Pass By Value Java uses pass by value to pass arguments to a method. There are important differences between passing a value of variables of primitive data types and passing arrays. For a parameter of a primitive type value, the actual value is passed. Changing the value of the local parameter inside the method does not affect the value of the variable outside the method. For a parameter of an array type, the value of the parameter contains a reference to an array; this reference is passed to the method. Any changes to the array that occur inside the method body will affect the original array that was passed as the argument. 4/13/2015 31 Stoyan Assoc. Prof. Bonev Simple Example public class Test { public static void main(String[] args) { int x = 1; // x represents an int value int[] y = new int[10]; // y is an array of int values m(x, y); // Invoke m with arguments x and y System.out.println("x is " + x); System.out.println("y[0] is " + y[0]); } // end of main public static void m(int number, int[] numbers) { number = 1001; // Assign a new value to number numbers[0] = 5555; //Assign new value to numbers[0] } // end of m } // end of class Test 4/13/2015 32 Stoyan Assoc. Prof. Bonev Exercise on methods Expand the program Methods1.java adding more methods that reside in the same class with method main(): Iterative GCD – gcdi() Iterative/Recursive factorial – facti(), factr() Iterative/Recursive Fibonacci – fiboi(), fibor() Iterative/Recursive Sum(1..n) – sumi(), sumr() Iterative/Recursive Power operator simulator – powi(), powr() Write a program to demonstrate the effect of passing by value. (method swap) 33 Exercises Palindrome: string that reads the same forwards and backwards Write a value-returning method isPalindrome(), that returns true if a given string is palindrome, i.e. it reads the same way forwards and backwards. The method isPalindrome() takes a string as a parameter and returns true if the string is a palindrome, false otherwise Write a Java program to test the method 34 Solution: isPalindrome() Method public static boolean isPalindrome(String str){ int len = str.length(); int i, j = len - 1; for (i = 0; i <= (len - 1) / 2; i++) { if (str.charAt(i) != str.charAt(j)) return false; j--; } return true; } Java Programming: From Problem Analysis to Program Design, 35 4e 35 Rewrite isPalindrome() Method using while loop stmt public static boolean isPalindrome(String str){ int len = str.length(); int i, j; j = len - 1; while (i <= (len - 1) / 2) { if (str.charAt(i) != str.charAt(j)) return false; i++; j--; } return true; } Java Programming: From Problem Analysis to Program Design, 36 4e 36 Exercises Write a value-returning method isVowel(), that returns true if a given character is vowel, and otherwise returns false. Write a Java program to test the method Write a Java program to output the number of vowels in a string. 37 The int variable num contains the desired sum to be rolled Java Programming: From Problem Analysis to Program Design, 38 4e 38 Moore on Java syntax Classes and Objects 39 Anatomy of a Class Classes defined inside packages Classes group: Data members Member functions /methods/ All programs consist of at least one class that includes at least one method main() Every class is named C# Programming: From Problem Analysis to Program Design 40 Class Definition • Building block or basic encapsulation constructs of Java object-oriented program. • Every executable statement must be placed inside a method and every method must be placed inside a class. • Classes define a category, or type, of object. • Classes define reference types that are the basic building blocks of Java programs, and they serve as ADT to create objects in OOP C# Programming: From Problem Analysis to Program Design 41 Defining Classes for Objects An object has both a state and behavior. •The state defines the object. •The behavior defines what the object does. Data fields define state and methods define behaviors. Additionally, a class provides special type of methods, known as constructors, invoked to construct objects from the class. Example: •A Circle object has a data field, i.e. radius which is the property to characterize a circle. •One behavior of a circle is that42its area can be computed using the method getArea() Classes class Circle { /** The radius of this circle */ double radius = 1.0; /** Construct a circle object */ Circle() { } Data field Constructors /** Construct a circle object */ Circle(double newRadius) { radius = newRadius; } /** Return the area of this circle */ double getArea() { return radius * radius * 3.14159; } } 43 Method Constructors Constructors are a special kind of methods that are invoked to construct objects. A constructor with no parameters is referred to as a no-arg constructor. Circle() { radius = 0.0; } //---------------------------Circle(double newRadius) { radius = newRadius; } 44 Constructors Constructors are a special kind of methods that are invoked to construct objects. A constructor with no parameters is referred to as a no-arg constructor. Circle() { radius = 0.0; } //---------------------------Circle(double radius) { this.radius = radius; } 45 Constructor-method with three differences · Constructors must have the same name as the class itself. · Constructors do not have a return type—not even void. · Constructors are invoked using the new operator when an object is created. Constructors play the role of initializing objects. 46 Default Constructor A class may be declared without constructors. In this case, a no-arg constructor with an empty body is implicitly declared in the class. This constructor, called a default constructor, is provided automatically only if no constructors are explicitly declared in the class. 47 Creating Objects Using Constructors Syntax: new ClassName(); Example: To create anonymous objects new Circle() new Circle(5.0) 48 Declaring Object Reference Variables To reference an object, assign the object (being created using new operator) to a reference variable. To declare a reference variable, use the syntax: ClassName objectRefVar; Example: Circle myCircle; 49 Declaring/Creating Objects in a two Steps Circle myCircle; myCircle = new Circle(); 50 Declaring/Creating Objects in a Single Step ClassName objectRefVar = new ClassName(); Example: Assign object reference Circle myCircle = Create an object new Circle(); 51 Accessing Objects Referencing the object’s data: objectRefVar.data e.g., myCircle.radius Invoking the object’s method: objectRefVar.methodName(arguments) e.g., myCircle.getArea() 52 Practical problem Write a Java program that constructs an object with radius 5 and an object with radius 10 and display the radius and area of each of the two circles. Change the radius of the second object to 100 and display the new radius and area. Add a new method to return the circumference of the circle. Hints: read next slide 53 Hints Version 1, project Circle1: One .java source file, one class Circle with methods: • two constructors, • method getArea() • method main(). See attached file Circle1.java Version 2, project Circle2: One .java file, two classes: • Circle with methods: two constructors and method getArea() • TestCircle with method main() only See attached file Circle2.java Version 3, project Circle3: Two classes Circle and TestCircle, as in version 2 Each class saved in a separate file, but in the same package 54 The null Value If a data field of a reference type does not reference any object, the data field holds a special literal value, null. 55 Default Value for a Data Field The default value of a data field is: null for a reference type, 0 for a numeric type, false for a boolean type, and '\u0000' for a char type. However, Java assigns no default value to a local variable inside a method (see next slide). public class Test { public static void main(String[] args) { Student student = new Student(); System.out.println("name? " + student.name); System.out.println("age? " + student.age); System.out.println("isScienceMajor? " + student.isScienceMajor); System.out.println("gender? " + student.gender); } 56 } Example Java assigns no default value to a local variable inside a method. public class Test { public static void main(String[] args) { int x; // x has no default value String y; // y has no default value System.out.println("x is " + x); System.out.println("y is " + y); } } Compilation error: variables not initialized 57 Differences between Variables of Primitive Data Types and Object Types int i = 1; Circle c = new Circle(1); Created using new Circle() Primitive type int i = 1 i 1 Object type Circle c c reference c: Circle radius = 1 58 Example of Using Instance and Class Variables and Method Objective: Demonstrate the roles of instance and class variables and their uses. Task: Modify the Circle program by adding a class variable numberOfObjects to track the number of Circle objects created. 59 Visibility modifiers private: private members are accessible only in the class itself package: package members are accessible in classes in the same package and the class itself (by default) protected: protected members are accessible in classes in the same package, in subclasses of the class, and in the class itself public: public members are accessible anywhere the class is accessible 60 Pencil public class Pencil { public String color = “red”; public int length; public float diameter; private float price; public static long nextID = 0; public void setPrice (float newPrice) { price = newPrice; } } CreatePencil public class CreatePencil { public static void main (String args[]){ Pencil p1 = new Pencil(); p1.price = 0.5; // illegal } } 61 Visibility Modifiers and Accessor/Mutator Methods By default, the class, variable, or method can be accessed by any class in the same package. public The class, data, or method is visible to any class in any package. private The data or methods can be accessed only by the declaring class. The get and set methods are used to read and modify private properties. 62 Accessor/Mutator Methods Coloquially, a get method is referred to as a getter (or accessor) a set method is referred to as a setter (or mutator) A get method has following signature: public returntype getPropertyName() If return type is boolean, get method is like: public boolean isPropertyName() A set method has following signature: public void setPropertyName(dataType propertyValue) 63 More on OOP syntax - Java class Book { private String m_Author; public Book() { m_Author = " ";} public Book(String pb) { m_Author = pb; } // method accessor public String getAuthor() { return m_Author; // methods mutators public void setAuthor(String pb) { } m_Author = pb; } } // end of class Book 64 Accessor/Mutator Methods See file ModernObjectProg1.java Modify the Circle class with get /accessor/ method and set /mutator or mutators/ method(s) associated to the rad data field for the radius of the circle. 65 Passing Objects to Methods Passing by value for primitive type value (the value is passed to the parameter) Passing by value for reference type value (the value is the reference to the object) 66 The this Reference Need to reference a class’s hidden variable in a method. A property name is used as a parameter in a set method for the property Hidden static variable is accessed using class name reference Hidden instance variable is accessed using keyword this class Foo { int i= 5; static double k=0; void setI(int i) { this.i = i; } void setK(double k) { Foo.k = k; } } 67 The this Reference Keyword this can also use inside a constructor to invoke another constructor of the same class. public class Circle { private double radius; public Circle (double radius) { this.radius = radius; } public Circle() this(1.0); } { public getArea() { return this.radius * this.radius * Math.PI; } } // this(1.0) has to appear first in the constructor before any other statements. 68 Array of Objects Circle[] circleArray = new Circle[10]; An array of objects is actually an array of reference variables. So invoking circleArray[1].getArea() involves two levels of referencing as shown in the figure. circleArray references to the entire array. circleArray[1] references to a Circle object. circleArray reference circleArray[0] circleArray[1] Circle object 0 … Circle object 1 69 circleArray[9] Circle object 9 Practical session Reminder: Program Methods1.java includes class Methods1 with methods main() and gcdr() public class Methods1 { public static void main(String[] args) … gcdr(a, b)); } static int gcdr(int m, int n) { … } } // end of class Methods1 C# Programming: From Problem Analysis to Program Design { 70 Practical session Reorganize Methods1.java program to Methods2.java like this: the same method gcdr() appears in three classes public class Methods2 { public static void main(String[] args) static int gcdr(int m, int n) { … } } class Arithmetic1 { public static int gcdr() { … } } class Arithmetic2 { public int gcdr() { … } } C# Programming: From Problem Analysis to Program Design {… } 71 Practical session Analyze the syntax correctness of the main() method public class Methods2 { public static void main(String[] args) { int a, b; Arithmetic2 ar = new Arithmetic2(); Methods2 pr = new Methods2(); a = 24; b = 15; System.out.print(" " + gcdr(a, b)); System.out.print(" " + Methods2.gcdr(a, b)); System.out.print(" " + pr.gcdr(a, b)); a = 20; b = 15; System.out.println(" " + Arithmetic1.gcdr(a, b)); a =17; b = 15; System.out.println(" " + ar.gcdr(a, b)); } static int gcdr(int m, int n) { if (n == 0) return m; else return gcdr(n, m % n); C#}Programming: From Problem Analysis to Program Design } // end of class Methods2 72 Practical session Analyze the syntax correctness of the main() method class Arithmetic1 { public static int gcdr(int m, int n) { if (n == 0) return m; else return gcdr(n, m % n); } } // end of class Arithmetic1 class Arithmetic2 { public static int gcdr(int m, int n) { if (n == 0) return m; else return gcdr(n, m % n); } } // end of class Arithmetic2 C# Programming: From Problem Analysis to Program Design 73 Recap: a static data variable is one whose value is shared by all class instances – true for Java and C#. There is only one occurrence of it. The static data member is associated with the class, rather than with each instance. A static method allows us to use that method from a class without first instantiating an object of the class - true for Java and C#. The main()/Main() methods of Java and C# are static methods – the main()/Main() methods can be used without first instantiating any objects of the class. C# may have a static constructor. Java uses a static initialization block (initializer). 74 Practical session – digression on C# Program Methods2.cs: same method gcdr() appears in three classes namespace Methods2 { class Program { Method static void Main() { … } Method static int gcdr() { … } } class Arithmetic1 { Method public static int gcdr() { … } } class Arithmetic2 { } } Method public int gcdr() { … } C# Programming: From Problem Analysis to Program Design 75 Practical session - digression on C# Analyze the syntax correctness of the Main() method static void Main(string[] args) { int a, b; Arithmetic2 ar = new Arithmetic2(); Program pr = new Program(); a = 24; b = 15; Console.WriteLine("\n“+Program.gcdr(a, b)+" "+gcdr(a, b)); Console.WriteLine("\n“+pr.gcdr(a, b)); a = 20; b = 15; Console.WriteLine("\n\n" + Arithmetic1.gcdr(a, b)); a = 17; b = 15; Console.WriteLine("\n\n" + ar.gcdr(a, b)); C# Programming: From Problem Analysis to Program Design } 76 Practical session Expand the reorganized program Methods2.java adding more methods that reside in the same class with method main() and in classes Arithmetic1 and Arithmetic2: Iterative GCD – gcdi() Iterative/Recursive factorial – facti(), factr() Iterative/Recursive Fibonacci – fiboi(), fibor() Iterative/Recursive Sum(1..n) – sumi(), sumr() Iterative/Recursive Power operator simulator – powi(), powr() C# Programming: From Problem Analysis to Program Design 77 Practical Tasks Develop class Counter Data field: count Constructors Getter method Setter method Method: incCount C# Programming: From Problem Analysis to Program Design 78 Practical session Problem: Write a program to develop ADT Counter class: Data field: int m_count Methods: no-arg constructor 1-arg constructor void incCount() get method /accessor/ set method /mutator/ 79 Practical session IDE NetBeans: Project name: Counter1 – user specified IDE generates: package name counter1 class name Counter1 Class includes ADT functionality + tester method main(…) 80 Practical session IDE NetBeans: Project name: Counter2 – user specified IDE generates: package name counter2 class name Counter2 (main class) To add new class: File > New File > Choose category: Java, File type : Java class Name: Counter 81 Practical Tasks Develop class Distance Data fields: feet, inches Constructors Getter methods Setter methods C# Programming: From Problem Analysis to Program Design 82 More on Java syntax Inheritance 83 More on OOP syntax - Java class Counter // file OOPInheritanceCounter.java { protected int count; public Counter() { count = 0; } public Counter(int pa) { count = pa; } public void IncCount() { count = count + 1; } public void setCount(int pa) { count = pa; } public int getCount() { return count; } } class CountDn extends Counter { public void DecCount() { count = count - 1; } } 84 Motivations Suppose you will define classes to model: students, instructors, professors. You can build a separate independent class for each one of the listed categories. BUT: These classes have many common features. What is the best way to design these classes so to avoid redundancy? The answer is to use inheritance. 85 Motivations Suppose you will define classes to model circles, rectangles, triangles. You can build a separate independent class for each one of the listed categories (2D geometric figures). BUT: These classes have many common features. What is the best way to design these classes so to avoid redundancy? The answer is to use inheritance. 86 Brief presentation 87 Inheritance A class can inherit properties and methods from another class, called its parent. In Java, this is called extending a class. The class doing the extending is the childor sub-class. The class getting extended is the parent or super-class. 88 Inheritance In Java, a class can only extend one parent. You can also: Add new properties/attributes/data fields Add new methods Override the methods of the super-class Classes are arranged in a treelike hierarchy. There is one class at the top, or root, of the hierarchy, named Object Every class except Object has one “parent” class, or super-class single inheritance. 89 Inheritance Example Parent public class Person { protected String name; Child public class Student extends Person { private double accountBalance; public void setName(String name) { this.name = name; } } public String getName() { return name; } Here is the extends keyword, signaling inheritance public void increaseBalance(double amount) { this.accountBalance += amount; } } public double getAccountBalance() { return accountBalance; } 90 Constructors in extended classes • A constructor of the extended class can invoke one of the superclass’s constructors by using the super method in Java. • If no superclass constructor is invoked explicitly, then the superclass’s default constructor is invoked automatically by the runtime system as the first statement of the extended class’s constructor. • FYI: in C#, the base method is used, not super. • In both C# and Java, may use base/super to invoke any overridden method in the parent class. E.g. super.ParentMethod(); 91 Superclass Subclass public class Person{ protected String name; public class Student extends Person { private int studentNumber; public Person() { name = “no_name_yet”; } public Student() { super(); // superclass studentNumber = 0; } public Person(String initialName) { this.name = initialName; } public Student(String initialName, int initialStudentNumber) { super(initialName); public String getName() { return name; } studentNumber = initialStudentNumber; } public void setName(String newName){ name = newName; } public int getStudentNumber() { return studentNumber; } public void setStudentNumber(int newStudentNumber ) { studentNumber = newStudentNumber; } 92 Comprehensive presentation 93 Superclasses and Subclasses Geometric objects: circles and rectangles Common properties: Color, filled/nofilled, dateCreated Circle – specific properties: radius Rectangle – specific properties: width, height 94 Superclasses and Subclasses GeometricObject -color: String The color of the object (default: white). -filled: boolean Indicates whether the object is filled with a color (default: false). -dateCreated: java.util.Date The date when the object was created. +GeometricObject() Creates a GeometricObject. +GeometricObject(color: String, filled: boolean) Creates a GeometricObject with the specified color and filled values. +getColor(): String Returns the color. +setColor(color: String): void Sets a new color. +isFilled(): boolean Returns the filled property. +setFilled(filled: boolean): void Sets a new filled property. +getDateCreated(): java.util.Date Returns the dateCreated. +toString(): String Returns a string representation of this object. Rectangle Circle -radius: double -width: double +Circle() -height: double +Circle(radius: double) +Rectangle() +Circle(radius: double, color: String, filled: boolean) +Rectangle(width: double, height: double) +getRadius(): double +Rectangle(width: double, height: double color: String, filled: boolean) +setRadius(radius: double): void +getWidth(): double +getArea(): double +setWidth(width: double): void +getPerimeter(): double +getHeight(): double +getDiameter(): double +setHeight(height: double): void +printCircle(): void 95 +getArea(): double +getPerimeter(): double Superclasses and Subclasses Inheritance illustrated as skeletal Java source class GeometricObject { … } class Circle extends GeometricObject { … } class Rectangle extends GeometricObject { … } public class TestProgram { public static void main(…) { … } … 96 } class GeometricObject Inheritance illustrated as skeletal Java source See detailed source text in file ProgGeometricObject.java 97 Task 1 Write a Java program to illustrate the inheritance relation among classes Circle and Cylinder Super class: Circle Sub class: Cylinder “is-a” relation: Cylinder is-a Circle Hint: Follow the style and ideology of Java program ProgGeometricObject.java 98 Are superclass’s Constructor Inherited? No. They are not inherited. They can not be invoked by name. They are invoked implicitly or may be invoked explicitly using the super keyword. A constructor is used to construct an instance of a class. Unlike properties and methods, superclass's constructors are not inherited in the subclass. They can only be invoked from the subclasses' constructors, using the keyword super. If the keyword super is not explicitly used, the superclass's noarg constructor is automatically implicitly invoked. 99 Superclass’s Constructor Is Always Invoked A constructor may invoke an overloaded constructor (using this) or its superclass’s constructor (using super). If none of them is invoked explicitly, the compiler puts super() as the first statement in the constructor. For example, public A() { } public A(double d) { // some statements } public A() { super(); } is equivalent to is equivalent to public A(double d) { super(); // some statements } 100 Using the Keyword super • Keyword this used to refer to the calling object. • Keyword super refers to the superclass of the class in which super appears. This keyword can be used in two ways: To call a superclass constructor super(); super(arguments); To call a superclass method super.method(arguments); 101 Example 3-arg constructor of Circle class: public Circle(double radius, String color, boolean filled) { setColor(color); setFilled(filled); this.radius = radius; } Can be replaced with: public Circle(double radius, String color, boolean filled) { super(color, filled); this.radius = radius; } 102 Constructor chaining File SonFatherGrandFather.java Given the class hierarchy: Class GrandGrandFather – super class ↑ Class GrandFather – sub class and super class ↑ Class Father – sub class and super class ↑ Class Son – sub sub sub class 103 Constructor chaining File Faculty.java. Given the class hierarchy: Class Person – super class ↑ Class Employee – sub class and super class ↑ Class Faculty – sub sub class 104 Overriding Members You can override (most) methods in a parent class by defining a method with the same name and the same parameter list in the child class. This is useful for changing the behavior of a class without changing its interface. 105 Example of Overriding Here we override to change method getIdentifier() public class Person { private String name; private String ssn; } public class Student extends Person { private String studentId; private double accountBalance; public void setName(String name) { this.name = name; } public void increaseBalance(double amount) { this.accountBalance += amount; } public String getName() { return name; } public double getAccountBalance() { return accountBalance; } public String getIdentifier() { return ssn; } public String getIdentifier() { // override return studentId; // use student id instead of ssn } } 106 Overriding vs. Overloading public class Test { public static void main(String[] args) { A a = new A(); a.p(10); a.p(10.0); } } public class Test { public static void main(String[] args) { A a = new A(); a.p(10); a.p(10.0); } } class B { public void p(double i) { System.out.println(i * 2); } } class B { public void p(double i) { System.out.println(i * 2); } } class A extends B { // This method overrides the method in B public void p(double i) { System.out.println(i); } } class A extends B { // This method overloads the method in B public void p(int i) { System.out.println(i); } } 107 Overriding vs. Overloading Overloading methods in base class and derived class Base class and derived class have method with Same name Different type and/or number of parameters Test Java Program TestOverLoad.java 108 Overriding vs. Overloading // file TestOverload.java class B { public void p(int par) { System.out.println(" Base class method } } " + par*2 ); class A extends B { public void p(double par) { // this method overloads base class method p() System.out.println(" Child class method " + par); } } public class TestOverLoad { public static void main(String[] args) { A a = new A(); a.p(10); a.p(10.0); } } 109 Overriding vs. Overloading Overriding methods in base class and derived class Base class and derived class have method with Same name Same type and/or number of parameters Test Java Program TestOverRide.java 110 Overriding vs. Overloading // file TestOverRide.java class B { public void p(double par) { System.out.println(" Base class method " + par*2 ); } } class A extends B { public void p(double par) { // this method overrides base class method p() System.out.println(" Child class method " + par); //super.p(10); //super.p(10.0); } } public class TestOverRide { public static void main(String[] args) { A a = new A(); a.p(10); a.p(10.0); } 111 } The Object Class and Its Methods Every class in Java is descended from the java.lang.Object class. If no inheritance is specified when a class is defined, the superclass of the class is Object. public class Circle { ... } public class Circle extends Object { ... } Equivalent 112 The Object class It is important to be familiar with methods provided by the Object class so that you can use them in your classes. Some of these methods are: public boolean equals(Object object) public int hashCode() public String toString() 113 The toString() method in Object The toString() method returns a string representation of the object. The default implementation returns a string consisting of a class name of which the object is an instance, the at sign (@), and a number representing this object. Circle circle = new Circle(); System.out.println(circle.toString()); Circle@15037e5 The code displays something like . This message is not very helpful or informative. Usually you should override the toString method so that it returns a digestible string representation of the object. 114 More on Java syntax Polymorphism 115 More on OOP syntax - Java // file OOPPolymorphism.java class Base { public void Show() { System.out.println( "\n Base:");} }; class Derived1 extends Base { public void Show() { System.out.println( "\n Derived1:");} }; class Derived2 extends Base { public void Show() { System.out.println( "\n Derived2:");} }; public class OOPPolymorhismJava { public static void main(String[] args) { Base ptr = new Base(); ptr.Show(); ptr = new Derived1(); ptr.Show(); ptr = new Derived2(); ptr.Show(); } } 116 Motivations It is a challenge from one side but gives power and flexibility if you are able to perform different tasks using the same calling statement. What is the way to achieve that effect? The answer is to apply POLYMORPHISM. How to interpret the term POLYMORPHISM? Polymorphism (from Greek meaning “many forms” )= = Giving different meaning to the same thing = Variable of a super type can refer to a subtype object In assignment statement or Through parameter passing mechanism 117 Polymorphism Inheritance is a relation that enables a sub class to inherit features from its superclass with additional new features. A subclass is a specialized form of its superclass. Every instance of a sub class is an instance of a superclass BUT not vice versa. Example: Every circle is a geometric object, BUT not every geometric object is a circle. !!! You can always assign an instance of a subclass to a reference variable of its superclass type. !!! You can always pass an actual argument /instance of a subclass type/ to meet corresponding formal parameter /instance of its superclass type/. 118 Consider code in Java // source text file: ProgBaseDerv1Derv2.java given inheritance hierarchy Object | Base / \ Derived1 Derived2 Classes Base, Derived1, Derived2 provide method toString() and method show() 119 Consider code in Java class Base { public void show() { System.out.println("Base " );} public String toString() { return "\n\nBase"; } } // end of class Base class Derived1 extends Base { public void show() { System.out.println("Derived1" );} public String toString() { return "\n\nDerived1"; } } // end of class Derived1 class Derived2 extends Base { public void show() { System.out.println("Derived2" );} public String toString() { return "\n\nDerived2"; } } // end of class Derived2 120 Consider code in Java // source text file: ProgBaseDerv1Derv2.java public class ProgBaseDerv1Derv2 { public static void main(String[] args) { Object o = new Object(); System.out.println(" Base a = new Base(); a.show(); System.out.println(" " + o.toString()); " + a.toString()); Derived1 b = new Derived1(), cir1 = new Derived1(); System.out.println(" " + b.toString()); b.show(); Derived2 c = new Derived2(), rect1 = new Derived2(); System.out.println(" " + c.toString()); c.show(); Object[ ] arr = new Object[4]; arr[0] = o; arr[1] = a; arr[2] = b; arr[3] = c; for(int i=0; i<4; i++) System.out.println( arr[i].toString()); // o is named polymorphic variable o=a; o=b; o=c; a=b; a=c; } // end of method main() } // end of class ProgBaseDerv1Derv2 121 Comments Ref variable o is Object type. Array ref variable arr is Object type. We can assign any instance of Object ((eg. New Base, new Derived1, or new Derived2 to o or to arr array element GEN RULE: An object of a subtype can be used wherever its supertype value is required or in other words a ref var of a super class type can point to an object of its sub class type. This feature is known as polymorphism. 122 Consider code in Java // source text file: ProgPolymorphismDemo.java given inheritance hierarchy Object | GeometricObject / \ Circle Rectangle 123 Consider code in Java // source text file: ProgpolymorphismDemo.java public static void main(String args[]) { displayObject(new Circle(1, "red", false)); displayObject(new Rectangle(1, 1, "blue", true)); Circle aa = new Circle(1, "red", false); displayObject(aa); Rectangle bb = new Rectangle(1, 1, "blue", true); displayObject(bb); } // end of main public static void displayObject( GeometricObject o) { System.out.println("Created:"+o.getDateCreated()+" color:"+o.getColor()+" Filled:"+o.isFilled()); // or System.out.println("Created:"+o.dateCreated+" color:"+o.color+" Filled:"+o.filled); } 124 Comments The formal param is GeometricObject o. The actual argument may be any instance of GeometricObject (eg. New Circle or new Rectangle) GEN RULE: An object of a subtype can be used wherever its supertype value is required or in other words a ref var of a super class type (formal param) can point to an object of its sub class type (actual arg). This feature is known as polymorphism. 125 Dynamic Binding // file: ProgGeometricObject3.java Object o = new GeometricObject(); System.out.println(o.toString()); Object aa = new Circle(1); System.out.println(aa.toString()); Q. Which toString() method is invoked by o and by aa? Before answer, let introduce two terms: declared type actual type 126 Dynamic Binding Object o = new GeometricObject(); A variable must be declared a type. The type of a variable is called its declared type. o’s declared type is Object. The actual type is the actual class for the object referenced by the variable o’s actual type is GeometricObject Which toString() method is invoked by o is determined by o’s actual type. This is known as dynamic binding 127 Dynamic Binding Given a hierarchy of classes: C1, C2, ..., Cn-1, Cn, where C1 is a subclass of C2, C2 is a subclass of C3, ..., Cn-1 is a subclass of Cn. That is, Cn is the most general class, and C1 is the most specific class. In Java, Cn is the Object class. Dynamic binding works as follows: Suppose an object o is an instance of class C1. If o invokes a method p, the JVM searches the implementation for the method p in C1, C2, ..., Cn-1 and Cn, in this order, until it is found. Once an implementation is found, the search stops and the first-found implementation is invoked. Cn Cn-1 ..... C2 C1 Since o is an instance of C1, o is also an instance of C2, C3, …, Cn-1, and Cn Object 128 class Person extends Object { public String toString() { return "Person"; } } class Student extends Person { public String toString() { return "Student"; } } class GraduateStudent extends Student { } Program output is: Can you analyze? What is the expected result? public class PolymorphismDemo { public static void main(String[] args) { m(new GraduateStudent()); m(new Student()); m(new Person()); m(new Object()); } public static void m(Object x) { System.out.println(x.toString()); } 129 } class Person extends Object { public String toString() { return "Person"; } } class Student extends Person { public String toString() { return "Student"; } } class GraduateStudent extends Student { } public class PolymorphismDemo { public static void main(String[] args) { m(new GraduateStudent()); m(new Student()); m(new Person()); m(new Object()); } public static void m(Object x) { System.out.println(x.toString()); } 130 } Program output is: Student Student Person Java.lang.Object@16f0472 Method Matching vs. Binding Matching a method signature and binding a method implementation are two separate issues. The compiler finds a matching method according to parameter type, number of parameters, and order of the parameters at compile time (early, static binding). A method may be implemented in several subclasses. The JVMe dynamically binds the implementation of the method at run time, decided by the actual type of the variable (late, dynamic binding). 131 Casting Objects You have already used the casting operator to convert variables of one primitive type to another. double d1=3.156, d2; int a1, a2=55; // casting – convert from int to double d2 = a2; // allowed d2 = (double) a2; // allowed // casting – convert from double to int a1 = d1; // compiler error a1 = (int) d1; // allowed Same approach applied when casting objects 132 Casting Objects Casting can also be used to convert an object of one class type to another within an inheritance hierarchy. In the preceding section, the statement m(new Student()); assigns the object new Student() to a formal parameter of the Object type. This statement is equivalent to: Object o = new Student(); // Implicit casting m(o); The statement Object o = new Student(), known as implicit casting, is legal because an instance of Student is automatically an instance of Object. 133 Why Casting Is Necessary? Suppose you want to assign the object reference o to a variable of the Student type using the following statement: Student b = o; A compilation error would occur. Why does the statement Object o = new Student(); work and the statement Student b = o; doesn’t? This is because a Student object is always an instance of Object, but an Object is not necessarily an instance of Student. Even though you can see that o is really a Student object, the compiler is not so clever to know it. To tell the compiler that o is a Student object, use an explicit casting. The syntax is similar to the one used for casting among primitive data types. Enclose the target object type in parentheses and place it before the object to be cast, as follows: Student b = (Student)o; // Explicit casting 134 TIP To help understand casting, you may also consider the analogy of fruit, apple, and orange with the Fruit class as the superclass for Apple and Orange. An apple is a fruit, so you can always safely assign an instance of Apple to a variable for Fruit. However, a fruit is not necessarily an apple, so you have to use explicit casting to assign an instance of Fruit to a variable of Apple. 135 Casting from Superclass to Subclass Explicit casting must be used when casting an object from a superclass to a subclass. This type of casting may not always succeed. Apple x = (Apple)fruit; // explicit casting only allow Orange x = (Orange)fruit; Apple x = fruit; // implicit casting not allowed Orange x = fruit; // implicit casting not allowed 136 Casting from Subclass to Superclass Explicit or implicit casting must be used when casting an object from a subclass to a superclass. This type of casting may always succeed. Fruit f1 , f2; Apple apl = new Apple(); f1 = apl; // implicit casting allowed f2 = (Fruit)apl; // explicit casting allowed 137 Casting from Superclass to Subclass Explicit casting must be used when casting an object from a superclass to a subclass. This type of casting may not always succeed. Object o = new GeometricObject(); Circle ac = new Circle(); ac = o; // syntax error, not every geometric //object is necessarily a circle. ac = (Circle) o; // OK, but casting may not // always succeed 138 Casting from Subclass to Superclass Explicit or implicit casting must be used when casting an object from a subclass to a superclass. This type of casting may always succeed. Object o = new GeometricObject(); Circle ac = new Circle(); o=ac; // OK o = (GeometricObject)ac; o = (Circle)ac; // OK // OK 139 The instanceof Operator Use the instanceof operator to test whether an object is an instance of a class: Object myObject = new Circle(); ... // Some lines of code /** Perform casting if myObject is an instance of Circle */ if (myObject instanceof Circle) { System.out.println("The circle diameter is " + ((Circle)myObject).getDiameter()); ... } 140 Example (8e): Demonstrating Polymorphism and Casting // source text file: ProgCastingDemo.java Given: inheritance relation Object - GeometricObject – Circle,Rectangle geometricObject (base class) – Circle, Rectangle (sub classes) Problem: write a program that creates two Object instances initialized as Circle(1.0) object and as a Rectangle(1.,1.0) object, and invokes the displayObject() method to display the objects. The displayObject() displays the area and diameter if the object is a circle, and displays area if the object is a rectangle. 141 Example (8e): Demonstrating Polymorphism and Casting Examine the source text: Q. which is the declared type and which is the actual type of o1 and o2? Object o1 = new Circle(1, "red", false); Object o2 = new Rectangle(1, 1, "blue", true); 142 Example (8e): Demonstrating Polymorphism and Casting Examine the source text: Q. what output is to display after following stmts? System.out.println(" "+ (o1 instanceof Object ) ); System.out.println(" "+ (o1 instanceof GeometricObject) ); System.out.println(" "+ (o1 instanceof Circle ) ); System.out.println(" "+ (o1 instanceof Rectangle ) ); 143 Example (8e): Demonstrating Polymorphism and Casting Examine the source text: Q. what output is to display after following stmts? System.out.println(" "+ (o2 instanceof Object ) ); System.out.println(" "+ (o2 instanceof GeometricObject) ); System.out.println(" "+ (o2 instanceof Circle ) ); System.out.println(" "+ (o2 instanceof Rectangle ) ); 144 Example (8e): Demonstrating Polymorphism and Casting Examine the source text: A. what output is to display after following stmts? Object GeometricObject Circle Rectangle o1 true true true false 145 o2 true true false true The final Modifier The final class cannot be extended: final class Math { ... } The final variable is a constant: final static double PI = 3.14159; The final method cannot be overridden by its subclasses. 146 More on Java syntax Abstract Classes and Interfaces 147 Interfaces & Abstract Classes The Interface concept 148 No method bodies – just method header. Interface Must provide implementation when used. public interface Driver { void turnWheel(double angle); void pressAccelerator(double amount); void pressBrake(double amount); } public class BusDriver implements Driver { // must include implementation for each of the three methods from Driver } 149 May also have public class BusDriver extends Person implements Driver { // must include implementation for each of the three methods from Driver } This is a “back door” approach to multiple inheritance for Java via extends and implements. Single inheritance via extends and extra inheritance via implements. 150 Interfaces & Abstract Classes The Abstract Class concept 151 Abstract Classes Similar for C# A class where some methods are unspecified (like in an interface). The unspecified methods are declared abstract. The class also is declared abstract. An abstract class must be sub-classed (i.e. extended) - you cannot instantiate objects of an abstract type. Useful if you want to specify an “interface” along with some default behaviors. 152 Abstract Class Example May have defined methods and abstract methods. abstract class CacheFile { String filename; byte[] contents; void flush() { // Write file to disk } void refresh() { // Load file from disk } abstract String deserialize(); abstract byte[] serialize(String s); } These methods are defined These methods are abstract because how you want to store data into the file is application-dependent 153 Abstract Classes & Interfaces Comprehensive presentation 154 Inheritance hierarchy If you move from super class down to sub class, classes become more specific and more concrete. If you move from sub class up to super class, classes become more general and less specific Sometimes super class is so abstract that it cannot have any specific instances. Such a class is referred to as an ABSTRACT CLASS Cn Cn-1 ..... C2 C1 Since o is an instance of C1, o is also an Object instance of C2, C3, …, Cn-1, and Cn 155 GeometricObject – Circle, Rectangle Object ↑ GeometricObject ↑ ↑ Circle Rectangle Common properties: Color, filled/nofilled, dateCreated Circle – specific properties: radius Rectangle – specific properties: width, height 156 GeometricObject – Circle, Rectangle GeometricObject ↑ ↑ Circle Rectangle Common properties: Color, filled/nofilled, dateCreated Circle – specific behavior: getArea(), getPerimeter() Rectangle – specific behavior: getArea(), getPerimeter() 157 GeometricObject – Circle, Rectangle GeometricObject ↑ ↑ Circle Rectangle Common properties: Color, filled/nofilled, dateCreated Circle – specific properties and behavior: Radius, getArea(), getPerimeter() Rectangle – specific properties and behavior: width, height, getArea(), getPerimeter() 158 Inheritance hierarchy Is it reasonable to generalize getArea(), getPerimeter() methods? From one side: Since we can compute area and perimeter for all geometric objects, it is better to define getArea(), getPerimeter() as methods in super class GeometricObject. From other side: Both methods cannot be implemented in the base class because their implementation depends on specific properties (radius or height/width) of the geometric object defined in the sub classes. Such methods are referred to as abstract methods and are denoted in the super class using modifier abstract. Class with abstract methods becomes an abstract class and is must to be also denoted abstract. See next slide. 159 Open file ProgGeometricObjectAbstractClass.java abstract class GeometricObject { … public abstract double getArea(); public abstract double getPerimeter(); } You cannot create instances of abstract classes using new operator. Constructors in abstract classes are protected because they are used only by subclasses. Super class defines common features (incl. methods getArea() and getPerimeter()). Because you don’t know how to compute area and perimeter of geometric objects, both methods are defined as abstract methods. These methods are implemented/overridden in the subclasses. 160 Open file ProgGeometricObjectAbstractClass.java class Circle extends GeometricObject { … public double getArea() { return Math.PI * radius * radius; } public double getPerimeter() { return 2 * Math.PI * radius; } public String toString()//overridden m. {return "Circle:\n"+super.toString();} } // end of class 161 Open file ProgGeometricObjectAbstractClass.java class Rectangle extends GeometricObject { … public double getArea() { return width * height; } public double getPerimeter() { return 2 * (width + height);} public String toString() //overridden m. {return "RecRec:\n"+super.toString();} } // end of class 162 Open file ProgGeometricObjectAbstractClass.java Why do we need abstract methods? What benefits if any? Browse the main() method: It creates two geometric objects – circle, rectangle Invokes equalArea() method – have a careful look at the formal parameters type Invokes displayGeometricObject() method – have a careful look at the formal parameter type 163 Open file ProgGeometricObjectAbstractClass.java public class ProgGeometricObjectAbstractClass { public static void main(String args[]) { GeometricObject geo1 = new Circle(5.); GeometricObject geo2 = new Rectangle(5., 3.); System.out.println("The two object have same area? "+ equalArea(geo1, geo2) ); displayGeometricObject(geo1); displayGeometricObject(geo2); } // end of main public static boolean equalArea( GeometricObject o1, GeometricObject o2) { return o1.getArea() == o2.getArea(); } public static void displayGeometricObject(GeometricObject o) { System.out.println("The area is " + o.getArea() ); System.out.println("The perimeter is " + o.getPerimeter() ); } } 164 Open file ProgGeometricObjectAbstractClass.java Thanks to declaring abstract methods in super class, it is valid to create a connection btw super class and sub classes through getArea()/getPerimeter() methods and apply the polymorphic approach or in other words: Reference variable of a super class type (formal parameter) can point to an object of its sub class type (actual argument – look at its actual type). 165 Open file ProgGeometricObjectAbstractClass.java Equalarea() method to have two parameters GeometricObject and to compare to equality the area of a circle and the area of a rectangle. public static boolean equalArea(GeometricObject o1, GeometricObject o2) { return o1.getArea() == o2.getArea(); } 166 Open file ProgGeometricObjectAbstractClass.java displayGeometricObject() method to have a parameter GeometricObject and to display: the area and perimeter of a circle or the area and perimeter of a rectangle (depends on actual argument) when method called. public static void displayGeometricObject(GeometricObject o) { System.out.println("The area is " + o.getArea() ); System.out.println(“Perimeter is "+o.getPerimeter()); } // end of method 167 Inheritance, polymorphism and abstract classes Given the source: GeometricObject geo1 = new Circle(5.); GeometricObject geo2 = new Rectangle(5., 3.); GeometricObject[] o = { new Circle(2.), new Circle(3.), new Rectangle(5., 3.), new Rectangle(4.,6.) }; for (int i=0; i< o.length; i++) System.out.println("The two objects have same area?"+ equalArea(geo1,o[i])); Q.: Can you guess/predict the expected output? 168 Inheritance, polymorphism and abstract classes Given the source: GeometricObject geo1 = new Circle(5.); GeometricObject geo2 = new Rectangle(5., 3.); GeometricObject[] o = { new Circle(2.), new Circle(3.), new Rectangle(5., 3.), new Rectangle(4.,6.) }; for (int i=0; i< o.length; i++) System.out.println("The two objects have same area?"+ equalArea(geo2,o[i])); Q.: Can you guess/predict the expected output? 169 Inheritance, polymorphism and abstract classes Expected output: Geo1 Geo2 ======================= false false false false false true false false 170 Digression on equalArea() problem The task to compare the area of a circle and the area of a rectangle could be solved without specifying abstract class GeometricObject and erasing the getArea()/getPerimeter() methods from the super class. BUT: such a solution should lose the advantages provided when using polymorphism 171 Java predefined abstract classes 172 Java library: Calendar - GregorianCalendar java.util.Calendar is an abstract base class for extracting detailed calendar info: y, m, d, h, m, s Subclasses of Calendar can implement specific calendar systems: Gregorian calendar, Lunar calendar, Jewish calendar Java supports subclass java.util.GregorianCalendar 173 Open file ProgCalendar.java Comments: Calendar cl1 = new GregorianCalendar(); cl1 declared type is Calendar cl1 actual type is GregorianCalendar Polymorphism in action: in other words a ref var of a super class type can point to an object of its sub class type. Task: Modify the ProgCalendar.java source file with String dayNameOfWeek(int dayOfWeek) method to return strings “Sunday”, “Monday”, … “Saturday” depending on calling integer argument value 1, 2, ...7 174 Interfaces 175 Interfaces Interface is class-like construct that contains only constants and abstract methods. Interface is similar to abstract class, but its intent is to specify common behavior for objects that belong even to different inheritance hierarchies. Reminder: Abstract class contain regular methods and abstract methods and polymorphic approach is within one only specific inheritance hierarchy. 176 Interfaces To distinguish an interface from a class, Java uses interface reserved word: public interface Edible { public abstract String howToEat(); } Each interface to save in separate file like Edible.java. You cannot create an instance of interface with new You can use interface as data type for ref var, or as a result of casting 177 Interface example Given: Edible interface and two separate independent inheritance hierarchies: =================================================================================================== Animal ↑ ↑ Tiger Chicken(Edible) Fruit(Edible) ↑ ↑ Apple Orange =================================================================================================== Animal – regular base class Fruit – base class implements Edible interface Chicken – child class implements Edible interface Tiger – regular child class Apple, Orange – regular child classes 178 Open files Edible.java & ProgInterfaceEdible.java Task: using Edible interface to specify which object is edible, in other words has implemented method howToEat(). Browse the source text 179 Open files Edible.java & ProgInterfaceEdible.java Chicken extends Animal, implements Edible to specify that chickens are edible, implements method howToEat() Tiger extends Animal, does not implement Edible i.e. tigers are not edible, no need to implement method howToEat() 180 Open files Edible.java & ProgInterfaceEdible.java Fruit implements Edible, and does not implement howToEat() method. Therefore Fruit is to be modified as abstract class and concrete subclasses of Fruit must implement howToEat() method, as it is done with Apple class and Orange class 181 Open files Edible.java & ProgInterfaceEdible.java Run the application 182 Java supported interfaces 183 Java supported interfaces: Comparable Problem: we need a method to return the larger of two objects of the same type: Two students, Two dates, Two circles, Two rectangles It is must the two objects to be comparable Comparability is considered a common behavior Java provides Comparable interface for this purpose package java.lang; public interface Comparable { public int compareTo(Object o); { 184 Java supported interfaces: Comparable Many Java predefined classes (String, Date) implement Comparable interface to define an order for the objects. String, Date classes provide compareTo() method. Their definition is like this: //------------------------------------public class String extends Object implements Comparable { // class body } //------------------------------------Public class Date extends Object implements Comparable { // class body } 185 Java supported interfaces: Comparable Given String s; Date d; //------------------------------(s instanceof String) is true (s instanceof Object) is true (s instanceof Comparable) is true //------------------------------(d instanceof Date) is true (d instanceof Object) is true (d instanceof Comparable) is true 186 User Defined class implement interfaces: Comparable Reminder : class Rectangle We cannot compare instances of Rectangle, because Rectangle does not implement Comparable interface How to proceed? Re edit Rectangle class to implement Comparable OR Create new class ComparableRectangle to extend Rectangle and to implement Comparable 187 User Defined class implement interfaces: Comparable Solution scheme for the second option: GeometricObject ↑ Rectangle Comparable ↑ ↑ ComparableRectangle - - - - - 188 User Defined class implement interfaces: Comparable Open source file ProgComparableRectangle.java Source text skeleton for ComparableRectangle public class ComparableRectangle extends Rectangle implements Comparable { public ComparableRectangle(…) { …} public int compareTo(Object o) {…} } 189 User Defined class implement interfaces: Comparable How to use the compareTo() method ComparableRectangle r1 = new ComparableRectangle(4.,5.); ComparableRectangle r2 = new ComparableRectangle(4.,6.); ComparableRectangle r3 = new ComparableRectangle(5.,4.); System.out.println(r1.compareTo(r2)); System.out.println(r1.compareTo(r3)); System.out.println(r2.compareTo(r1)); 190 Questions? And/Or Thank You For Your Attention! 191