G51PGP Programming Paradigms Lecture OO-5 Inheritance and Class Diagrams 1
Early module feedback response I will leave Graham to comment on the Haskell side Mostly positive, including about speed for Java Good news for me since I re-wrote the Java side this year to go slower Record the lectures, especially Java I just want to flag up that the Java ones are recorded click watch now in the column to the left of the lecture slides on the web page I liked that some people re-watched the Java lectures and coded alongside me doing so A nice idea and seems to help multiple people Also makes it worth me recording them (also told it is useful for revision) The module is great, but it needs more pizza Will pass that on although no labs afternoon this semester Someone doesn t like that I compared against C because they didn t like C and/or found it too hard My aim was to help you to understand Java, rather than C Avoid starting from scratch + help you see the links (previous issue here) No more C in courseworks although I may try to explain things in terms of C when it helps to explain a concept 2
The story so far In Object Oriented Programming we decompose the program into a set of interacting objects Classes define the structure of objects of that class In Java we create objects (instances of a class) using the new operator We store a reference to the resulting object in a variable of the appropriate object reference type We use the. operator to apply a method to an object We can use Aggregation or Composition to reuse classes within other classes (simple reuse is a huge benefit of OO) So that objects of that class have one of the aggregated/composed objects inside it We can also use Inheritance / sub-type polymorphism Inheritance is key for good object oriented design This is what OO people mean when they talk about polymorphism Aside: FP people usually mean parametric polymorphism 3
Reminder: aggregation public class PGPFile public boolean openreadfile( String strfilename ) Setter/mutator if ( br!= null ) closereadfile(); try br = new BufferedReader( new FileReader(strFileName)); catch(exception e ) return false; return true; Data: hidden inside the class protected BufferedReader br; public String readnextline() if ( br == null ) return null; try return br.readline(); catch (IOException e) return null; Setter/mutator public boolean closereadfile() if (br==null) return false; Getter? Changes the file if not the object though try br.close(); br = null; catch (IOException e) return false; return true; 4
Second part of PGPFile mirror of first public boolean openwritefile( String strfilename ) if ( bw!= null ) closewritefile(); try Different classes used bw = new BufferedWriter( new FileWriter(strFileName)); return true; catch (IOException e) return false; protected BufferedWriter bw; Data: hidden inside the class public boolean writeline( String strline ) if ( bw == null ) return false; try bw.write( strline + "\r\n" ); return true; catch (IOException e) return false; public boolean closewritefile() if ( bw == null ) return false; try bw.close(); bw = null; return true; catch (IOException e) return false; 5
Sub-classing Sub-type polymorphism Creating a modified version/type of existing classes 6
Inheritance: IS-A relationships A class can be a specialisation of another class E.g. 4 wheeled cars, 3 wheeled cars are all types of Car 4 wheeled car IS-A car 3 wheeled car IS-A car Anything you can do with a car you can do with a 3 wheeled car, or a 4 wheeled car 7
Animal Class public class Animal public String gettype() return "Animal"; We create a class to represent an animal We could, for example, create a plant type as well if we wished to do so (we won t do so though) public String getname() return "I am an animal"; public String getnoise() return "Unknown noise"; public class Plant public String gettype() return "Plant"; 8
Animal and Bear sub-class public class Animal public String gettype() return "Animal"; public class Bear extends Animal public String getname() return "I am a bear"; public String getname() return "I am an animal"; public String getnoise() return "Unknown noise"; public String getnoise() return "GROWL..."; Use extends to get inheritance, so a Bear IS-AN Animal It gets everything in Animaland can change it or add to it 9
Bear inherits the methods of Animal You can create Bears and (generic) Animals Animal animal = new Animal(); System.out.println("I am a(n) : " + animal.getname() ); System.out.println("My type is : " + animal.gettype() ); System.out.println("I go : " + animal.getnoise() ); Bear bear = new Bear(); System.out.println("I am a(n) : " + bear.getname() ); System.out.println("My type is : " + bear.gettype() ); System.out.println("I go : " + bear.getnoise() ); Here we called gettype() using a Bear Bear inherits gettype() from Animal 10
Bear IS-An Animal You can create Bears and (generic) Animals Animal animal = new Animal(); System.out.println("I am a(n) : " + animal.getname() ); System.out.println("My type is : " + animal.gettype() ); System.out.println("I go : " + animal.getnoise() ); Animal a2 = new Bear(); System.out.println("I am a(n) : " + a2.getname() ); System.out.println("My type is : " + a2.gettype() ); System.out.println("I go : " + a2.getnoise() ); Bear IS-An Animal (it inherits methods and attributes) Bear inherits gettype() 11
More animals public class Fish extends Animal public String getname() return "I am a fish"; public class Mouse extends Animal public String getname() return "I am a mouse"; public String getnoise() return "(glug)"; public String getnoise() return "squeek..."; 12
Why does this work? public class TestAnimals public static void main(string[] args) Animal[] animals = new Animal[6]; animals[0] = new Bear(); animals[1] = new Mouse(); animals[2] = new Mouse(); animals[3] = new Fish(); animals[4] = new Mouse(); animals[5] = new Bear(); Array of object references Create objects and store in the array for ( int i = 0 ; i < animals.length ; i++ ) System.out.println( "" + animals[i].getname() + "... " + animals[i].getnoise() ); 13
Sub-type polymorphism We used sub-type polymorphism Often called Inheritance or sub-classing Original class is called a super-class or base class New type is called a sub-class or derived class We had an array of animal objects Remember inheritance means IS-A, so a Bear IS-An Animal When we called a function using the animal-type reference, the (same named) function on the object which is a specialisation of the Animal class was called i.e. it knew what class the object really was and used the function from that class instead Even though the code treats it as an animal Example of runtime polymorphism the compiler does not (and cannot) know the type 14
Polymorphism Means many forms not fixed to specific types Multiple types of polymorphism to consider Parametric polymorphism: Code works with multiple types, or regardless of types What Functional Programmers mean by polymorphism OO often calls it generic programming, e.g. for ArrayList<> Java generics (e.g. ArrayList<String>), C++ templates Ad-hoc polymorphism (function overloading) Same function name, multiple versions differing by parameter types Function may work differently depending upon the type Sub-type polymorphism (sub-classing) This is usually what we mean by polymorphism in OO terms 15
Class Diagrams Now we have seen inheritance, let s look at how we can visualise these relationships We will look at design patterns a lot later, and these diagrams will help us to understand them We can use diagrams to represent the relationships between classes To help us to understand the structure of the program Association is an important relationship objects of one class use objects of another class Aggregation and composition are also important relationships: objects of one are a part of another Inheritance is the final important relationship that we will think about: one class is a specialisation of another 16
Class diagrams Box for each class Three sections: Class name Member data Operations/functions Methods/functions Line for each relationship Association Aggregation Composition Is-A/ type of Top level window State/attributes/data members PGPText Main Container Contents PGPText String PGPText PGPTextFile 17
Class diagram for Animals Animal gettype() getname() getnoise() Bear Fish Mouse getname() getnoise() getname() getnoise() getname() getnoise() 18
Reminder: the entire PGPTextclass import java.util.arraylist; public class PGPText public PGPText() internalarray = new ArrayList<String>(); public int getlinecount() return internalarray.size(); // A standard collection class protected ArrayList<String> internalarray; public void addline( String str ) internalarray.add(str); public String getline( int iline ) return internalarray.get(iline); public void setline( int iline, String strtext ) while ( iline >= internalarray.size() ) internalarray.add(""); internalarray.set(iline, strtext); 19
Class diagram for PGPText PGPText internalarray PGPText() getlinecount() addline() getline() setline() ArrayList<String>? add() get() set() size() PGPText has an internal ArrayList<> The list is destroyed when the object is destroyed : composition The ArrayList<> contains Strings These Strings exist outside of the ArrayList<> but references to them are added to the array: aggregation String Sometimes we omit the attributes and methods Especially for standard classes 20
Java Packages Classes are organised into packages Groups of classes which are similar and work together These classes have special access to the methods/data of each other Packages can be embedded inside packages Directory structure must match the package structure Example using Eclipse Creates directory structure Labelled with keyword package and the name Refer to classes by packagename.classname Use the text using if you access classes in other packages to avoid having to keep stating packagename 21
Demo comments You can use eclipse to move classes to a new package Use refactor move and choose the package It will label package names and change the code which uses the classes appropriately Or move the files to a new directory called animal Note: in the lecture (and recording) I accidentally named the package with a capital A Ideally packages should be named in lower case Then the files will not compile unless you label them package animal; at the top (note ; at the end) Package name has to match the directory name Class name must match filename You can use eclipse to move 22
Assume Animal, Bear, etcare in package animal, then this code would work: animal.animal[] animals = new animal.animal[6]; animals[0] = new animal.bear(); animals[1] = new animal.mouse(); animals[2] = new animal.mouse(); animals[3] = new animal.fish(); animals[4] = new animal.mouse(); animals[5] = new animal.bear(); for ( int i = 0 ; i < animals.length ; i++ ) System.out.println( "" + animals[i].getname() + "... " + animals[i].getnoise() ); 23
Using using animal.*; animal.animal[] animals = new animal.animal[6]; animals[0] = new animal.bear(); animals[1] = new animal.mouse(); animals[2] = new animal.mouse(); animals[3] = new animal.fish(); animals[4] = new animal.mouse(); animals[5] = new animal.bear(); for ( int i = 0 ; i < animals.length ; i++ ) System.out.println( "" + animals[i].getname() + "... " + animals[i].getnoise() ); 24
Access permissions Packages are very important because of access privileges Attributes and methods are labelled with access permissions public Anything can access this protected This class + this package + subclasses can access this nothing (package) This class + this package can access this private Only this class can access this So there is a hierarchy of importance: The class itself has the most access (any modifier) Then other classes in this package (blank, public, protected) Then subclasses (public or protected) Then world (has to be public) 25
Next Lecture Interfaces and abstract classes Using some existing GUI classes More on Java GUI over the next few lectures after that 26