【问题标题】:is it possible to use an interface to speak to another class in java?是否可以使用接口与 java 中的另一个类对话?
【发布时间】:2015-11-27 20:29:05
【问题描述】:

假设我有 A 类和 B 类以及一个名为 Message 的接口

public interface Message{
   public void sendMessage();
}

public class A implements Message{
   @Override
    public void sendMessage(){
      //call the sendMessage() in class B.
    }
}

public class B implements Message{
    @Override
     public void sendMessage(){
       System.out.println("Hola Stack!");
      }

 }

如果没有对 B 类的直接引用,我能以某种方式从 A 类调用 B 类中的 sendMessage() 方法吗?

【问题讨论】:

  • 首先,您需要在 ClassA 中定义一个变量,以便引用 ClassB 对象。不要将变量类型化为ClassB,而是将ot 类型化为Message,然后使用ClassB 的实例对其进行初始化,可能通过DI 来确保A 不知道B
  • 这类问题可以使用event bus来解决。这样发送者不需要知道(或关心)谁在接收消息,但仍然可以在接收类中触发动作(例如 B 监听 A,当它看到消息时,它会调用自己的 sendMessage() 方法) .

标签: java oop design-patterns interface


【解决方案1】:

当然可以。

class ClassA {
    private Message message;

    public ClassA(Message message) {
        this.message = message:
    }

    public void sendMessage() {
        message.sendMessage();
    }
}

只需将 B 的实例传递给 A:

Message b = new ClassB();
Message a = new ClassA(b);
a.sendMessage();

【讨论】:

    【解决方案2】:

    您在这里有点滥用接口。当然,你可以使用

        Message a = new B();
    `   a.sendMessage();
    

    这会做你想做的事,但不是你想要的做法,也不是你想要的。如果你希望 A 和 B 可以互换,你应该像这样创建 A 超类并让 B 从它继承,删除接口:

    public class A {
    
        public void sendMessage(){
          //call the sendMessage() in class B.
        }
    }
    
    public class B extends A{
        @Override
         public void sendMessage(){
           System.out.println("Hola Stack!");
          }
    
     }
    

    这样你就可以做到:

    A a = new B();
    a.sendMessage(); //  prints inside of B, but you tell the JVM to forget it is B, and think it is A
    

    请记住,如果您希望类可互换,则子​​类必须具有 A 的所有功能,并且您不能使用 A 中未定义的 B 功能(作为具体方法或抽象方法)

    【讨论】:

      【解决方案3】:

      您至少可以使用这两种设计模式来解决您的问题:

      • 观察者
      • 调解员

      根据您的应用程序的用例,一个可能比另一个更好,但两者都解决了对象之间的高耦合问题。它们之间的区别在于,观察者模式将引入“观察者”和“主题”对象,而中介者将封装对象之间的通信。您可以使用两个接口为您的解决方案组合这两种模式,如下例所示:

      import java.util.*; 
      
      public class TestAB {
      
          public static void main(String args[]) {
      
              Mediator messageBus = new Mediator();
      
              ClassA objA = new ClassA();
      
              ClassB objB = new ClassB();
              messageBus.register("ClassB", objB);
      
              objA.sendMessage(messageBus, "ClassB", "Hello class B!");
          }
      }
      
      class ClassA {
      
          public void sendMessage(Mediator bus, String dest, String text) {
              // send message to the sendMessage() in class B.
              bus.sendMessage(new Message() {
                  public String getDestination() { return dest; }
                  public String getText() { return text; }
              });
          }
      
      }
      
      class ClassB implements Observer {
      
          public void sendMessage(Message msg){
              System.out.println("sendMessage from ClassB received: "+ msg.getText());
          }
          public String getId(){
              return "B";
          }
          public void onMessage(Message msg) {
              // listen to message calls from the message bus (Mediator)
              sendMessage(msg);
          }
      }
      
      interface Message {
          public String getDestination();
          public String getText();
      }
      
      interface Observer {
          public String getId();
          public void onMessage(Message msg);
      }
      
      class Mediator {
          Map<String, Observer> observerList = new HashMap<String, Observer>();
          protected void register(String id, Observer obj) {
              observerList.put(id, obj);
          }
          protected void sendMessage(Message msg) {
              Observer obj = observerList.get(msg.getDestination());
              obj.onMessage(msg);
          }
      }
      

      所有想要接收消息的类都需要实现Observer接口,本例中B实现了Observer接口,当有消息到达时调用自己的“sendMessage”方法。最后,我们创建了一个带有中介对象(消息总线)的 TestAB 类,负责将消息从 A 传递到 B 对象。

      为了简单起见,我尽量避免对实现进行一些改进,如果您想了解更多关于这些模式的信息,可以在以下链接中获得更多信息

      https://sourcemaking.com/design_patterns/mediator

      【讨论】:

        猜你喜欢
        • 2017-02-07
        • 1970-01-01
        • 1970-01-01
        • 2011-09-16
        • 1970-01-01
        • 1970-01-01
        • 2020-10-31
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多