2

Let's say you have a class that extends Activity and implements MyInterface, where Activity contains public final void setProgress(int progress) and MyInterface contains public abstract void setProgress(int progress)

I need to override the method from the interface, but I can't because Activty says it's final and can't be overridden.

What do I do?

Example:

public class MyActivity extends Activity implements MyInterface
{
  @Override
  protected void onCreate(Bundle bundle)
  {
    //stuff goes here
  }
  //Cannot override the final method from Activity
  @Override
  public void setProgress(int progress)
  {
  }

}

Let's also extend this question and say you don't have access to the source of MyInterface to change it, what does one do in such situations?

ldam
  • 4,412
  • 6
  • 45
  • 76
  • Do you need to extend from Activity? If not you could use a composition of Activity, delegate the needed methods to Activity. – mszalbach May 10 '13 at 16:05
  • Yes, as far as I'm aware I need my Activity to be an Activity :) – ldam May 10 '13 at 16:09
  • Since I do not have the complete good I can only guess ;). Would it help to create a class MyActivity which is not implementing the interface and a class MyInterfaceImpl which does. The class MyInterfaceImpl gets a method asActivity and has a MyActivity as composition. So you could pase around your MyInterfaceImpl object and whenever its needed as Activity call the asActivity method on it. Maybe one of Bridge,Adapter pattern can also solve this problem . Or else remove the final :) – mszalbach May 10 '13 at 16:32
  • @mszalbach This is the best suggestion. Can you make that into answer instead? – MaciejGórski May 10 '13 at 16:34

5 Answers5

3

Use a decorator Design Pattern.

and here's a simplified example of the decorator pattern. (adapted from the interwebs and polygenelubricants' answer on SO)

Note: before we begin remove the abstract keyword from the interface, that's wrong syntax

The class hierarchy is restructured as static inner classes so that the whole example is contained in one compilation unit (as seen on ideone.com):

Here's a diagrammatic overview of intended class hierarchy

Class hierarchy Overview

public class AnimalDecorator {

    static interface Animal {
        public String makeNoise();
            public void wagTail();
            //other methods
    }   
    static class Dog implements Animal {
        public final String makeNoise() { return "woof"; }
        public final void wagTail() { //do wag tail action }
    }
    static class DogDecorator implements Animal {
            //delegate
            private Animal animal;

            public DogDecorator (Animal animal){this.animal = animal;}
        public String makeNoise() { animal.makeNoise();}
            public void wagTail() { animal.wagTail();}

    }

    static class LoudDog extends DogDecorator {
        @Override public String makeNoise() {
            return "WOOF WOOF WOOF!!!";
        }
    }
}

So here we have a simple Animal hierarchy, with Dog subclass. We also have a DogDecorator decorator -- also an Animal -- that simply delegates all methods to another Animal. That is, it doesn't really do any effective decoration, but it's ready to be subclassed so that actual decorations can be added.

We only have two methods here, makeNoise() and wagTail(). We then create the class we want LoudDog and use it. (Consider the case where Animal has many methods; then Normal would be most valuable).

Note that we can even stack one decoration on top of another. The exact implementation details may vary, but this simplified example pretty much captures the essence of the decorator pattern.


Steps

  1. Subclass the original "Component" class into a "Decorator" class (see UML diagram);
  2. In the Decorator class, add a Component pointer as a field;
  3. Pass a Component to the Decorator constructor to initialize the Component pointer;
  4. In the Decorator class, redirect all "Component" methods to the "Component" pointer; and
  5. In the ConcreteDecorator class, override any Component method(s) whose behavior needs to be modified.

See also

  • Effective Java 2nd Edition, Item 18: Prefer interfaces to abstract classes

Related questions

Community
  • 1
  • 1
Dheeraj Bhaskar
  • 18,633
  • 9
  • 63
  • 66
0

Edit:

In this case, the class cannot override the final method. So either your interface will have the exact same signature as the parent class (hence the interface is implemented automatically by inheritance), or you create a method with a different name.

The solution would largely depend on the circumstances, there's no textbook solution here.

tbkn23
  • 5,205
  • 8
  • 26
  • 46
  • Then when I (or anything else behind the scenes) call `setProgress` on my object later, which `setProgress` am I calling? And what do I do if I can't edit said interface? – ldam May 10 '13 at 15:59
  • Unfortunately there's not much you can do if you do not control the Interface. You might want to create your own interface, or a method with a different name that will call the original method. Did whomever create the interface intend for it to be used with `Activity`? If so, he made a mistake and you can ask him to fix it. – tbkn23 May 10 '13 at 16:03
  • If you share a little more background of what you're trying to do we could help you come up with alternatives. – tbkn23 May 10 '13 at 16:05
  • In my case I can edit my source fairly quickly :) but I would also like to know for future reference, maybe someone else will arrive at a problem like this and find it via google :) – ldam May 10 '13 at 16:07
  • Then I'd say the solution would depend on the situation... You could create a class that has the Activity as a member, or you could create another interface. There's no 1 solution I think. – tbkn23 May 10 '13 at 16:09
  • Also, you can't have a final method in an interface. The whole point of an interface is to implement its functionality. Oh and you should have `interface` not `Interface` ;) – ldam May 10 '13 at 16:12
0

You cannot override the final method because in the Java programming language, the final keyword is used to define an entity which cannot later be changed.

form Java Language Specification

NullPointerException
  • 3,732
  • 5
  • 28
  • 62
  • I know that. That's not what I asked. I asked how one gets around such a situation. – ldam May 10 '13 at 15:57
0

Never tried but can give it a try. You must implement the MyInterface in subclass too and can override the setProgress method of MyInterface and not of its superclass.

Should say..a good question:)

bakriOnFire
  • 2,685
  • 1
  • 15
  • 27
0

Don't have your MyActivity implement MyInterface and instead create anonymous or inner class that implements it.

This ways you still have access to all MyActivity components and functions from setProgress(int) which is completly separate from final Activity.setProgress(int).

MaciejGórski
  • 22,187
  • 7
  • 70
  • 94
  • I do need that interface reference elsewhere in my project (platform independence ftw). I also can't exactly change Android code either. – ldam May 10 '13 at 16:12
  • @LoganDam Ok. I understand your problem now. The simple answer is **just don't** use the same function name in your interface. – MaciejGórski May 10 '13 at 16:18
  • Lucky for me I can, but it's not impossible for something like this to happen in a library that someone uses and then they can't change the function name. – ldam May 10 '13 at 16:26
  • @LoganDam completly changed the answer based on mszalbach's suggestion. – MaciejGórski May 10 '13 at 16:45