【问题标题】:Java polymorphism - how to call same method in different classesJava多态-如何在不同的类中调用相同的方法
【发布时间】:2015-03-29 00:12:38
【问题描述】:

所以我正在用 java 制作一个游戏,并且我的对象都具有 2 种方法; update()render()

在游戏循环所在的主类中,我必须为每个可更新和可渲染的对象调用 update()render() 方法。
有什么方法可以设置某种形式的接口,我可以在其中调用方法一次,它会在所有实现的对象中调用它?

【问题讨论】:

  • 是的。如果您想要默认实现,则称为interfaceabstract class。或者如果您使用 Java 8,则使用两个 interfaces 和 default 方法。
  • 为了澄清:您是否希望能够进行单个方法调用,该方法调用将在实现该接口的类对象的每个实例上调用 #update
  • 是的,这正是我想要实现的目标。到目前为止,我在其他响应中看到的唯一问题是,如果我要创建一个名为“World”的类和另一个名为“Player”的类,我希望这两个类都有 update() 和 render()方法。如果我在“世界”对象中创建了一些“玩家”对象,然后在我的主“游戏”类中创建了一个“世界”对象,我将如何从“游戏”类中用两个更新“玩家”对象像 objects.update() 和 objects.render() 这样的简单方法调用?
  • 你需要使用复合模式。详情请查看here

标签: java inheritance interface polymorphism


【解决方案1】:

其他答案都是正确的,但是使用composite pattern会更好:

public interface GameComponent {

    void render();

    void update();
}

public abstract class ChildComponent implements GameComponent {

    protected ContainerComponent parent; // (see below)

    // getter and setter for parent
}

public class ContainerComponent implements GameComponent {

    protected List<GameComponent> children = new ArrayList<>();

    public void add(GameComponent child) {
        this.children.add(child);
        child.setParent(this);
    }

    @Override
    public void update() {
        for (GameComponent c : this.children) {
            c.update();
        }
    }

    @Override
    public void render() {
        for (GameComponent c : this.children) {
            c.render();
        }
    }

}

然后你实现你的特定GameComponents 以便它们扩展ChildComponentContainerCompoenent

public class Player extends ChildComponent {

    @Override
    public void update() {
        // update player
    }

    @Override
    public void render() {
        // render player
    }

}

public class World extends ContainerComponent {

    @Override
    public void update() {
        super.update(); // update world's children (the player)
        // update the world (this can be done either after or before updating children,
        // you choose how to update your world)
    }

    @Override
    public void render() {
        super.render(); // render world's children (the player)
        // render the world (this can be done either after or before rendering children,
       // you choose how to render your world)
    }

}

然后,在你的主循环中:

// Create player and world
Player p = new Player();
World w = new World();

// Add player to world
w.add(p);

// Update everything
w.update();

// Render everything
w.render();

这样,您创建了GameComponents 的合成,然后您将update()render() 只是最顶层的ContainerComponent

【讨论】:

  • 非常感谢!太棒了。我会对此做一些进一步的研究以便更好地理解:)
【解决方案2】:

接口用于:

interface I {
    void render();
}

class A implements I {
     public void render() {
         // render an A object ...
     }
}

class B implements I {
     public void render() {
         // render an B object ...
     }
}

以及您可能拥有的任何地方

List<I> list = new ArrayList();
list.add(new A());
list.add(new B());

for(I i:list) {
    i.render();
}

A 类和 B 类的对象不同,但它们实现相同的协定(接口)。

【讨论】:

    【解决方案3】:

    这是面向对象编程的支柱之一,polymorphism

    基本上,您需要使用所需的方法定义一个接口。请注意,在 java 中,接口方法默认是公共的。

    public interface Renderable {
      void render();
      void update();
    }
    

    然后你定义实现。要实现一个接口,您需要使用“implements”关键字。在下面的示例中,您将看到“implements Renderable”

    public class MyRenderable implements Renderable {
      public void render() {
         ... // method impl
      }
    
      public void update() {
         ... // method impl
      }
    }
    

    最后,您创建一个实例并通过接口调用方法。

    Renderable r = new MyRenderable();
    r.render();
    r.update();
    

    从这里您可以使用您的界面类型填充一个列表。您可以遍历该列表,从接口调用方法,调用实现。

    【讨论】:

    • 好的,但是如果我创建另一个名为 MySecondRenderable 的类,它也实现了 Renderable,并在 MyRenderable 类中创建了一个 MySecondRenderable 对象。如何从我初始化 Renderable r = new MyRenderable() 的地方调用 MySecondRenderable 对象的 render() 和 update() 方法?
    • @Phil 请查看我的回答,该回答完全符合您的要求。
    【解决方案4】:

    接口的主要用途之一是实现多态性,或对多个不同对象执行相同操作的能力。例如,如果不同的对象都实现了相同的接口并具有相同的方法,则可以将所有这些对象存储在 Vector/List 中,并通过对每个对象调用该方法的 Vector 进行迭代。

    根据您的要求:

        interface I {
        void render();
        void update();
       }
    
    class first implements I {
         public void update(){
           // doWhaterver you want to do 
         }
         public void render() {
             // doWhaterver you want to do 
         }
    }
    
    class second implements I {
         public void update(){
           // doWhaterver you want to do 
         }
         public void render() {
             // doWhaterver you want to do 
         }
    }
    

    现在将它们添加到列表中

    List<I> list = new ArrayList();
    list.add(new first());
    list.add(new second());
    
    for(I i:list) {
        i.update();
        i.render();
    }
    

    它将调用实现的函数,即多态

    【讨论】:

      猜你喜欢
      • 2012-08-11
      • 1970-01-01
      • 2013-08-30
      • 1970-01-01
      • 1970-01-01
      • 2016-12-23
      • 2022-11-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多