4.9 Interfaces

An interface is a specification of what a class should do without actually telling how it should do it. An interface is defined much like a class, except that there aren't any fields. The methods must be public and abstract, and they can't be static or native. Because the methods are abstract, they have no method bodies.

Here is an example of an interface:

 ; Used to list objects .interface Enumerator ; Get the next element .method public abstract getNext ()Ljava/lang/Object; .end method ; See if there is another object .method public abstract anyMore ()Z .end method .end class 

This specifies what methods an Enumerator must have, but it doesn't specify how to implement them. A class using the .implements directive claims that it implements the required methods. For example, this class implements an Enumerator for a linked list. (The LinkedList class has value and next fields.)

 .class LinkedListEnum .implements Enumerator .field private list LLinkedList; ; Initialize the enumerator with the list .method public <init>(LLinkedList;)V aload_0 invokespecial java/lang/Object/<init>()V       ; Superclass init aload_0 aload_1 putfield LinkedListEnum-list LLinkedList;      ; Save list return .end method .method public getNext ()Ljava/lang/Object; aload_0                                  ; Get the current value getfield LinkedListEnum/list LLinkedList; getfield LinkedList/value Ljava/lang/Object;                                      ; Leave it on the stack aload_0                             ; Store the tail of the list aload_0                             ; in list getfield LinkedListEnum/list LLinkedList; getfield LinkedList/next LLinkedList; putfield LinkedListEnum/list LLinkedList; areturn                            ; Return the value .end method .method public anyMore ()Z aload_0                            ; Get the list getfield LinkedList/list LLinkedList; ifnull false                       ; Go to false label on null iconst_1 ireturn                            ; Return 1 if not null false: iconst_0                           ; Return 0 if null ireturn .end method 

You may have additional methods, but you must implement all the methods declared in the interface. In this example, we have added a constructor. You can even use more than one .implements directive, in which case you must implement all of the methods in all of the interfaces that the class implements.

An object of type LinkedListEnum can be treated as an Enumerator, as if Enumerator were the superclass of LinkedListEnum. For example,

 .class Business .field currentInventory LLinkedList; .method public inventory ()LEnumerator; new LinkedListEnum             ; Create a LinkedListEnum dup aload_0 getfield Business/currentInventory    LLinkedList;                         ; Load the current                                         ;    inventory list invokespecial LinkedListEnum/<init>    (LLinkedList;)V                      ; Initialize                                         ;    the LinkedListEnum                                         ; with the LinkedList areturn                                 ; Return the                                         ;    LinkedListEnum .end method 

The return instruction is legal, because the actual return type (LinkedListEnum) implements the interface given in the method descriptor (Enumerator).

If you call inventory on a Business, you can enumerate over its inventory using the anyMore and getNext methods (in Java):

 Business business; // Get a Business from somewhere Enumerator e = business.inventory(); while(e.anyMore()) {    System.out.println(e.getNext()); } 

You don't have to say anything about LinkedListEnum. You only have to know that e contains an Enumerator, and you can call any of the methods defined there.

Since Business returns an Enumerator instead of a LinkedList, you can change the implementation of Business to use an ArrayEnum instead:

 .class ArrayEnum .implements Enumerator .field private elements [Ljava/lang/Object; .field current I .method public getNext()Ljava/lang/Object; ;; Return elements[current], and increment current .end method .method public anyMore()Ljava/lang/Object; ;; Return false if current < the length of elements .end method 

The implementor of Business can change the implementation of inventory without altering any of the classes that use it, since the implementation of Enumerator was kept separate from the interface definition.

Invoking methods through interfaces is slightly different from invoking methods using invokevirtual or invokespecial. A third instruction, invokeinterface, is required. To call anyMore, use code like this:

 ; Assume there's a Business in local variable 0 aload_0                                            ; Get the                                                    ; Business invokevirtual Business/inventory LEnumerator;      ; Get its                                                    ; inventory invokeinterface Enumerator/anyMore ()Z 1           ; Call anyMore 

The last argument to the invokeinterface instruction is the number of stack words used as parameters to the method call, including the receiver itself.[2] In this example, the only parameter is the Enumerator object itself, so the value is 1. For the interface:

[2] This number should not be necessary, since it can be derived from the method descriptor. However, it is included in the Oolong language because it is part of the underlying JVM bytecodes.

 .interface Searchable .method find(Ljava/lang/String;)Ljava/lang/Object; .end method 

A call to find looks like this:

 ; Assume there's a Searchable object in register 1 aload_1               ; Get the object ldc "potato chips"    ; We want an element named "potato chips" invokeinterface Searchable/find                 (Ljava/lang/String;)Ljava/lang/Object; 2 

The number of words to pop is 2: one for the object, and one for its argument. As usual, if an argument is a long or double, it counts as two slots instead of one.



Programming for the Java Virtual Machine
Programming for the Javaв„ў Virtual Machine
ISBN: 0201309726
EAN: 2147483647
Year: 1998
Pages: 158
Authors: Joshua Engel

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net