6

I'm looking for a way to add some methods into exists class like this:

String s = "";
s.doSomething();

In objective C, I can use category to do this.

@interface NSString( Stuff)
-(void)doSomething();
@end

Is android has something like that? Or another hack?


Update: Actually, I got this problem: I use a class (not final) from jar file (so, I can't touch its source code). Then I want to add methods( or something like that) into this class without using inheritance. For example:

 public class Provider{
       // many methods and fields go here...
       public String getName(){}
 }

All I want to do is:

 provider.print(); //that call getName() method;

I also tried proxy pattern, it worked, but I don't like that way (because it like a wrapper class, I must store an object with many fields and methods to use only one method):

 public class ProxyProvider{
       Provider provider;
       public ProxyProvider(Provider provider){
           this.provider = provider;
       }
       public void print(){
           String name = provider.getName();
           //do something
       }
 }

Is there any way to solve that?

ductran
  • 10,043
  • 19
  • 82
  • 165
  • 1
    *"because it like a wrapper class, I must store an object with many fields and methods to use only one method"* => not really, it is only storing a reference to the object, so from a memory perspective it should not have a significant impact. – assylias Jul 30 '12 at 11:49

4 Answers4

4

You could create a utility class with static methods:

public final class ProviderUtils {

    private ProviderUtils() {} // not instantiable, it is a utility class

    public static void print(Provider provider) {
        String name = provider.getName();
        // print the name
    }
}

In your code, you can then call it:

Provider p = new Provider(...);
ProviderUtils.print(p);

And if that class only has one print method, you can maybe call it ProviderPrinter instead of ProviderUtils.

In the end you don't have thousands of possibilities - you can:

  • extend the class and whatever method you need in the sub class => you said you don't want that
  • modify the source code of the class and recompile your own version of the jar
  • wrap the class in a wrapper that adds the methods you need (your ProxyProvider example)
  • put the methods you need in a static utility class (what I proposed above)
  • modify the class at runtime and add a method, but that's a complicated path because you need to play with classloaders.
Community
  • 1
  • 1
assylias
  • 321,522
  • 82
  • 660
  • 783
  • Thanks, but can you confirm whether or not to add method into a class? Should I use adding method or your way? – ductran Jul 31 '12 at 06:36
  • @R4j See my edit. There isn't a better way: it really depends on your requirement and why you need to do that, which you don't really explain. The Wrapper or static utility class methods are the less intrusive and error prone. – assylias Jul 31 '12 at 09:46
  • Thanks, I got it. Let me clarify, the requirements don't allow the use of inheritance, and I want to find the best way to solve problems (I though that add methods as well, but now I'm not sure). So, could you recommend me what should I do? – ductran Aug 01 '12 at 03:03
  • i like this answer, i think that's the way to go in java. for me it was completely the opposite; i started coding in objective c and was _very_ surprised you can do this :) – kritzikratzi Aug 01 '12 at 15:26
  • Thanks! @R4j The Wrapper method and utility class are similar - I would use the utility class because (a) it saves the creation of an object and will have a lower memory footprint if you need to deal with many Providers and (b) it is thread safe and (c) it keeps things simple. – assylias Aug 01 '12 at 15:52
  • @assylias Thanks, it saved me a lot of time. – ductran Aug 02 '12 at 03:14
1

It is not possible, however, there is a java like DSL available called Xtend that can be used as a compelling replacement for JAVA that might be work looking at which supports extension methods like this.

http://www.eclipse.org/xtend/

DISCLAIMER: I am in no way associated to this I am just an avid user of the core technology that was used to create xtend called xtext. I have considered using xtend on an Android project

Ian Warwick
  • 4,774
  • 3
  • 27
  • 27
0

In Java, a class can be extended using regular inheritence unless it final. String is final, because Strings are immutable, and therefore are intentionally protected against subclassing.

Also, adding behaviour by subclassing is considered bad practice in many cases - the coupling is simply too strong and sticks with you for instances of your objects you are ever going to create. The rule of thumb is "favour composition over inheritance".

Having said this, there are many approaches / patterns to solve your special problem. Decorator might be the pattern you are looking for.

Please update your question or post a new one with more information.

Jan Groth
  • 14,039
  • 5
  • 40
  • 55
0

Try to extend the class in question and add your methods to it. if that can't be done (like it's been said, String is final) then just write a wrapper around it with the methods you want and the object you want to extend.

Like

 public class MyString
 {
    private String internal;

    //your methods
 }

try to further elaborate your problem so i can give a better answer. like whats the real object in question and what you really wanna do, if you can disclose it that is.

Shark
  • 6,513
  • 3
  • 28
  • 50
  • I think your answer is what i am doing in updated question. I also give my real problem in updated question, please read carefully. – ductran Jul 29 '12 at 05:35