EE2E1. JAVA Programming Lecture 3 Inheritance
Contents Base classes and derived classes Base classes and derived classes Protected scope Protected scope Inheritance hierarchies Inheritance hierarchies The IS-A relationship The IS-A relationship Polymorphism Polymorphism Abstract classes Abstract classes Superclass Object Superclass Object
Base classes and derived classes Inheritance is a fundamental requirement for object orientation Inheritance is a fundamental requirement for object orientation Inheritance allows new classes to be derived from existing classes Inheritance allows new classes to be derived from existing classes Existing methods can be changed and extra instance fields can be added in the derived class Existing methods can be changed and extra instance fields can be added in the derived class
Example A Student class represents basic information about students at the University A Student class represents basic information about students at the University There are many categories of students There are many categories of students We can think about extending the Student class to represent We can think about extending the Student class to represent Undergraduate students Postgraduate students Each extension requires additional instance fields Each extension requires additional instance fields
class UndergradStudent represents the basic student information class UndergradStudent represents the basic student information name id. number address It also represents undergraduate specific information It also represents undergraduate specific information degree programme
Likewise class PostgradStudent represents the basic student information Likewise class PostgradStudent represents the basic student information name id. number address It also represents postgraduate specific information It also represents postgraduate specific information research supervisor
public class Student { public Student(String n, int id, String a) { name=new String(n); idNumber=id; address=new String(a); name=new String(n); idNumber=id; address=new String(a);} public void printInfo() { System.out.println(name + “ ”+ idNumber + “ ” + address); System.out.println(name + “ ”+ idNumber + “ ” + address);} private String name; private int idNumber; private String address; }
public class UndergradStudent extends Student { public UndergradStudent(String n, int id, String a, String d) { super(n,id,a); super(n,id,a); degreeProgramme=new String(d); degreeProgramme=new String(d);} public void printInfo() { super.printInfo(); super.printInfo(); System.out.println(degreeProgramme); System.out.println(degreeProgramme);} private String degreeProgramme; }
public class PostgradStudent extends Student { public PostgradStudent(String n, int id, String a, String p) { super(n,id,a); super(n,id,a); projectSupervisor=new String(p); projectSupervisor=new String(p);} public void printInfo() { super.printInfo(); super.printInfo(); System.out.println(projectSupervisor); System.out.println(projectSupervisor);} private String projectSupervisor; }
public class StudentTest { public static void main(String[] args) { UndergradStudent s1=new UndergradStudent( “John Smith”, 3429, “21 Bristol Rd”, “Electrical Eng”); PostgradStudent s2=new PostgradStudent( “Alan Jones”, 5395, “30 Bournbrook Rd”, “Dr. Mike Spann”); s1. printInfo(); s2.printInfo(); }
Keyword extends means we are making a new class which derives from an existing class Keyword extends means we are making a new class which derives from an existing class The new class is the derived class and the existing class is the base class The new class is the derived class and the existing class is the base class Student is the base class Classes PostgradStudent and UndergradStudent are derived classes Also the terms superclass (base class) and subclass (derived class) are often used Also the terms superclass (base class) and subclass (derived class) are often used
A key point is that private instance fields in the base class cannot be accessed by derived class methods A key point is that private instance fields in the base class cannot be accessed by derived class methods The derived class constructor invokes the base class constructor through the call to super(…) The derived class constructor invokes the base class constructor through the call to super(…) Must be the first statement in the derived class constructor Avoids the derived class having to access private instance fields in order to initialize them
Protected scope Protected scope gives a derived class access to base class instance fields and methods declared as protected Protected scope gives a derived class access to base class instance fields and methods declared as protected Breaks encapsulation only in the inheritance hierarchy Breaks encapsulation only in the inheritance hierarchy
class myClass {.. protected int member; } class anotherClass extends myClass { public f() { member=1;// OK – member protected }..}
Summary of member scope ScopeKeyword Visible (where)? Privateprivate In encapsulating class Protectedprotected In encapsulating class’s derived classes or package Publicpublic Wherever the encapsulating class is visible
Inheritance hierarchies A simple tree diagram indicates the base class/derived class relationship A simple tree diagram indicates the base class/derived class relationship Student PostgradStudent UndergradStudent
The hierarchy can easily be extended The hierarchy can easily be extended Student PostgradStudentUndergradStudent PhDStudentMastersStudent
The IS-A relationship Any object that is an instance of a derived class must be useable in place of an object which is an instance of a base class Any object that is an instance of a derived class must be useable in place of an object which is an instance of a base class Base class/derived class relationship form an IS-A relationship Base class/derived class relationship form an IS-A relationship PostgradStudent IS-A Student MastersStudent IS-A PostgradStudent etc
We can assign a derived class object to a base class variable We can assign a derived class object to a base class variable Becomes important for polymorphism Becomes important for polymorphism The converse is not legal – we can’t assign a base class object to a derived class variable The converse is not legal – we can’t assign a base class object to a derived class variable Can use a cast but be careful!
public class StudentTest { public static void main(String[] args) { Student[] s=new Student[2]; PostgradStudent ps=new PostgradStudent( “Alan Jones”, 5395, “30 Bournbrook Rd”, “Dr. Mike Spann”); UndergradStudent us=new UndergradStudent( “John Smith”, 3429, “21 Bristol Rd”, “Electrical Eng”); s[0]=ps; // legal assignment s[1]=us;// legal assignment ps=s[0];// Error! }
Polymorphism Crucial to object oriented programming Crucial to object oriented programming It is an object determining which method to call depending on where it is in the inheritance hierarchy It is an object determining which method to call depending on where it is in the inheritance hierarchy While the method (argument and return types) might be the same, objects might respond differently While the method (argument and return types) might be the same, objects might respond differently
When a method of a derived class is called through a reference to a base class object When a method of a derived class is called through a reference to a base class object The derived class method is called if there is a match (argument types and return type) Otherwise the method call is passed to the base class (or to the next class up the inheritance hierarchy) The key is late binding. Code for the method call is generated at runtime The key is late binding. Code for the method call is generated at runtime
public class Student {.. public void displayFees() {}.}
public class UndergradStudent extends Student {.. public void displayFees() { System.out.println(“Undergrad. fees are £1000 pounds”); System.out.println(“Undergrad. fees are £1000 pounds”);}.}
public class PostgradStudent extends Student {.. public void displayFees() { System.out.println(“Postgrad. fees are £5000 pounds”); System.out.println(“Postgrad. fees are £5000 pounds”);}.}
public class StudentTest { public static void main(String[] args) { Student[] s=new Student[2]; PostgradStudent ps=new PostgradStudent( “Alan Jones”, 5395, “30 Bournbrook Road”, “Dr. Mike Spann”); UndergradStudent us=new UndergradStudent( “John Smith”, 3429, “21 Bristol Road”, 3429, “21 Bristol Road”, “Electrical Eng”); s[0]=ps; // legal assignment s[1]=us;// legal assignment s[0].displayFees();// Postgraduate fees displayed s[1].displayFees();// Undergraduate fees displayed }}
Method displayFees() exhibits different functionality depending on the object making the call Method displayFees() exhibits different functionality depending on the object making the call No obvious implementation of Student.displayFees() method – could make it abstract (see next section) No obvious implementation of Student.displayFees() method – could make it abstract (see next section) However if a displayFees() method is not present in the derived class, the call is passed up to the base class Method calls are always passed up the inheritance chain until a match is found
Student PostgradStudent UndergradStudent s[] Student.displayFees() s[] PostgradStudent.displayFees() s[] UndergradStudent.displayFees()
So why the big deal over polymorphism? So why the big deal over polymorphism? Easy to extend the hierarchy Simply add displayFees() methods for new classes in the hierarchy Existing code will still work! Student s=new Student(…); MastersStudent ms=new MastersStudent(…); s=ms; // legal assignment s.displayFees();// Masters student fees displayed
Abstract classes At high levels in the inheritance hierarchy, classes become more and more abstract At high levels in the inheritance hierarchy, classes become more and more abstract The implementation of their methods becomes less clear and more abstract A call to an abstract method is always delegated down to one of the derived class methods A class containing at least one abstract method is called an abstract class A class containing at least one abstract method is called an abstract class Java uses the keyword abstract to denote abstract classes and methods Java uses the keyword abstract to denote abstract classes and methods
public abstract class Shape { public Shape(int x, int y){xpos=x; ypos=y;} public void move(int dx, int dy){xpos+=dx; ypos+=dy;} public abstract float area(); private int xpos, ypos; } public class Square extends Shape { public Square(int x, int y, int s){super(x,y); side=s;} public float area() {return side*side;} private int side; }
The method area() is abstract which makes the class Shape abstract The method area() is abstract which makes the class Shape abstract A Shape object cannot be created A Shape object cannot be created Shape s = new Shape(0,0);// Error! We can have Shape object variables but they must refer to a derived class object We can have Shape object variables but they must refer to a derived class object Shape sq = new Square(0,0,100);// OK float a = sq.area(); The method move() is non-abstract and is not overridden in the derived classes The method move() is non-abstract and is not overridden in the derived classes Common functionality across the inheritance hierarchy
Superclass Object Class Object is the ultimate ancestor of every class in Java Class Object is the ultimate ancestor of every class in Java However, we don’t have to explicitly write class myClass extends Object Useful for generic programming Useful for generic programming Alternative is C++ template classes which are more complex
Example – a generic search algorithm We want a generic search algorithm to search for any kind of object in an array We want a generic search algorithm to search for any kind of object in an array Class Object provides an equals() method to test whether one object is equal to another Class Object provides an equals() method to test whether one object is equal to another Simply checks if the 2 object references point to the same area of memory Not very useful in practice! We need to provide an equals() method in the class of the object we are searching for We need to provide an equals() method in the class of the object we are searching for Polymorphism does the rest!
In the following example we are searching for a Student object in an array In the following example we are searching for a Student object in an array The search is based on the student ID number Class SearchAlg provides a linearSearch method which carries out the search Class SearchAlg provides a linearSearch method which carries out the search We have provided an implementation of equals() in class Student We have provided an implementation of equals() in class Student
public class Student { public Student(String n, int id, String a) { name=n; idNumber=id; address=a; name=n; idNumber=id; address=a;} public boolean equals(Object obj) { Student s = (Student) obj; Student s = (Student) obj; return (idNumber==s.idNumber); return (idNumber==s.idNumber);} private String name; private int idNumber; private String address; }
public class SearchAlg { public static int linearSearch(Object[] a, Object b) { int n=a.length; int n=a.length; for (int i=0; i<n; i++) for (int i=0; i<n; i++) { if (a[i].equals(b)) if (a[i].equals(b)) return i; return i; } return –1; return –1;}}
public class StudentTest { public static void main(String[] args) { Student[] s = new Student[3]; Student[] s = new Student[3]; s[0]=new Student(“John Smith”, 3429, s[0]=new Student(“John Smith”, 3429, “21 Bristol Rd”); s[1]=new Student(“Paul Evans”, 5393, s[1]=new Student(“Paul Evans”, 5393, “9 Pershore Rd”); s[2]=new Student(“John Smith”, 6592, s[2]=new Student(“John Smith”, 6592, “3 Dawlish Rd”); Student st=new Student(“SmithJ”,6592, “5 Dawlish Rd”); Student st=new Student(“SmithJ”,6592, “5 Dawlish Rd”); int index=SearchAlg.linearSearch(s,st); int index=SearchAlg.linearSearch(s,st); System.out.println(“Student found at index ” + index) System.out.println(“Student found at index ” + index)}}
Key point is that SearchAlg.linearSearch() works for any type of object passed to it as long as an equals() method is defined for the object Key point is that SearchAlg.linearSearch() works for any type of object passed to it as long as an equals() method is defined for the object The cast from object to Student is crucial in enabling polymorphism to work The argument to the equals() method must be an Object for it to be overidden with the equals() method in Student
And finally….. This has been an important lecture in explaining the mechanics and some simple examples of inheritance and polymorphism This has been an important lecture in explaining the mechanics and some simple examples of inheritance and polymorphism Its important to understand why polymorphism is key to object oriented programming Its important to understand why polymorphism is key to object oriented programming You will develop a fuller understanding of this from the EE2E2 (object oriented design) course You will develop a fuller understanding of this from the EE2E2 (object oriented design) course