0

Imagine the following:

Every word is a list of characters. However there can be no character itself, it always has to be part of a word.

So the Word class could look like this:

class Word extends List<MyCharacter>

Now, how could one enforce that it isn't possible to instantiate a MyCharacter which is not part of a Word? Maybe make MyCharacter an private inner class of Word and add a method like addCharacter(String character) to Word? But then, would it be possible to let Word extend the List class while MyCharacter is a private inner class of Word?

Thanks for any hint on this!

Update:

I now ended up at

import java.util.ArrayList;

public final class Word extends ArrayList<Word.MyCharacter> {

    protected final class MyCharacter
    {
        private String character;

        public String getCharacter() {
            return character;
        }

        public MyCharacter(String character)
        {
            this.character=character;
        }
    }

    public void addCharacter(String character) {
        add(new MyCharacter(character));
    }   
}

And here is how it's used:

public static void main(String[] args) {

    Word word = new Word();

    // word.add(new MyCharacter("a")); // as intended: not possible, because MyCharacter class can't be accessed
    word.addCharacter("a"); // ok           
}
stefan.at.kotlin
  • 15,347
  • 38
  • 147
  • 270
  • 1
    With `Character`, do you mean `java.lang.Character`, or is it one of your own classes? It's not a good idea to create your own classes with the same name as existing standard classes. – Jesper Mar 29 '13 at 11:54
  • No object is ever in any other object. There are only references. And all references, be they from the guts of `List<>` or from a a method of `Word` or from somewhere else entirely, are equal before the law. Your query just doesn't even make sense from the language's perspective, and you'll be hard pressed to implement it literally. Perhaps rephrase it so it reflects your actual goal? –  Mar 29 '13 at 11:56
  • Thanks for the hint, it's one of my own classes. – stefan.at.kotlin Mar 29 '13 at 11:56

2 Answers2

1

Maybe make Character an private inner class of Word and add a method like addCharacter(String character) to Word?

Yes. - Or maybe only declare the constructor of MyCharacter private and the MyCharacter class final. Or declare the MyCharacter class outside of Word having a 'package-private' constructor. Or have a kind of (static) factory method inside MyCharacter like appendToWord( Word w, Character char ) and a private constructor. Or ... :-)

Edit: I first misunderstood the question:

would it be possible to let Word extend the List class with the private inner Character class?

Word can extend List<T> in any way. But -as you figured out- not List<Word.SomeInnerClass>.

JimmyB
  • 12,101
  • 2
  • 28
  • 44
  • Hanno, I can't completely follow your reply, could you modify my posted example? Thanks :-) – stefan.at.kotlin Mar 29 '13 at 12:03
  • If I declare a constructor private, how can I instantiate such a class at all? – stefan.at.kotlin Mar 29 '13 at 12:04
  • 'It just works' ;) - See for example here: http://stackoverflow.com/questions/663059/why-do-inner-classes-make-private-methods-accessible – JimmyB Mar 29 '13 at 12:15
  • Thanks for updating my question and your reply Hanno, my question wasn't clear at the beginning, my fault. Also thanks for the hints, though I find the idea of @CapnSmack more comfortable. – stefan.at.kotlin Mar 29 '13 at 12:16
  • Hanno, interesting link, so makign the inner class public and the constructor private also works the same, I just tested this. Damn, I can't accept two replies ): Could you add your comment to your reply? Upvoted your reply :-) – stefan.at.kotlin Mar 29 '13 at 12:19
1

This is possible, in theory. One problem will arise in that Character is already a java class. Also, if you're using Eclipse, it won't let you declare

public class Word extends ArrayList<Letter> {
    private class Letter {
        //...
    }
}

unless you make Letter at most protected. I'm not sure whether that's an Eclipse issue or if Java would also stop you.

Regarding your superclass problem, it's because you cannot use List as it is only an interface. You must use something that implements it, like ArrayList.

CapnSmack
  • 232
  • 1
  • 4
  • Thank you for the hints, I now got a working example, see above :-) – stefan.at.kotlin Mar 29 '13 at 12:16
  • "One problem will arise in that Character is already a java class." - This shouldn't be a problem in any way. It's perfectly ok to have multiple classes of the same name, including the names of those classes provided by the Java API. – JimmyB Mar 30 '13 at 14:18