开发者

Multiple toString() Methods with Generics

I have an object which will be stored in two different data structures.

I am using generics, and each structure has to print out the object in a different way. Is there a way to have multiple toString() methods that will invoke ac开发者_JAVA百科cordingly?

I can't create two different methods that return a string, as custom methods are not defined in the generic type, so you can't call them unless you cast it, which breaks the point behind generics.

Should I just create two different objects with different toString() methods for each data structure? Or is there an alternative?

Thanks


I think you need to use the toString() of the different objects, but you should still be able to do this with generics in place.

I imagine your generic class has at least one instance of the generic type. If that is the case, override your generic classes toString() to delegate to the generic type object instance.

If your generic class only has a single instance, you can do something like this:

class Holder<T> {
    private T instance;

    public Holder(T _instance) {
        instance = _instance;
    }

    public String toString() {
        return instance.toString();
    }
}

And if your class has multiple instances of the generic type (as with many Collection's), you can delegate to each instance of the type.

class CollectionHolder<T> {
    private Collection<T> collection;

    public CollectionHolder(Collection<T> _collection) {
        collection= _collection;
    }

    public String toString() {
        StringBuilder builder = new StringBuilder();
        for(T t : collection) {
            builder.append(t); //same as builder.append(t.toString())
        }
        return builder.toString();
    }
}


If you need to call it on both you need to add it to your interface. It's entirely possible you don't want to use toString() for it, since toString() is supposed to be a human readable representation.

class Nay1 {

    String someCrazyMethod() { return "ugh"; }
}

class Nay2 {

    String someRandomMethod() { return "ook"; }
}

Well this sucks. You wouldn't want a Nay1 to ook, or a Nay2 to ugh. But you need something uniform!

interface NayInterface {

String nayRepresentation();

}

And your new classes:

class Nay1 implements NayInterface  {

    String someCrazyMethod() { return "ugh"; }

    public String nayRepresentation() { return someCrazyMethod(); }
}

class Nay2 implements NayInterface {

    String someRandomMethod() { return "ook"; }

    public String nayRepresentation() { return someRandomMethod(); }
}

Now no matter what, you can call myNayInterface.nayRepresentation(); to get your string representation that matches the appropriate class without doing any casting.

class ActuallyDoesSomething<T extends NayInterface> {

    String foo;

    public ActuallyDoesSomething(T t) {
        this.foo = t.nayRepresentation();
    }

    public String foo() { return foo; }

}

Obviously if you want to use toString() instead of nayRepresentation, you can do that. But this will allow you to not have to consume toString and keep that instead for debugging purposes.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜