4

我正试图围绕界面进行思考,我希望它们是我问题的答案。

我为不同的游戏制作了插件和模组,有时类有 onUpdate 或 onTick 或其他可覆盖的方法。

如果我用一个方法创建一个接口,并创建实现该方法的其他类,并创建这些类的实例,那么如何一次从所有对象调用该方法?

4

5 回答 5

3

您将看到观察者模式或类似的东西。它的要点是:您必须在某处保留ArrayList“您的界面”类型的列表(足够)。每次创建新对象时,将其添加到此列表中。之后,您可以对列表执行循环并在其中的每个对象上调用该方法。

稍后我将使用代码示例进行编辑。

public interface IMyInterface {
    void DoSomething();
}

public class MyClass : IMyInterface {
    public void DoSomething() {
         Console.WriteLine("I'm inside MyClass");
    }
}

public class AnotherClass : IMyInterface {
    public void DoSomething() {
         Console.WriteLine("I'm inside AnotherClass");
    }
}


public class StartUp {
    private ICollection<IMyInterface> _interfaces = new Collection<IMyInterface>();

    private static void Main(string[] args) {
        new StartUp();
    }

    public StartUp() {
        AddToWatchlist(new AnotherClass());
        AddToWatchlist(new MyClass());
        AddToWatchlist(new MyClass());
        AddToWatchlist(new AnotherClass());
        Notify();
        Console.ReadKey();
    }

    private void AddToWatchlist(IMyInterface obj) {
        _interfaces.Add(obj);
    }

    private void Notify() {
        foreach (var myInterface in _interfaces) {
            myInterface.DoSomething();
        }
    }
}

输出:

I'm inside AnotherClass 
I'm inside MyClass 
I'm inside MyClass 
I'm inside AnotherClass

编辑:我刚刚意识到您将其标记为 Java。这是用 C# 编写的,但除了使用 ofArrayList而不是Collection.

于 2013-08-14T19:50:33.520 回答
2

一个接口定义了一个服务契约。简单来说,它定义你可以用一个类做什么。

例如,让我们使用一个名为ICount. 它定义了一个 count 方法,因此每个实现它的类都必须提供一个实现。

public interface ICount {
    public int count();
}

任何实现的类ICount,都应该重写该方法并给它一个行为:

public class Counter1 implements ICount {
    //Fields, Getters, Setters
    @Overide
    public int count() {
        //I don't wanna count, so I return 4.
        return 4;
    }
}

另一方面,Counter2对应该做什么有不同的看法count

public class Counter2 implements ICount {
    int counter; //Default initialization to 0
    //Fields, Getters, Setters
    @Overide
    public int count() {
        return ++count;
    }
}

现在,您有两个实现相同接口的类,那么,您如何平等对待它们呢?很简单,通过使用他们共享的第一个公共类/接口:ICount.

ICount count1 = new Counter1();
ICount count2 = new Counter2();
List<ICount> counterList = new ArrayList<ICount>();
counterList.add(count1);
counterList.add(count2);

或者,如果您想保存一些代码行:

List<ICount> counterList = new ArrayList<ICount>();
counterList.add(new Counter1());
counterList.add(new Counter2());

现在,在包含实现该接口的对象的列表中counterList包含两个不同类型但具有相同接口 in common( ) 的对象。ICounter您可以遍历它们并调用方法countCounter1将返回0whileCounter2将根据您调用的次数返回结果count

for(ICount current : counterList)
    System.out.println(current.count());
于 2013-08-14T20:00:08.430 回答
0

关键是要有一个列表来存储每次实例化实现接口的类。该列表必须在与接口和实现它的类不同的级别上可用。换句话说,编排或控制的类将拥有该列表。

接口是一种将实现留给实现接口的类的契约。类实现接口遵守该契约并实现方法而不是覆盖它们。

取接口为

 public interface Model {
        public void onUpdate();
        public void onClick();
       }       

    public class plugin implements Model {

        @Override
        public void onUpdate() {
            System.out.println("Pluging updating");

        }

        @Override
        public void onClick() {
            System.out.println("Pluging doing click action");

        }
    }

您的控制器类将是实例化和控制动作的类

 public class Controller {

    public static void orchestrate(){
        List<Model> modelList = new ArrayList<Model>();
        Model pluginOne  = new plugin(); 
        Model plugTwo  = new plugin();
        modelList.add(pluginOne);
        modelList.add(plugTwo);

        for(Model model:modelList){
            model.onUpdate();
            model.onClick();
        }
    }
}

您可以拥有另一个名为 pluginTwo 的实现,将其实例化,将其添加到列表中并调用其上接口指定的方法。

于 2013-08-14T20:07:43.120 回答
0

您不能从碰巧同时实现某个接口的所有对象中调用方法。反正你不会想要的。但是,您可以使用多态性通过接口名称来引用所有这些对象。例如,与

interface A { }
class B implements A { }
class C implements A { }

你可以写

A b = new B();
A c = new C();
于 2013-08-14T19:49:46.470 回答
0

接口不是这样工作的。它们的行为就像一些类可以使用的某种掩码。例如:

public interface Data {
    public void doSomething();
}

public class SomeDataStructure implements Data {
    public void doSomething()
    {
        // do something
    }
}

public static void main(String[] args) {
    Data mydataobject = new SomeDataStructure();
}

这使用了Data几个类可以使用并具有某些功能的“掩码”,但是您可以使用不同的类来实际实现该功能。

于 2013-08-14T19:51:25.083 回答