【问题标题】:Adding methods to exists class in android将方法添加到android中的现有类
【发布时间】:2012-07-24 17:12:31
【问题描述】:

我正在寻找一种将一些方法添加到现有类中的方法,如下所示:

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

在目标 C 中,我可以使用 category 来执行此操作。

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

android有类似的东西吗?还是其他黑客?


更新:实际上,我遇到了这个问题:我使用 jar 文件中的一个类(不是最终类)(因此,我无法触及它的源代码)。然后我想在不使用继承的情况下将方法(或类似的东西)添加到这个类中。例如:

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

我想做的就是:

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

我也试过proxy pattern,它有效,但我不喜欢这种方式(因为它就像一个包装类,我必须存储一个包含许多字段和方法的对象才能使用只有一个方法):

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

有什么办法可以解决吗?

【问题讨论】:

  • “因为它像一个包装类,我必须存储一个具有许多字段和方法的对象才能只使用一种方法” => 不是真的,它只是存储一个引用到对象,所以从内存的角度来看,它不应该有显着的影响。

标签: java android design-patterns


【解决方案1】:

您可以使用静态方法创建实用程序类:

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

在您的代码中,您可以调用它:

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

如果该类只有一个print 方法,您可以将其称为ProviderPrinter 而不是ProviderUtils

最终你没有成千上万的可能性——你可以:

  • 在子 1234562 中扩展你需要的类和任何方法 => 你说你不想要那个
  • 修改类的源代码,重新编译自己版本的jar
  • 将类包装在添加您需要的方法的包装器中(您的 ProxyProvider 示例)
  • 将您需要的方法放入静态实用程序类(我在上面提出的)
  • 在运行时修改类并添加一个方法,但是that's a complicated path因为你需要玩类加载器。

【讨论】:

  • 谢谢,但你能确认是否要在类中添加方法吗?我应该使用添加方法还是您的方式?
  • @R4j 查看我的编辑。没有更好的方法:这实际上取决于您的要求以及您为什么需要这样做,您并没有真正解释。 Wrapper 或静态实用程序类方法侵入性较小且容易出错。
  • 谢谢,我知道了。让我澄清一下,要求不允许使用继承,我想找到解决问题的最佳方法(我虽然也添加了方法,但现在我不确定)。那么,你能推荐我该怎么做吗?
  • 我喜欢这个答案,我认为这就是 java 的方式。对我来说完全相反;我开始在目标 c 中编码,非常很惊讶你能做到这一点:)
  • 谢谢! @R4j Wrapper 方法和实用程序类是相似的 - 我会使用实用程序类,因为(a)它保存了对象的创建,并且如果您需要处理许多提供程序,并且(b)它是线程,它将具有较低的内存占用安全且 (c) 它使事情变得简单。
【解决方案2】:

这是不可能的,但是,有一个类似于 DSL 的 Java 可用,称为 Xtend,它可以用作 JAVA 的引人注目的替代品,它可能正在寻找支持这样的扩展方法的工作。

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

免责声明:我与此无关,我只是用于创建名为 xtext 的 xtend 的核心技术的狂热用户。我曾考虑在 Android 项目上使用 xtend

【讨论】:

    【解决方案3】:

    在 Java 中,可以使用常规继承来扩展一个类,除非它是 finalStringfinal,因为字符串是不可变的,因此有意防止子类化。

    此外,在许多情况下,通过子类化添加行为被认为是不好的做法 - 耦合太强了,并且对于您将要创建的对象的实例一直存在。经验法则是“优先组合优于继承”。

    话虽如此,有很多方法/模式可以解决您的特殊问题。 Decorator 可能是您正在寻找的模式。

    请更新您的问题或发布一个包含更多信息的新问题。

    【讨论】:

      【解决方案4】:

      尝试扩展相关类并将您的方法添加到其中。如果这不能完成(就像有人说的那样,String 是最终的),那么只需用你想要的方法和你想要扩展的对象编写一个包装器。

      喜欢

       public class MyString
       {
          private String internal;
      
          //your methods
       }
      

      尝试进一步详细说明您的问题,以便我可以给出更好的答案。比如有问题的真实对象是什么以及你真正想做的事情,如果你能透露的话。

      【讨论】:

      • 我认为您的答案就是我在更新问题中所做的。我也在更新的问题中给出了我真正的问题,请仔细阅读。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-02-02
      • 2012-03-21
      • 2023-02-10
      • 2023-03-13
      • 2011-04-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多