Interface Interface When you talk about the interface
Interface
Interface • When you talk about the interface of a class you typically mean the public methods of the class. • Often the implementation is postponed until the interface is settled, this can give a more “high-level” construction phase. • But also changing and extending the interface without changing the implementation is considered to be a great quality of objectoriented development. The classes which is dependent of the changed class might be subject to a “sound” revision.
An Interface Can Be Seen As a Protocol • An interface is an agreement on behavior • A class which implements an interface agrees on supporting the specified behavior • An interface can also be seen as a definition of a role, role classes which implements the role are able to play that role. Example: The auto-pilot of an airplane can act as a pilot the same is true about some humans. The auto-pilot and the human is quit different types of objects, but they can both play the same role. Many different types of objects can implement the interface, so the interface is not the same as a “class to subclass from”.
Interfaces in Java • In Java you can explicitly declare an interface • Definition (Java. Soft): An interface is a named collection of method definitions (without implementations). An interface can also include constant declarations (no fields). • In C++ you can declare interfaces through abstract classes. • Java do not have multiple-inheritance (multiple-inheritance is considered difficult both conceptually and when it comes to implementation of compilers). With interfaces you can achieve much the same as when you use multiple-inheritance. It is possible to inherit from one class and at the same time implement several interfaces.
Example • All methods in an interface must be public and abstract so it is not necessary to explicitly specify this. • Example: If you have a set of objects (of the same type) and you want to sort this objects, then it must be possible for each pair of objects to do a comparison and decide if one object is “larger” then the other. The objects must implement the interface Sortable: public interface Sortable { public int compare(Sortable b); }
1 Sorting an Array of Person-objects <<interface>> Sortable …. . int compare(sortable) static void bubble. Sort(Sortable[]) Person String name …. . String get. Name() …. . int compare(sortable) Register * 1 Person[] reg void sort() …. .
2 Sorting an Array of Person-objects public class Sort { public static void bubble. Sort(Sortable[] array){ // Find index of last used arrayelement int len = array. length; for(; (array[len-1] == null) && (len>0); len--); for(int pass = 1; pass < len; pass++){ for(int i = 0; i<len - 1; i++){ if(array[i]. compare(array[i+1]) > 0){ Sortable hold = array[i]; array[i] = array[i+1]; array[i+1] = hold; } } }
3 Sorting an Array of Person-objects public class Person implements Sortable{ public int compare(Sortable other){ if (!(other instanceof Person)) return 0; String other. Name = ((Person)other). get. Name(); return name. compare. To(other. Name); } …… } public class Register{ private Person[] reg; public void sort(){ if (no. Of. Persons==0) return; Sort. bubble. Sort(reg); } …… }
The clone-method • The Object class has a clone-method which do a byte by byte copy class Object{ protected native Object clone() throws Clone. Not. Supported. Exception{. . } • This method is not always applicable. If you have a reference field, than the object which is referenced will not be copied just the reference to the object. The clone-object and the original object will both have a field which have a reference to the same object • Cloning is considered a serious matter. The method is protected, so it can only be used inside a derived class. If you want to have a clonemethod or use the one from the Object class, than you have to implement the Cloneable interface.
If You Have a cloneable Class • Assume: class My. Class implements Cloneable{. . . . }. . My. Class obj 1 = new My. Class(. . . ); My. Class obj 2 = (My. Class)obj 1. clone(); • Than the following is typically true: obj 1 != obj 2 // the two references are to different objects obj 1. equals(obj 2) // values of the two different objects are compared obj 1. clone. get. Class() == obj 1. get. Class() // they are of the same class
Making Your Own Clone-method Example No. 1 class Person implements Cloneable { private String name; Person(String new. Name){ name = new. Name; } public String get. Name(){ return name; } public Object clone(){ try{ return super. clone(); // remember Strings are not mutable }catch (Clone. Not. Supported. Exception e){ return null; // should not happen, Cloneable is implemented } } } public class Test. Clone { public static void main(String[] args) { Person p 1 = new Person("Olsen"); Person p 2 = (Person)p 1. clone(); System. out. println("p 1. Name: " + p 1. get. Name()); System. out. println("p 2. Name: " + p 2. get. Name()); while(true); // let the user see the output } }
Making Your Own Clone-method Example No. 2 - Will Not Work public class Test. Clone { public static void main(String[] args) { Person p 1 = new Person("Jan"); Person p 2 = (Person)p 1. clone(); String. Buffer temp = p 2. get. Name(); temp = temp. append(" Olsen"); // p 1. name is also changed System. out. println("p 1. Name: " + p 1. get. Name()); System. out. println("p 2. Name: " + p 2. get. Name()); } } class Person implements Cloneable { private String. Buffer name; Person(String new. Name){ name = new String. Buffer(new. Name); } public String. Buffer get. Name(){ return name; } public Object clone(){ try{ return super. clone(); // NOTE!!! the following is not good enough // String. Buffer is mutable and a reference to the same // object can give you problems }catch (Clone. Not. Supported. Exception e){ return null; // should not happen, Cloneable is implemented } } }
Making Your Own Clone-method Example No. 3 - This Will Work Ok public class Test. Clone { public static void main(String[] args) { Person p 1 = new Person("Jan"); Person p 2 = (Person)p 1. clone(); String. Buffer temp = p 2. get. Name(); temp = temp. append(" Olsen"); // p 2. name will not be changed System. out. println("p 1. Name: " + p 1. get. Name()); System. out. println("p 2. Name: " + p 2. get. Name()); } } class Person implements Cloneable { private String. Buffer name; Person(String new. Name){ name = new String. Buffer(new. Name); } public String. Buffer get. Name(){ return name; } public Object clone(){ try{ // this will work Person temp = (Person)super. clone(); temp. name = new String. Buffer(name. to. String()); return temp; }catch (Clone. Not. Supported. Exception e){ return null; // should not happen, Cloneable is implemented } } }
- Slides: 13