简体   繁体   中英

Extend ArrayList<E> when E is a nested class of the ArrayList itself…is this wrong?

First this IS a Java question so forgive this first C#-related explanation...

I've most recently been using C# where one .cs source file can contain multiple class definitions, example...

// Servers.cs

public class Server {
}

public class ServerList : ArrayList <Server> {
}

I do the above because it reduces the number of source files and keeps the two classes together.

In Java of course it's one class to one .java file but I had the idea of nesting the Server class as follows...

//Servers.java
public class ServerList extends ArrayList<ServerList.Server> {

    // Edited to make Server class 'static'
    public static class Server implements Serializable {
    }
}

This builds without compile time errors or warnings but I can't decide if it's right.

The more I look at it, the more I'm happier with it but I'm still worried that it may be considered bad practice or I could run into problems along the line.

So the question...is this OK to do? Sorry if this is a rookie Java question (or even a rookie OOP question - despite using OOP going back to mid 1990s with C++, I'm self taught and have never tried something like this).

EDIT:

Many thanks to all who have provided comments/pointers to this question.

Firstly I've edited my code to make the Server class static - I expect I would have discovered this down the line but it's good to know from the start that I should be approaching it this way.

To expand on things related to other comments...

I have reasons for extending ArrayList rather than using ArrayList (or List) in associated code. I didn't include the code (haven't started yet) but ServerList will encapsulate specific handling of Server objects (including searching on Server-specific fields/members).

Also I'm using ArrayList rather than List as I'll be using an instance of ServerList to bind to an Android Spinner widget (nice and easy with an ArrayAdapter). Sorry I didn't mention Android but my question was (in my mind) specific to Java practice and not really to my choice of classes to achieve what I'm looking to do.

As for extensibility / inheritance etc with respect to other programmers (or myself) using the Server or ServerList classes at a later date, they really are quite specific to the requirements of my current project...not necessarily a good OO approach to class definition I admit (and not usually my approach) but they serve my project best in terms of usability and efficiency.

Thanks again to all.

I have two issues with this:

  • since Server is the important class here, it should be a top level class. Having it as an inner class IMHO makes your code unintuitive, harder to understand. (And as @EboMike pointed out, whichever way you do it, the inner class should be static .)
  • I don't see a good reason to subclass ArrayList<Server> - apart from creating an extra class of minimal use, this ties its implementation to ArrayList , which limits your future options. I would prefer declaring List<Server> on public interfaces - program to interfaces, not to implementations . It is just as readable as ServerList , and more usable, since any Java programmer will know what it is, and how to use it.

If you want to mirror your first example more closely, you should make your inner class static:

public class ServerList extends ArrayList<ServerList.Server> {

    public class static Server implements Serializable {
    }
}

That means that the inner class can be created independently and is not related to the outer class. Otherwise, each inner class would be linked to its outer class (and would have access to those class' members as well) and would therefore be required to be created from within the context of ServerList.

I can be perfectly fine to nest classes. Try searching google for nested classes:

http://www.javaworld.com/javaworld/javatips/jw-javatip75.html

That is a good article on it. But to answer the question, no it is not "bad practice" but there are specific times you will use it.

It is technical perfect legal do do this, if you have a good reason.

For example the Java Map Interface do something (not 100%) similar: It has an Inner Interface Map.Entity , and defined an entry set, that uses this Inner Interface ( Set<Map.Entry<K, V>> entrySet() ) .

Anyway, you should make the inner class static, if you do not need access to the outer class within the inner one.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM