【问题标题】:Java inheritance with threads confusionJava继承与线程混淆
【发布时间】:2020-01-09 10:45:21
【问题描述】:

我在这里检查使用继承和线程的代码。

下面有一个 BaseCom 和 ServerCom 类。 ServerCom 类扩展了 BaseCom 类。 BaseCom 类实现了一个名为 Com 的接口。

public class BaseCom implements Com
{
   protected final Thread thread;
   protected final InetSocketAddress socketAddress;


   public BaseCom(InetSocketAddress socketAddress)
   {
      System.out.println("BaseCom CONSTRUCTOR!!!!");
      this.socketAddress = socketAddress;
      thread = new Thread(() -> run(socketAddress));
   }

   @Override
   public void start()
   {
      System.out.println("HELLO FROM BaseCom start method!!!!");
      thread.start();
   }

   protected void run(InetSocketAddress socketAddress)
   {
      System.out.println("HELLO FROM BaseCom run!!!!");
   }

   //.... more stuff .... not shown here 
}

lll

public class ServerCom extends BaseCom
{

   public ServerCom(InetSocketAddress socketAddress, long timeOutMs)
   {
      super(socketAddress);
      System.out.println("ServerCom CONSTRUCTOR!!!!");

   }

   @Override
   protected void run(InetSocketAddress socketAddress)
   {
      System.out.println("ServerCom run method!!!!");
   }
   // ... more stuff.. not shown here
}

为什么当我从 main 函数运行以下代码时,实际上执行的是 ServerCom 类的 run 方法而不是 basecom 类的 run 方法?

thread = new Thread(() -> run(socketAddress)); 行在 BaseCom 类而不是 ServerCom 类中的事实让我认为它应该是被调用的 Basecom 运行方法。

connectorA = new ServerCom(socketAddressA, 1000000);
connectorA.start();

【问题讨论】:

    标签: java multithreading inheritance interface base-class


    【解决方案1】:

    run(...) 的调用在运行时解决(dynamic dispatch)。由于这个BaseCom的实际类型是ServerCom,所以ServerComrun(...)被执行。如果 BaseComrun(...) 方法被覆盖,则无法强制调用它(因为它被覆盖,原始方法无法访问)。

    问题与多线程无关。

    【讨论】:

    • “没有办法强制调用 BaseCom 的 run(...) 方法”,如果你可以使方法成为最终方法,则可以。
    • @AndyTurner true,但是您不能覆盖该方法;)
    • 我还是不能完全理解这一点。我了解 OO 编程中方法调用的动态解析,但是这里的 run() 方法在 Basecom 类中被调用/分配? "new Thread(() -> run(socketAddress)" ,这个stage怎么知道使用ServerCom的run()方法?
    • 让我们了解一下技术:java 中的 lambda 是匿名内部类的语法糖。在该类中,您调用一个方法run(...) - 它不存在。由于它是一个内部类,编译器在外部类中寻找一个方法run(...)——它确实存在。因此,来自封闭类的方法run(...) 被调用——如果需要,可以调用this.run(...)。但是,引用 this 有一个类型 - 在您的情况下为 ServerCom。与这种类型相关的是它的所有方法——继承和覆盖。因此,在您的情况下,this.run(...) 导致执行ServerComrun(...)-方法
    猜你喜欢
    • 1970-01-01
    • 2011-04-25
    • 1970-01-01
    • 2012-09-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-20
    • 2011-12-30
    相关资源
    最近更新 更多