Path: news.daimi.aau.dk!news.uni-c.dk!newsfeed.cs.auc.dk!news From: Kasper Osterbye Newsgroups: comp.lang.java.advocacy,comp.lang.beta Subject: Re: inner classes are hideous Date: Tue, 12 Aug 1997 11:18:18 +0200 Organization: Department of Computer Science, Aalborg University Lines: 143 Message-ID: <33F02A5A.2234@cs.auc.dk> References: <01bc958d$10ec9a00$3fe82299@mayura> <33EA55A0.DEE@earthlink.net> <33EA63AB.2DDB@earthlink.net> <33EC29CA.7CD5@earthlink.net> <5shqsc$fq$1@gjallar.daimi.aau.dk> <33ECD6E7.46C9@earthlink.net> NNTP-Posting-Host: kobber.cs.auc.dk Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit X-Mailer: Mozilla 3.0 (WinNT; I) Xref: news.daimi.aau.dk comp.lang.java.advocacy:13237 comp.lang.beta:11239 Jay Martin wrote: > > Ole Lehrmann Madsen wrote: > > I thus think that Inner > > Classes in Java can be just as well traced back to an > > Algol/Simula/BETA OO-style as to a Scheme style. > > References > > > If you are interested in how nested classes are used in OO languages, > > here are some (incomplete and BETA biazed) references: > > > > In 1-3 the use of nested classes in object.oriented languages are > > discussed. 4. discuss the combination of part objects and anonymous > > nested classes. 5 and 6 are general papers about Simula and BETA > > published > > in 8, and 7 is a book on BETA. > > -------- > > A nice list of work. But one research language (or a fist > full of academic papers) does not prove that "nested classes" > are a necessary concept for OO. This is a highly > controversal area. In fact, much more definitive > sources on OO say otherwise (like OO Software Construction > (2nd edition), Bertrand Meyer. In fact, OO has pretty much > basically been about inheritance and not nesting. There are probably many opinions on what should be in an OOP. Bertrand has many a good idea about Software engineering, and if nothing else is probably the best textbook writer. But he has some strange ideas as well, just look at his view on exception handling. That is hardly a "normal view". But returning to inner classes. Inner classes are not too interesing without anonymous classes. Perhaps in practice anonymous classes are much more practically useful than inner classes. The following code is from http://java.sun.com/docs/books/javaprog/1.1Update.html: "When you are writing simple subclasses or implementations of interfaces, creating a bunch of classes for each trivial class can be awkward. Anonymous classes are a convenient short form of inner classes that have no name, only an implementation that is specified right along with the new. Suppose you want to create a simple Observer object (see page 233) that keeps a history of the events stored in a field of your object. The following would do this directly and simply: private Vector history = new Vector(); public void watch(Observable o) { o.addObserver(new Observer() { public void update(Observable o, Object arg) { history.addElement(arg); } }); } The addObserver has an embedded new of an anonymous class that implements the Observer interface, implicitly extending Object. This anonymous class implements update by adding an element to the enclosing object's history vector. The compiler creates an unnamed (hence "anonymous") class that overrides update as specified." An other example is with collections, here I draw an example from the JGL (http://www.objectspace.com/jgl/documentation.html) The idea is the now classic pattern of separating iterators from collections, so that more than one instance of an iterator can be created for each collection. If you look in the documentation for JGL, you will see that there is a table that specifies the realation between each collection class, and its appropriate iterator. This is a good example where inner classes should be used to provide the appropriate encapsulation. There should be an innerclass which is named "Iterator", and each collection should then provide its own version of this class. The above problem is found also in connection with the new event/listener model in the Beans. This is discussed in connection with page 25 in the http://splash.javasoft.com/beans/beans.101.pdf document. Each source *could have* provided an abstract inner class "Listener", which provides the listener to be used with the specific event source (ES). class ES { class Listener { Listener() { // ..... } public void fooBarHappened(FooEvent fe) {} public void fooBazHappened(FooEvent fe) {} } // .... } This way one can create a instances of ES in the following way: ES myES = new ES(....); and listen to ES events like: myES.addListener(new myES.Listener() { public void fooBarHappened(FooEvent fe) { // handle event } } It can be argued that there is not much interesting here, as one could have created a new class Fooey (as on page 25). However, if you program uses two ES objects, and they need to handle events differently, then you need a Fooey1 and a Fooey2 class. Inner- and anonymous classes solves this. In general, your references to blockstructure "nesting is for the birds" etc. is hitting on an other nail, blockstructure is not to be used for modularization aka. abstract datatypes. This I believe is true. On the other hand, there are also problems in using class structure for modularization as can be seen with the friend classes from C++, and their counterpart of file scopes or "no encapsulation". This does not mean that classes are a bad idea, only that there are short commings. Block structure sometimes solves the friend problem (letting the friend be an inner class), sometimes it does not. In my experience there is nothing unnatural about block structure to beginners. They are used to thinking that many concepts need a context to be understood. Also anonymous classes are easy to understand: "I want one like that, only this little thing slightly different". Now I am just waiting for Java to reintroduce the idea of nested procedures, so that I can place my "supporter methods" within the method they support, so that it is clear from the code and can be checked be the compiler that supporter methods are only called by the one they are expected to support. -- Kasper