400 likes | 556 Views
EE2E1. JAVA Programming. Lecture 3 Inheritance. Contents. Base classes and derived classes Protected scope Inheritance hierarchies The IS-A relationship Polymorphism Abstract classes Superclass Object. Base classes and derived classes.
E N D
EE2E1. JAVA Programming Lecture 3 Inheritance
Contents • Base classes and derived classes • Protected scope • Inheritance hierarchies • The IS-A relationship • Polymorphism • Abstract classes • Superclass Object
Base classes and derived classes • Inheritance is a fundamental requirement for object orientation • 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
Example • A Student class represents basic information about students at the University • There are many categories of students • We can think about extending the Student class to represent • Undergraduate students • Postgraduate students • Each extension requires additional instance fields
class UndergradStudent represents the basic student information • name • id. number • address • It also represents undergraduate specific information • degree programme
Likewise class PostgradStudent represents the basic student information • name • id. number • address • 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); } public void printInfo() { 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); degreeProgramme=new String(d); } public void printInfo() { super.printInfo(); 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); projectSupervisor=new String(p); } public void printInfo() { super.printInfo(); 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 • 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
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(…) • 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 • Breaks encapsulation only in the inheritance hierarchy
class myClass { . . protected int member; } class anotherClass extends myClass { public f() { member=1; // OK – member protected } . . }
Student UndergradStudent PostgradStudent Inheritance hierarchies • A simple tree diagram indicates the base class/derived class relationship
Student PostgradStudent UndergradStudent PhDStudent MastersStudent • The hierarchy can easily be extended
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 • 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 • Becomes important for polymorphism • 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 • 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
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
public class Student { . . public void displayFees() {} . }
public class UndergradStudent extends Student { . . public void displayFees() { System.out.println(“Undergrad. fees are £1000 pounds”); } . }
public class PostgradStudent extends Student { . . public void displayFees() { 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”, “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 • 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
s[] Student.displayFees() Student s[] PostgradStudent.displayFees() s[] UndergradStudent.displayFees() UndergradStudent PostgradStudent
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 • 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 • 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 • 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 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 • Common functionality across the inheritance hierarchy
Superclass Object • 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 • 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 • 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 • Polymorphism does the rest!
In the following example we are searching for a Student object in an array • The search is based on the student ID number • Class SearchAlgprovides a linearSearch method which carries out the search • 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; } public boolean equals(Object obj) { Student s = (Student) obj; 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; for (int i=0; i<n; i++) { if (a[i].equals(b)) return i; } return –1; } }
public class StudentTest { public static void main(String[] args) { Student[] s = new Student[3]; s[0]=new Student(“John Smith”, 3429, “21 Bristol Rd”); s[1]=new Student(“Paul Evans”, 5393, “9 Pershore Rd”); s[2]=new Student(“John Smith”, 6592, “3 Dawlish Rd”); Student st=new Student(“SmithJ”,6592, “5 Dawlish Rd”); int index=SearchAlg.linearSearch(s,st); 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 • 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 • 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