Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 绑定和分派的关系是什么?它们是一样的吗?_Java_Oop - Fatal编程技术网

Java 绑定和分派的关系是什么?它们是一样的吗?

Java 绑定和分派的关系是什么?它们是一样的吗?,java,oop,Java,Oop,我在一些参考资料中看到,动态分派和后期绑定是相同的。如果是这样的话,绑定应该等于调度。在某些地方,它们将重载/早期绑定/静态调度声明为相同,将覆盖/后期绑定/动态调度声明为相同 所以我想出了一个类比来理解这一点下面的类比正确吗?或者我如何修改下面的解释 我们的班级结构如下 class Board { public void show(){}; } class Shape{ public void draw(Board board) {}; } class Square ext

我在一些参考资料中看到,动态分派和后期绑定是相同的。如果是这样的话,
绑定
应该等于
调度
。在某些地方,它们将
重载/早期绑定/静态调度
声明为相同,将
覆盖/后期绑定/动态调度
声明为相同

所以我想出了一个类比来理解这一点下面的类比正确吗?或者我如何修改下面的解释

我们的班级结构如下

class Board {
    public void show(){};
}

class Shape{
    public void draw(Board board) {};
}

class Square extends Shape {
    public void draw(Board board) {
        System.out.println("Drawing a Square");
    };
}

class Circle extends Shape {
    public void draw(Board board) {
        System.out.println("Drawing a Circle");
    };
}
我们有:

Shape shape = createShape(type); // This will return any of Shape, Square, Circle
shape.draw(board);
Board myBoard = new Board();
myBoard.show();
我们有:

Shape shape = createShape(type); // This will return any of Shape, Square, Circle
shape.draw(board);
Board myBoard = new Board();
myBoard.show();
我想不出什么解释

绑定:确定
形状
的实际类型(可以是形状、正方形或圆形)。假设只有在运行时才知道
形状
的类型,那么它就是
后期绑定
。可以在编译时决定
myBoard
的类型。这是早期绑定

调度:决定
绘图
的实际实施被视为
调度
。假设
draw
的实际实现只能在运行时决定,则为
动态调度
,否则,如果可以在编译时决定,则称为
静态调度

静态分派:当我在编译时知道调用方法时将执行哪个函数体时发生。因此
myBoard.show()
,这里可以静态调度方法
show
。其中
shape.draw(board)
我们不能静态地分派
draw
,因为我们不能保证在运行时执行哪个函数体

单一分派(动态):将仅根据
形状
的类型选择
绘图
的实现,而不考虑
的类型或值

多重分派(动态):将执行的
绘图操作由
形状
的类型共同决定。(在这种情况下,它是双重分派

我使用的资源很少:


最后回答这个问题:

绑定和分派是不同的

  • 绑定通常指将符号解析为某个值/对象/实现。例如,赋值语句
    x=42
    将符号
    x
    绑定到表达式
    42
    的值。在Java中,类型名始终可以在编译时解析

  • 分派(或者更准确地说是调用分派或方法分派)是将方法调用(或函数调用)解析为方法实现的一种绑定。对于静态分派或早期绑定,可以在编译时知道该调用的目标;对于方法调用的动态分派或后期绑定,可以在运行时选择目标

    接口方法或虚拟方法(Java中的默认方法)使用动态分派。最终方法、私有方法和静态方法是有效的静态调度(尽管严格来说,JVM仍然必须解析调用)

我还将很快提到,表达式的静态类型是静态已知或“声明”的表达式类型,而动态类型是该表达式的运行时值的实际类型。例如,当我们声明一个变量
Board b
时,
b
的静态类型是
Board
类,但动态类型可能是
Board
或其任何子类–在为其分配特定对象之前,我们不知道。动态分派的方法可以在动态类型已知后立即绑定(假设在Java中是基于类型的单一分派)

您的
myBoard.show()
示例使用虚拟方法,通常会动态调度:
myBoard
声明为具有type
Board
或任何
Board
-子类。如果您将类或
show()
声明为final,则会发生更改。实际上,此特定示例可以优化为静态调度,因为您在同一范围内构造了
newboard()
,因此
myBoard
的动态类型是已知的。但这只是一种优化

相反,您的
createShape().draw()
示例显然是动态分派,因为调用方不知道
createShape()
的动态类型

您对单次派送/多次派送的理解基本正确

我想指出,“分派”在解析函数调用的一般意义上并不一定局限于类型。我们还可以使用if/elses中的逻辑来调度调用。考虑这个例子,根据x和y的值,我们将一个<代码>象限(x,y)< /COD>调用到一个类似于东北的特定象限。从语言的角度来看,这是静态分派,但从程序员的角度来看,其行为更像静态分派

class Quadrants {
  ...
  public static void quadrant(int x, int y, String value) {
    // dispatch a call with a x→east, y→north coordinate system
    if (x >= 0) {
      if (y >= 0) {
        quadrantNE(value);
      } else {
        quadrantSE(value);
      }
    } else {
      if (y >= 0) {
        quadrantNW(value);
      } else {
        quadrantSW(value);
      }
    }
  }
  private static void quadrantNE(String value) { ... }
  private static void quadrantNW(String value) { ... }
  private static void quadrantSE(String value) { ... }
  private static void quadrantSW(String value) { ... }
}

在后台,语言运行时也只需使用一些逻辑来执行动态调度,特别是对于多调度。基于类型的单一分派(如Java中的实例方法调用,其中静态类型是一个类)可以通过简单的表查找(vtable dispatch)实现,并且不需要复杂的逻辑。

“如果是这样的话,
绑定
应该等于
分派
”——我不会这么说。“绑定”是指将标识符与方法相关联。“调度”是指进行实际呼叫。但是,如果您“绑定得晚”,那么就没有必要分派到静态决定的方法。如果您“提前绑定”,您没有选择余地,您必须在编译时选择一个方法。那么,延迟绑定实际上是动态调度吗?关于上述解释,你能说些什么