?? ifc.html
字號:
<html><!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN"><html> <head><title>Interfaces in Java</title></head><BODY bgcolor=#ffffee vlink=#0000aa link=#cc0000><H2>Interfaces in Java</H2><P> An interface encapsulates a coherent set of services andattributes (broadly, a <AHREF="javascript:if(confirm('http://g.oswego.edu/dl/rp/roles.html \n\nThis file was not retrieved by Teleport Pro, because it is addressed on a domain or path outside the boundaries set for its Starting Address. \n\nDo you want to open it from the server?'))window.location='http://g.oswego.edu/dl/rp/roles.html'" tppabs="http://g.oswego.edu/dl/rp/roles.html">Role</A>), withoutexplicitly binding this functionality to that of any particular objector code.<p> Interfaces are ``more abstract'' than classes since they don't sayanything at all about representation or code. All they do is describepublic operations. For example, the <code>java.lang.Runnable</code>interface is just:<pre>public interface Runnable { public abstract void run();}</pre>Notes:<ol> <li> The keyword <code>abstract</code> means that no code is supplied for this method. It is strictly optional to bother listing it in <code>interfaces</code>. <em>All</em> methods defined in <code>interfaces</code> must be <code>abstract</code>. <li> All methods defined in <code>interfaces</code> must be <code>public</code>. <li> The only other kind of declaration allowed in an <code>interface</code> is to list <code>public static final</code> constants.</ol><p> Interfaces turn out to be a more useful concept than they might firstappear. They are vital tools for stepping up from writing occasionalone-shot classes to writing extensible packages and frameworks ofclasses that form the basis for suites of applications:<ul> <li> Classes that are otherwise totally unrelated can support the same interface if they happen to offer the same service. For example, the kinds of classes that can support <code>Runnable</code> have nothing else in common. Or for a different kind of example, linked-lists, hash tables, trees, and many other data structures all support basic operations like <code>addElement</code>, so can support a common interface even though their internal structures are completely different (See the <A HREF="javascript:if(confirm('http://g.oswego.edu/dl/classes/collections/index.html \n\nThis file was not retrieved by Teleport Pro, because it is addressed on a domain or path outside the boundaries set for its Starting Address. \n\nDo you want to open it from the server?'))window.location='http://g.oswego.edu/dl/classes/collections/index.html'" tppabs="http://g.oswego.edu/dl/classes/collections/index.html"> collections</A> package for several examples along these lines.) <li> In Java, a class can have only one superclass, but can claim to implement any number of interfaces. (In other languages, reasons for allowing more than superclass typically have little to do with supporting multiple interfaces. The troubles that Java avoids by the only-one-superclass rule mainly surround ambiguities, arbitrariness, and implementation messiness in dealing with how multiple possibly conflicting data representations and code are inherited when there are common ancestor classes among superclasses.) <li> Interfaces form a useful basis for <em>remote</em> method invocations; i.e., messages to objects that reside on different computers or processes. Such objects have <em>no</em> local representations. (Note: Remote invocation is not yet supported in Java.)</ul><p>Interfaces are otherwise used pretty much just like classesin Java. For example, you can write a method that acceptsany object obeying a stated interface and invoke methods on it,as in:<pre>class Foo { void doIt(Runnable r) { r.run(); }}</pre><H3>Subinterfaces</H3>One interface may be described as a subinterface of another if itextends its properties (i.e., contains additional methods.) In somelanguages one interface need not explicitly list that it is asubinterface of another -- if it contains all of the same features, pluspossibly more, it is considered a subinterface. (This is known as typeconformance.)<p>But in Java, each subinterface must be explicitly listedas <code>extend</code>ing one or more other interfaces, implicitlyinheriting all of the super-interface operations. For a classicexample:<pre>interface File { public void open(String name); public void close();}interface ReadableFile extends File { public byte readByte();}interface WritableFile extends File { public void writeByte(byte b);}interface ReadWriteFile extends ReadableFile, WritableFile { public void seek(int position);}</pre><p>It is common when defining interface hierarchies to use fairlyfine-grained interfaces at the top, each defining only a fewoperations, and to use (multiple) interface inheritance to define``fatter'', more useful ones as various combinations of these basicbits of functionality.<H3>Implementation Classes</H3>A class can implement an interface merely by:<ol> <li> Declaring that it does so. <li> Actually implementing the methods defined in the interface.</ol><p> For example, to implement Runnable in the dumbest (but fastest!)possible way:<pre>class FastRunner implements Runnable { public void run() {} }</pre><p> Note that there's a difference between a method defined not to doanything (i.e., with a null body) versus an <code>abstract</code>method, which is not defined at all.<p>Subclasses can also implement unrelated interfaces. Forexample, to create a subclass of some pre-exisiting classthat also implements <code>Runnable</code> to execute a particularmethod when <code>run()</code> is invoked:<pre>class FileReader { protected String filename_; protected byte[] buffer_; public FileReader(String filename, byte[] buffer) { filename_ = filename; buffer_ = buffer; } public void read() { /* read the file into buffer */ }}class RunnableFileReader extends FileReader implements Runnable { public RunnableFileReader(String filename, byte[] buffer) { super(filename, buffer); } public void run() { read(); }}</pre><H3>Abstract Classes</H3><em>Abstract classes</em> form an interesting and useful middle groundbetween interfaces and classes. Abstract classes are different thanordinary classes in that they declare one or more interface-style<code>abstract</code> methods in addition to normal methods andinstance variables. Such classes must be explicitly declaredas <code>abstract</code>. For example:<pre>abstract class MachinePart { protected String partID_; public String partID() { return partID_; } protected MachinePart(String id) { partID_ = id; } public abstract boolean canConnectTo(MachinePart other);}</pre><p>Here, the <code>MachinePart</code> class set down a commonrepresentation for <code>partIDs</code> that holds for all subclasses.But the declaration of <code>canConnectTo</code> is abstract since ithas to be implemented differently in every public subclass.(Alternatively, we could have provided a default implementation, sayto return <code>false</code>.)<p>Every <code>MachinePart</code> subclass gets its <code>partID</code>mechanics for free, but must specially implement <code>canConnectTo</code>.And as usual, it can further extend the class or even implementadditional interfaces:<pre>class Gadget extends MachinePart { public Gadget(String id) { super(id); } public boolean canConnectTo(MachinePart other) { if (other instanceof Gadget) return true; else if (other.partID().startsWith("Universal")) return true; else return false; } public void specialGadgetMethod() { ... }}</pre><p> Abstract classes are like interfaces in one other sense: Neitherare directly instantiable via <code>new</code>. So you cannot writecode like:<pre> Runnable r = new Runnable(); // wrong MachinePart p = new MachinePart(); // wrong</pre><p>The reason they are not instantiable is that there is nocode supporting one or more methods, so no such objectcan be constructed. This is true even though abstractclasses often have constructors. But these are calledonly from subclass constructors.<p> There are several further variations on this interplay betweeninterfaces and classes. For example, it is legal in Java to say thatan <code>abstract</code> class <code>implements</code> an<code>interface</code> even though it doesn't actually define one ormore of the methods, but instead leaves them for its own subclasses todefine. Such odd-sounding techniques tend to become parts of standardtricks of the trade when designing large frameworks and packages.<H3>Factories</H3>The fact that interfaces are not instantiable turns out to be a usefulproperty. It forces you to separate the notions of calling methodsfrom constructing objects. A client of an interface doesn't reallycare about which object or its immediate implementation class it getsto perform a service. So it has no business invoking a constructordeclared within a particular implementation class. Instead, whendesigning sets of components via interfaces, you can create<EM>factories</EM> (see the <AHREF="javascript:if(confirm('http://st-www.cs.uiuc.edu/users/patterns/Books.html \n\nThis file was not retrieved by Teleport Pro, because it is addressed on a domain or path outside the boundaries set for its Starting Address. \n\nDo you want to open it from the server?'))window.location='http://st-www.cs.uiuc.edu/users/patterns/Books.html'" tppabs="http://st-www.cs.uiuc.edu/users/patterns/Books.html"> DesignPatterns</A> book).<p>A factory class exists just to help create instrances of otherclasses. Factories often have methods that produce instances of ofseveral related classes, but all in a compatible way. Factoriesshould themselves be defined via interfaces, so the client need notknow which particular factory object it is using. Ideally, all suchmatters can be reduced to a single call to construct the appropriate``master'' factory in a client application.<p>Among the most well-known examples of factories is in UI toolkitsdesigned to run on different windowing systems. There might beinterfaces for things like:<pre>interface ScrollBar { ... }interface MenuBar { ... }...</pre><p>And associated classes implementing them on different windowingsystems:<pre>class MotifScrollBar implements ScrollBar { ... }class OpenLookScrollBar implements ScrollBar { ... }...</pre><p>And a factory interface that itself doesn't commit to representation:<pre>interface WidgetFactory { public abstract ScrollBar newScrollBar(); public abstract MenuBar newMenuBar(); ...}</pre><p>But implementation classes that do:<pre>class MotifWidgetFactory implements WidgetFactory { public ScrollBar newScrollBar() { return new MotifScrollBar(...); } ...}class OpenLoookWidgetFactory implements WidgetFactory { ... }</pre>Finally, to get an application up and running on different systems,only one bit of implementation-dependent code is needed:<pre>class App { public static void main(String args[]) { WidgetFactory wf = null; if (args[0].equals("Motif")) wf = new MotifWidgetFactory(); else ... startApp(wf); }}</pre><p> All other objects construct widgets using the factory passedaround (or, more likely, kept in a central data structure), neverknowing or caring what windowing system they happen to be running on.<p> Note: The Java AWT uses a strategy that is similar in concept butdifferent in detail for achieving implementation independence, via aset of ``peer'' implementation classes that are specialized for theplatform that the Java session is being run on, and instantiated whenuser-level AWT objects are constructed.<hr><A HREF="javascript:if(confirm('http://g.oswego.edu/dl \n\nThis file was not retrieved by Teleport Pro, because it is addressed on a domain or path outside the boundaries set for its Starting Address. \n\nDo you want to open it from the server?'))window.location='http://g.oswego.edu/dl'" tppabs="http://g.oswego.edu/dl">Doug Lea</A><!-- hhmts start -->Last modified: Wed Feb 14 06:44:14 EST 1996<!-- hhmts end --></body> </html>
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -