1.34k likes | 1.85k Views
Advance concepts in OOP. We discuss fundamental object-oriented techniques that supports re-use of software: Interface and polymorphhism Inheritance Method overriding Polymorphism, widening & narrowing protected and final modifiers. syllabus. basic programming concepts.
E N D
Advance concepts in OOP • We discuss fundamental object-oriented techniques that supports re-use of software: • Interface and polymorphhism • Inheritance • Method overriding • Polymorphism, widening & narrowing • protected and final modifiers syllabus basic programming concepts object oriented programming topics in computer science
Principles of object-oriented programming • encapsulation: data is protected from “external” users • inheritance: properties and methods defined for a certain structures can be used by all structures defined as direct offspring • polymorphism: the same function call may invoke different code, depending on context
Interfaces • A Java interface is a collection of abstract methods and constants • An abstract method is a method header without a method body An abstract method can be declared using the modifier abstract, but because all methods in an interface are abstract, it is usually left off • An interface is used to formally define a set of methods that a class will implement
interface is a reserved word A semicolon immediately follows each method header Interface: example None of the methods in an interface are given a definition (body) public interface Doable { public void doThis(); public int doThat(); public void doThis2 (float value, char ch); public boolean doTheOther (int num); }
Interfaces • An interface cannot be instantiated • Methods in an interface are always public and abstract • Constant in an interface are always public, static and final • A class formally implements an interface by • stating so in the class header • providing implementations for each abstract method in the interface • If a class declares that it implements an interface, it must define all methods in the interface or the compiler will produce errors
implements is a reserved word Each method listed in Doable is given a definition Implementing interface: example public class CanDoimplements Doable { public void doThis () { // whatever } public void doThat () { // whatever } // etc. }
Interfaces • A class that implements an interface can implement other methods as well • A class can implement multiple interfaces; the interfaces are listed in the implements clause, separated by commas • The class must implement all methods in all interfaces listed in the header
Polymorphism via Interfaces • An interface name can be used as the type of an object reference variable Doable obj; • The obj reference can be used to point to any object of any class that implements the Doable interface • The version of doThis that the following line invokes depends on the type of object that obj is referring to: obj.doThis();
Example: Animate Interface //************************************ // Animate.java // // Demonstrates the declaration of an interface //************************************ public interface Animate { int HIND_LIMBS_NUM = 2; int FORE_LIMBS_NUM = 2; public void sound (); public void gait (String type); }
// Parrot.java class Parrot implements Animate { private String word; //---------------------------------- // Establish Parrot's vocabulary //---------------------------------- public Parrot (String word) { this.word = word; } //---------------------------------- // Prints this parrot's sound. //---------------------------------- public void sound () { System.out.println ("This parrot says " + word); } //---------------------------------- // Prints this parrot's gait //---------------------------------- public void gait (String gaitType) { System.out.println ("Parrots " + gaitType + " on " + HIND_LIMBS_NUM + " limbs"); } }
// Dog.java class Dog implements Animate { private String name; private String owner; //---------------------------------- // Establish Dog's id //---------------------------------- public Dog () { name = "Lassi"; owner = "John"; } //---------------------------------- // Prints this dog's sound. //---------------------------------- public void sound () { System.out.println ("woof"); } //---------------------------------- // Prints this dog's gait //---------------------------------- public void gait (String gaitType) { System.out.println ("Dog " + name + " " + gaitType + " on " + (HIND_LIMBS_NUM+FORE_LIMBS_NUM) + " limbs"); } //---------------------------------- // Prints unique contact information //---------------------------------- public void contact() { System.out.println ("If you find me, call " + owner); } }
// Pets.java class Pets { //----------------------------------------------------------------- // Instantiates two objects using an interface reference and invokes one of the common // methods. Then casts interface reference into a class reference to invoke its unique method //----------------------------------------------------------------- public static void main (String[] args) { Animate current; current = new Parrot("hello"); current.sound(); current.gait("walk"); System.out.println("***********\n"); current = new Dog(); current.sound(); current.gait("runs"); ((Dog) current).contact(); } } This parrot says hello Parrots walk on 2 limbs woof Dog Lassi runs on 4 limbs If you find me, call John
Polymorphism via Interfaces • Interface reference is polymorphic, which can be defined as "having many forms" • The corresponding line of code may execute different methods at different times if the object that obj points to changes • Note that polymorphic references must be resolved at run time; this is called dynamic binding • Careful use of polymorphic references can lead to elegant, robust software designs
Review: Interfaces and polymorphism • A Java interface is a collection of abstract methods and constants; an interface is used to formally define a set of methods that a class will implement • Interface reference is polymorphic, which can be defined as "having many forms" • The corresponding line of code may execute different methods at different times if the object that obj points to changes
Standard Interfaces • The Java standard class library contains many interfaces that are helpful in certain situations • The Comparable interface contains an abstract method called compareTo, which is used to compare two objects • The String class implements Comparable which gives us the ability to put strings in alphabetical order • The Iterator interface contains methods that allow the user to move through a collection of objects easily
Example: Sorting Objects • Integers have an inherent order, but the order of a set of objects must be defined by the person defining the class • We can use the Comparable interface to develop a generic sort for a set of objects
class Contact implements Comparable { private String firstName, lastName, phone; // Uses both last and first names to determine lexical ordering. public int compareTo (Object other) { int result; if (lastName.equals(((Contact)other).lastName)) result = firstName.compareTo(((Contact)other).firstName); else result = lastName.compareTo(((Contact)other).lastName); return result; } public String toString() return lastName + ", " + firstName; }
public class Sorts { public static void insertionSort (Comparable[] objects) { for (int index = 1; index < objects.length; index++) { Comparable key = objects[index]; int position = index; // shift larger values to the right while (position > 0 && objects[position-1].compareTo(key) > 0) { objects[position] = objects[position-1]; position--; } objects[position] = key; } } }
class SortPhoneList { //----------------------------------------------------------------- // Creates an array of Contact objects and sorts them //----------------------------------------------------------------- public static void main (String[] args) { Contact[] friends = new Contact[4]; friends[0] = new Contact ("John", "Smith", "610-555-7384"); friends[1] = new Contact ("Daphna", "Weinshall", "02-555-7777"); friends[2] = new Contact ("Moshe", "Cohen", "03-222-3333"); friends[3] = new Contact ("Marsha", "Grant", "243-555-2837"); Sorts.insertionSort(friends); for (int i=0; i<friends.length; ++i) System.out.println(friends[i]); } }
Unit 8 • Interface and polymorphhism • Inheritance • Method overriding • Polymorphism, widening & narrowing • protected and final modifiers
Inheritance • Inheritance allows us to derive a new class from an existing one: • The existing class is called the superclass or base-class • The derived class is called the subclass or derived-class • Instances of the derived class inherit all the properties and functionality (data and methods) defined in the base class • Usually, the derived class adds more functionality and properties
Executive Hourly Example Employee (String name, ... hire(double payRate) pay()layoff() promote() ... Employee Hourly() addHours(int moreHours) Executive() giveBonus(int bonus)
Properties of subclass • Everything that can be done with an Employee object can also be done with an Hourly object • An Hourly is a special kind of Employee; it has all the functionality of an employee and some more • The subclass instances are more specific than the instances of the superclass
public class Employee { private String name; private String address; private double payRate; public Employee (String name, String address) { this.name = name; this.address = address; payRate = 0; } public void hire (double payRate) { this.payRate = payRate; } public double pay() { return(payRate); } } Example: the Employee class public void layoff () { payRate = 0; }
// define a special kind of employee - LEFI SHAOT public class Hourly extends Employee { private int hoursWorked; public void addHours (int moreHours) { hoursWorked += moreHours; } public double pay() { return payRate*hoursWorked; } } Subclass: the extends Keyword
More about subclass • Derived class should normally extend the functionality of the superclass • In certain cases, a derived class would change some of the functionality of the superclass
// define a special kind of employee - LEFI SHAOT public class Hourlyextends Employee { private int hoursWorked; public void addHours (int moreHours) { hoursWorked += moreHours; } public void pay() { return payRate*hoursWorked; } } The hourly subclass extend change
Pixel Hourly AdjustableSwitch File RestrictedFile Examples Point Employee Object Switch
What is Inherited? • The subclass inherits: • all the fields of the base class • all the methods of the base class • The constructors of the subclass should be defined again • Private fields and methods are inherited but cannot be accessed directly from the code of the subclass; they can only be accessed indirectly
Switch Example Switch • Switch() • boolean isOn() • setOn(boolean) • isOn
// An electronic switch that can be on/off public class Switch { // Records the state of the switch private boolean isOn; // Checks if this switch is on public boolean isOn() { return isOn; } // Sets the state of the switch on/off public void setOn(boolean state) { isOn = state; } } Switch Code
an adjustable switch has a “level of current” dial on off pressing the adjustable switch turns it on Special type: Adjustable Switch
Inheriting AdjustableSwitch from Switch • Switch() • isOn() • setOn(boolean) Switch • AdjustableSwitch() • setLevel(float) • getLevel() AdjustableSwitch
setOn(boolean) • isOn() • isOn • AdjustableSwitch() • setLevel(float) • getLevel() • level AdjustableSwitch Example AdjustableSwitch
AdjustableSwitch Code public class AdjustableSwitchextends Switch { // The level of current (0-100) private float level; // Sets the level of current public void setLevel(float level) { this.level = level; } // Returns the level of current of the switch public float getLevel() { return level; } }
Private Fields - Inherited but not Accessible • An AdjustableSwitch object has a state variable isOn inherited from Switch • However, it cannot be accessed directly from the code of AdjustableSwitch because it is defined as private in Switch (it is encapsulated)
Inheritance: a Basis for Code Reusability • Fast implementation - we need not write the implementation of AdjustableSwitch from scratch, we just implement the additional functionality • Ease of use - if someone is already familiar with the base class, then the derived class will be easy to understand • Less debugging - debugging is restricted to the additional functionality • Ease of maintenance - if we need to correct/improve the implementation of Switch, AdjustableSwitch is automatically corrected as well • Compactness - our code is more compact and is easier to understand
Example: Changing the Base Class • Suppose that we want to add the property of ‘maximal power’ to our representation of a switch • This property is suitable in adjustable switches as well (the inheritance supports our abstraction!) • Inheritance allows us to add this property only in the base class; the changes will automatically take place in the inherited class
Changing the Switch Class public class Switch { // Records the state of the switch private boolean isOn; // The maximal power of this switch private float maxPower; // constructor public Switch(float maxPower) { if (maxPower > 0.0f) this.maxPower = maxPower; } // Returns the maximal power of this switch public float getMaxPower() { return maxPower; } }
Constructors of subclasses must be redefined? • The constructor of Switch receives a parameter - maxPower - and initializes the private field with the same name • We have to define a constructor for AdjustableSwitch that receives the same parameter and initializes this field; but this field is private, so there is no direct access to it • In general, when we invoke a constructor of a subclass, we first have to construct the superclass “part” of the subclass; we do this by using the super keyword
// Constructs an adjustable switch public AdjustableSwitch(float power) { super(power); } AdjustableSwitch - Redefinition of Constructor The first line of the constructor calls the constructor of the superclass (Switch) that receives a float parameter to initialize the state variable defined in the superclass
Calling super(...) • The constructor of a derived class MUST initialize the state of the object from the point of view of its parent class • the first line in the constructor must be a call to one of the constructors in the superclass using super(...) • Otherwise, the compiler automatically places a call to the empty constructor of the superclass • A later call to super(...) is not allowed because a constructor can be invoked only once
Automatic Default Construction • In the previous implementation of Switch and AdjustableSwitch we did not include any constructors • The compiler automatically adds an empty (default) constructor to each of the classes • In addition, the compiler puts in the first line of the empty constructor of AdjustableSwitch a call to the empty constructor of Switch
Automatic Default Construction // ...in class Switch (automatically added) public Switch() { } // and in class AdjustableSwitch //(automatically added) public AdjustableSwitch() { super(); }
Default Construction Using Other Constructors • Sometimes the programmer may wish to define a default constructor (i.e., a constructor with no arguments) by herself, which may call other constructors with default arguments of her choice • If we do this in the Switch class, we need not define any constructor in the AdjustableSwitch class
Default Construction - Delegation // Constructs a new switch. // @param power the maximal power of the switch public Switch(float maxPower) { if (maxPower > 0.0f) this.maxPower = maxPower; } private static final DEFAULT_POWER = 60.0f; // Constructs a switch with default power public Switch() { this(DEFAULT_POWER); }
Unit 8 • Interface and polymorphhism • Inheritance • Method overriding • Polymorphism, widening & narrowing • protected and final modifiers
Overriding Methods • Occassionally, when we derive a class, we want to change some of the functionality defined in the superclass • Mechanism: a sub-class can override the definition of an inherited method in favor of its own • That is, a child can redefine a method that it inherits from its parent; the new method must have the same signature as the parent's method, but can have different code • The type of the object executing the method determines which version of the method is invoked
File(String name) • isOpen() • open() • close() • getName() File • RestrictedFile(String name, long key) • isLocked() • lock() • unlock(long key) RestrictedFile Overriding: example we want clients to be able to open a restricted file only if it is unlocked; how do we do it?
File Example public class File { // The name of the file private String name; // true if the file is opened private boolean isOpen; // Construct a file with a given name public File(String name) { this.name = name; } // Returns the name of the file public String getName() { return name; }