How to by-pass inheritance in java when invoking a method – Education Career Blog

    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.

,

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 …

,

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.

,

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.

,

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;
    }

}

,

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.

,

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

,

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!

,

I’m hesistant to post this as an answer, since the question is quite horrible – but static methods would do roughly what the OP seems to want. Specifically, they are resolved on the compile-time declared class of the variable, not on the class of the instance held within that variable at runtime.

So modifying the original example:

class Super {
public static void staticMethod(String s) { System.out.println("Super " + s); } }

class Sub extends Super {

    public static void staticMethod(String s) {
        System.out.println("Sub " + s);
    }

}

public static void main(String args) {

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

}

then main() will print out “Super test”.

But still don’t do this until you understand why you want to, and you recognise that you are introducing subclasses and then gratuitously working around the point of them being there. Most IDEs for example will flag the above example with lots of warnings, saying that you shouldn’t call static methods on instance variables (i.e. prefer Super.staticMethod("Test") instead of s.staticMethod("Test")), for exactly this reason.

,

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.

,

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).

Leave a Comment