简体   繁体   English

使用Java调用委托方法

[英]Delegate method calling in Java

In Java: What is the best way to pass a method from one object to another so that it can be called at a later time by the second object? 在Java中:将方法从一个对象传递到另一个对象的最佳方法是什么,以便以后第二个对象可以调用它?

I come from an ActionScript background where it is as easy to pass around references to methods as it is to pass around references to variables but this seems to be much more difficult in Java. 我来自一个ActionScript背景,它很容易传递对方法的引用,因为它传递对变量的引用,但这在Java中似乎要困难得多。 The first few links I found flat out say it is not possible (and it may have been at the time of their posting), but then I found http://www.javacamp.org/javavscsharp/delegate.html which details how this can be accomplished. 我发现的前几个链接说不可能(并且它可能在发布时),但后来我找到了http://www.javacamp.org/javavscsharp/delegate.html详细说明了这一点可以完成。

My issue with using Javacamp's example is the string based reference to the method. 我使用Javacamp的例子的问题是基于字符串的方法引用。 Methods get renamed all the time and a string reference will only complain once you actually run that function runtime as opposed to compile time for a proper explicit link. 方法一直被重命名,一个字符串引用只会在您实际运行该函数运行时而不是为正确的显式链接编译时间时进行投诉。

Is there no way to do this with proper explicit links to the method you want the other class to execute? 有没有办法用你希望其他类执行的方法的正确显式链接来做到这一点?

Model of what I am hoping to accomplish: 我希望完成的模型:

  1. Player clicks an upgrade button on Activity1 > Activity1 passes upgrade method to a new confirmation activity Player单击Activity1上的升级按钮> Activity1将升级方法传递给新的确认活动
  2. Player clicks "Yes" > Confirmation activity calls upgrade method passed in from Activity1 播放器单击“是”>确认活动调用从Activity1传入的升级方法
  3. OR: Player clicks "No" > Confirmation Activity closes 或:玩家单击“否”>确认活动关闭

EDIT: To be clear I am not looking for a static method solution as that would require my Confirmation activity to hold many lines of logic for which static method to call. 编辑:要明确我不是在寻找静态方法解决方案,因为这需要我的确认活动来保存许多逻辑行,以便调用静态方法。 The Confirmation activity will be used all over my application: a simple "Are you sure you want to X?" 确认活动将在我的应用程序中使用:简单的“您确定要X吗?” -Yes -No, if yes execute X - 是 - 否,如果是,则执行X.

I am currently looking at implementing onActivityResult to avoid this issue but that will be more logic than I like for this kind of issue. 我目前正在考虑实现onActivityResult来避免这个问题,但这比我喜欢的这类问题更具逻辑性。

you can use interfaces like this: 你可以使用这样的接口:

public interface MyMethod {
    public void method();
}


public class FirtObject{

    private SecondObject ob;

    public void tellSecondObjectExecuteLater(){
        ob.executeLater( new MyMethod() { 
          public void method(){System.out.println("duh Method");} });
    }
}

public class SecondObject {

    private MyMethod myMth;

    public void executeLater(MyMethod mth){
        myMth = mth;
    }

    public void executeNow(){
        myMth.method();
    }
}

does this solve your problem? 这会解决你的问题吗?

The typical way to pass methods is to use an Interface and Anonymous Inner Classes. 传递方法的典型方法是使用Interface和Anonymous Inner Classes。 In order to maintain static typing an Interface is used to declare the method signature and typing information. 为了维护静态类型,使用Interface来声明方法签名和键入信息。 The caller can use either a concrete implementation of that interface as a normal class or using Anonymous Inner Classes for quick class creation. 调用者可以使用该接口的具体实现作为普通类,也可以使用匿名内部类来快速创建类。 I'll use standard Java SDK classes to illustrate: 我将使用标准的Java SDK类来说明:

interface Comparator<T> {
    public int compare( T a, T b); 
}

class SpecialCollection<T> {
    public void sort( Comparator<T> comparator ) {...} 
}

public class SomeClient {
    public void doSomething( SpecialCollection<SpecialObj> collection ) {

        collection.sort( new Comparator<SpecialObj>() {
           public int compare( SpecialObject a, SpecialObject b ) {
               // some implementation
           }
        } );
    }
}

The above is an example of a strategy pattern. 以上是战略模式的一个例子。 The thing about the strategy pattern (and passing callback methods like in Javascript). 关于策略模式的事情(以及传递Javascript中的回调方法)。 The author has to plan for those types of extensions. 作者必须计划这些类型的扩展。 The author has to predict up front where he/she wants you to extend. 作者必须预先预测他/她希望您扩展的位置。 And it just happens it's cleanest if you use Interfaces. 如果您使用Interfaces,它就会发生最干净的事情。

However, pure delegation doesn't have to have always involve Interfaces. 但是,纯委托不必总是涉及接口。 You can pass concrete classes, since Java can always pass a subclass that overrides various methods of that class to change what method or code will be invoked. 您可以传递具体的类,因为Java总是可以传递一个子类来覆盖该类的各种方法,以更改将调用的方法或代码。 For example in Java InputStream/OutputStream are abstract classes and you typically pass subclass instances to the methods. 例如,在Java中,InputStream / OutputStream是抽象类,您通常将子类实例传递给方法。

If you need the method to act differently depending on the context (AKA, it is different depending on how it is created), you'll want to pass along the instance of the class that the method is in. 如果您需要根据上下文采用不同的方法(AKA,它根据创建的方式而有所不同),您将需要传递该方法所在类的实例。

If it is a static method, you can just referenced the method itself if you import that class at the top of your new class. 如果它是一个静态方法,如果您在新类的顶部导入该类,则可以只引用该方法本身。

For example, lets say you have a method that will tell you stuff about a certain string. 例如,假设您有一个方法可以告诉您有关某个字符串的内容。 IF the class looks like this: 如果这个类看起来像这样:

class stringChecker {
    private String stringToCheck;
    public class stringChecker(String s) {
         stringToCheck = s;
    }
    public int getStringLength() {
         return stringToCheck.length();
    }
    public boolean stringStartsWith(String startsWith) {
         return (stringToCheck.indexOf(startsWith) == 0);
    }
}

Then you'll want to pass along the instance, since it is non-static. 然后你会想要传递实例,因为它是非静态的。 Different instances have different strings that they were created with, so you will get a different return if you use a different instance. 不同的实例具有创建它们的不同字符串,因此如果使用其他实例,则会获得不同的返回值。

However, if your class looks more like this: 但是,如果您的班级看起来更像这样:

class stringChecker {
     public static int getStringLength(String s) {
          return s.length();
     }
     public static boolean stringStartsWith(String s, String startsWith) {
          return (s.indexOf(startsWith) == 0);
     }
}

Then you can just reference those methods with stringChecker.getStringLength("test");, because the methods are static. 然后你可以用stringChecker.getStringLength(“test”);引用那些方法,因为这些方法是静态的。 It doesn't matter what instance they are in. The returned result depends ONLY on what is being passed in. You just have to make sure to add import stringChecker; 它们所处的实例并不重要。返回的结果仅取决于传入的内容。您只需确保添加import stringChecker; at the top or whatever your class will be called. 在顶部或任何你的课程将被称为。 For you, it'll probably be something like com.example.blah.otherthing.stringChecker, since you're working with android. 对你而言,它可能就像com.example.blah.otherthing.stringChecker,因为你正在使用android。

Good luck! 祝好运! I hope this helps :) 我希望这有帮助 :)

EDIT: Looks like I may have read the problem too quickly...if this isn't what you were asking about, just let me know with a comment and I'll delete this answer so as to not confuse anybody else. 编辑:看起来我可能太快读了这个问题...如果这不是你问的问题,请告诉我一个评论,我会删除这个答案,以免混淆任何人。

You said that you are using it in a project to open a Confirmation activity. 您说您在项目中使用它来打开确认活动。

Activities should not contain references to each other to avoid memory leaks. 活动不应包含彼此的引用以避免内存泄漏。 To pass data between activities should be used Intent class. 要在活动之间传递数据,应该使用Intent类。 To receive a result, call StartActivityForResult() and get result in the onActivityResult() method. 要接收结果,请调用StartActivityForResult()并在onActivityResult()方法中获取结果。

But in general for your task is more suitable AlertDialog or PopupWindow . 但一般来说,你的任务更适合AlertDialogPopupWindow

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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