简体   繁体   中英

How do you override method() in third party library class if it calls super.method?

i would have liked to call super.super.method() but you can't do that in java. and there are several questions and plenty of answers like this one but none would work in this case.
it's not a matter of "bad design" or breaking encapsulation. i have a real usecase in which i need to override third party class because it has a bug, and i'm looking for a good solution.

So the situation for which i'm seeking a solution is this:
class ContextGetter and SpecialContextGetter are in third part class library. The method getContext in SpecialContextGetter has a bug (it sets i to 8 instead of 7).

i want to fix it. So i extended SpecialContextGetter with SpecialContextGetterCorrected in which i re-implement getContext (copied it from SpecialContextGetter and made the change) and instructed the framework to use my class, SpecialContextGetterCorrected, instead of SpecialContextGetter.

The problem is that my new method still needs to call ContextGetter.getContext and i can't tell Java to do that. (i'd like to call super.super.getContext)

how do i accomplish that short of placing my own com.thirdparty.SpecialContextGetter in front of the classpath?

package com.thirdparty;
class ContextGetter {
    //has several state variables  
    public Context getContext(Set x) throws Exception { 
        /* uses the state vars and its virtual methods */
        /* may return a Context or throw an Exception */
    } 
    /* other methods, some overridden in SpecialContextGetter */
}
class SpecialContextGetter extends ContextGetter {
    //has several state variables  
    public Context getContext(Set x) throws Exception { 
        /* uses the state vars and its virtual methods */
        /* somewhere in it it contains this: */

        if (isSomeCondition()) {
            try {
                // *** in my copied code i want to call super.super.getContext(x) ***
                Context ctxt=super.getContext(x); 
                /* return a modified ctxt or perhaps even a subclass of Context */
            } catch( Exception e) {
                /* throws new exceptions as well as rethrows some exceptions
                   depending on e and other state variables */
            }
        else {
            /* some code */
            int i=8; // *** this is the bug. it should set i to 7  ***
            /* may return a Context or throw an Exception */
        }
    } 
    /* other methods, some overridden in SpecialContextGetter */
}

I see a couple options, both of which might be unfeasible if the visibility declarations of the 3rd party software are too tight.

  • Instead of extending SpecialContextGetter and override just the culprit method, copy/paste the whole SpecialContextGetter class and fix the bug there. This might ugly, the the only way around.
  • Instead of extending SpecialContextGetter , extend ContextGetter and delegate to an instance of SpecialContextGetter (which you'll receive in the constructor of this new class) for all methods except the one you'd like to fix the bug where you'll have access to the super you want. If you're lucky you might do this, but I've got a feeling some visibility declarations or mutable state won't let you do it.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM