views:

452

answers:

10
    class Super {

        public void anotherMethod(String s) {
            retValue(s)
        }


        public String retValue(String s) {
            return "Super " + s;
        }

    }

    class Sub extends Super {

        public void anotherMethod(String s) {
            retValue(s)
        }

        public String retValue(String s) {
            return "Sub " + s;
        }

    }

if suppose in main,

Super s = new Sub();
s.anotherMethod("Test");

Output will be, Sub Test

Can you anyone help me in telling how to get output Super Test with the given sequences in main.

And let me explain why I want this, say I have a class which has method test() and it can be overriden by sub classes, in some cases I want the overriden test() and in some cases I want the test() of super class itself, there are many ways to do this, best suggestions will be helpful.

+10  A: 

Why would you ever want to do that ??

The whole point of polymorphism is to call the right method without the need to know which kind of instance you've got ...

siukurnin
A: 

From class Sub you can call super.anotherMethod("bla"), but you cannot access the method of the superclass in your main method - that would be against the whole idea of using subclasses.

Simon Groenewolt
A: 

The runtime type of s is Sub, so you're only ever calling methods on that class.

David Grant
+2  A: 

You would have to go the route of:

Super s = new Super();
s.anotherMethod("Test");

...but that will defeat the purpose of inheritance if you also need whatever Sub's got. You could hack it like below but this seems an unelegant way to do it.

class Sub extends Super {

    public String anotherMethod( String s, boolean bSuper ) {
        if( bSuper )
            return super.retValue(s);
        else
            return retValue(s);
    }

    public String retValue(String s) {
        return "Sub " + s;
    }

}
QAZ
A: 

Whilst I agree with the other posters that this is not the best idea in the world, I believe it could be done with a little bit of tinkering.

If your child class was defined as:

    class Sub extends Super {

        public void anotherMethod(String s) {
            retValue(s)
        }

        public void yetAnotherMethodString s) {
            super.retValue(s)
        }

        public String retValue(String s) {
            return "Sub " + s;
        }

    }

and then call this new method in your main you would be able to print out "Super Test".

Doesn't seem like a very good plan tho. If you want access to parent functionality from a child class then don't override your parent method, just write a new one!

chillysapien
Assume we can't modify sub-class or caller.
Riyaz Mohammed Ibrahim
so you can't modify the child class at all?? What about the existing methods?
chillysapien
A: 

Can you anyone help me in telling how to get output "Super Test" with the given sequences in main.

  • Don't overwrite anotherMethod() and retValue() in Sub in the first place.

  • In Sub.anotherMethod(), return super.retValue(s) instead of retValue(s).

Zach Scrivena
A: 
Andrzej Doyle
+6  A: 

Whenever I find myself asking (or being asked) a question like this, I know, categorically, that I have made a mistake in my design and/or my object definitions. Go back to your object hierarchy and check, double-check and triple-check that every inheritance relationship represents an "IS-A", and not a "HAS-A" or something even weaker.

endian
A good valid point, being working in a legacy code can't change the hierarchy rather than add some workaround
Riyaz Mohammed Ibrahim
Ah OK, fair enough. I thought you were writing something brand-new, although I have no idea why I had that impression.
endian
+2  A: 

And let me explain why I want this, say I have a class which has method test() and it's can be overriden by sub classes, some cases I want the overriden test() and in some cases test() of super class itself, there are many ways to do this, it will be helpful if anyone can be best solution.

If your subclass overrides test(), then it overrides test() - this is the whole point of object inheritance. You just call methods on the object, which are dynamically resolved to the appropriate implementation based on the object's runtime class. That's the beauty of polymorphic typing, in fact, the caller doesn't have to know about any of this at all, and the subclasses determine how their behaviour differs from the superclass.

If you sometimes want it to act as its superclass method and sometimes want it to act as its subclass method, then you need to provide the context required to do this. You could either define two test-type methods; one which is never overridden and so always returns the superclass' behaviour (you can even mark the definition with final to ensure it's not overridden), and your normal one which is overridden as appropriate by the subclasses.

Alternatively, if there is some contextual information available, you can let the subclasses decide how to handle this; their implementation(s) could check some proeprty, for example, and based on that decide whether to call super.test() or proceed with their own overridden implementation.

Which one you choose depends on conceptually whether your main method (i.e. the caller), or the (sub)class objects themselves, are going to be in the best position to judge whether the superclass' method should be called or not.

But in no case can you override a method and expect it to magically sometimes not be overridden.

Andrzej Doyle
A: 

You cannot modify Sub or Super directly? If you could control what instance of Sub is used you could do something like:

Super sub = new Sub() {
  @Override
  public String retValue() {
    // re-implement Super.retValue()
  }
};
otherObject.use(sub);

Of course this requires you to have or be able to reproduce the source code of Super.retValue() and for this method not to use anything you can't access from an anonymous child. If the API is this badly designed though, you might do well to think about changing it out for something else.

wds