Hannibal
Hannibal

Reputation: 1127

Java - Overriding Object Type Parameter With Concrete Type

EDIT: I will leave this here as an example. Read the comments for more information but generally: DON'T USE THIS DESIGN! It's BAD!

I searched for an answer for a while now, but couldn't find anything really specific saying, no you can't because... or yes you can that's how you do it..

So the question is, Can I create an abstract method defining Object type parameters and then have something implement it with a concrete Type of parameter like this:

public abstract class ToBeOverriden {
    public Object method1 (Object parameter);
    public String method2 (Object parameter);
    public void method3 (Object parameter);
}

And then override it with this:

public class Implementation {
    @Override
    public DateTime method1 (Person parameter){
        return new DateTime();
    }

    @Override
    public String method2 (MotorCycle parameter){
        return new DateTime();
    }

    @Override
    public void method3 (String parameter){
        return new DateTime();
    }
}

Where Person is an object created by me. Return Type can be whatever. Currently I can't do this. It doesn't let me. My guess is that this is because my Class doesn't extend Object. Although everything extends Object... So...

Or do I need to refresh my Java knowledge? :)

EDIT: Added a more complex class structure.

Thanks!

Upvotes: 8

Views: 18579

Answers (3)

bezmax
bezmax

Reputation: 26132

You would need to use Java Generics:

public abstract class ToBeOverriden<E,V> {
    public E method (V parameter);
}

public class Implementation extends ToBeOverriden<DateTime,Person> {
    @Override
    public DateTime method (Person parameter){
        return new DateTime();
    }
}

Added:

E parameter can be ommited, the code will still compile. However, if different implementations of the ToBeOverriden will use different return types, I think it's better to retain E. But that's a matter of personal taste - I don't like seeing Object anywhere in code.

Added 2:

As about your update in the question, you would need to have a separate Generic type for every method. For example:

public abstract class ToBeOverriden<A,B,C> {
    public Object method1 (A parameter);
    public String method2 (B parameter);
    public void method3 (C parameter);
}

However, usually, when you need such a horrible structure - then your code is designed the wrong way. In 95% cases 1 generic type parameter is enough. In 4.99% cases 2 generic type parameters are enough.

Upvotes: 19

Amir Pashazadeh
Amir Pashazadeh

Reputation: 7302

You can do the following:

public abstract class ToBeOverriden<T> {
    public Object method (T parameter);
}

public class Implementation extends ToBeOVerriden<Person>{
    @Override
    public DateTime method (Person parameter){
        return new DateTime();
    }
}

But you can't do that without generification, and the problem is the argument, not the return type. Suppose you could do that without generification, then you could hold a reference to your implementation object with an interface, and you could call the method with any object as argument, not just a Person (which is against Java's type-safety).

Upvotes: 3

Alexander Pavlov
Alexander Pavlov

Reputation: 32286

You do :) The spec says:

Two methods have the same signature if they have the same name and argument types.

You can easily have public Object method (Object parameter); and public Object method (Person parameter); in your class side by side, and these will be different methods.

And yes, all classes ultimately extend Object.

Upvotes: 0

Related Questions