代码之家  ›  专栏  ›  技术社区  ›  unj2

为什么会有两个具有相同签名的构造函数?

  •  10
  • unj2  · 技术社区  · 15 年前

    有两个具有相同签名的构造函数的用例是什么?

    编辑:你不能在Java中这样做,因为有效Java说你需要静态工厂。但我想知道为什么你一开始就需要这样做。

    6 回复  |  直到 15 年前
        1
  •  15
  •   CPerkins    15 年前

    你这么做的原因 认为 您想这样做的是,您发现自己处于一种变量类型不足以满足上下文的情况下。

    例如,我可能会自欺欺人地认为我需要给我的点类两个构造函数:一个按x和y工作,另一个按度和弧度工作。两者都可以表示为浮动。

    所以我想我需要两个具有相同签名的构造函数(float,float)。

    布洛赫博士指出,最好是制造工厂方法:

    
        public static Point newPointByDegreesAndRadians (float degrees, float radians);
        public static Point newPointByXandY (float x, float y);
    

    顺便说一下,工厂方法的另一个替代方法是创建类型,这些类型包含数据类型中缺少的上下文,如下所示:

    
        public class CoordinatesXY {
           float X;
           float Y;
           ...
        }
        public class CoordinatesDegreesRadians {
           float degrees;
           float radians;
           ...
        }
        public Point (CoordinatesXY coordinates) { ... }
        public Point (CoordinatesDegreesRadians coordinates) { ... }
    

    你认为这是否比工厂的方法更清楚,这是一个品味问题。对于这个特定的例子,我自己的感觉是,只有当您的设计使坐标独立于这些坐标的点时,这两个坐标类才有用。

        2
  •  11
  •   Gilbert Le Blanc    15 年前

    您想要两个(或更多)具有相同签名的构造函数的原因是数据类型不是意义的同义词。

    一个简单的例子是一个行类。

    这里有一个构造函数: public class Line(double x1, double y1, double x2, double y2)

    这里还有一个: public class Line(double x1, double y1, double angle, double distance)

    第一个构造函数定义一条线的两个端点。第二个构造函数定义一个端点,以及到第二个端点的角度和距离。

    Java无法区分两行类构造函数,为真。但有充分的理由让两个或多个构造函数具有相同的签名。

        3
  •  5
  •   akf    15 年前

    一个类不能有两个具有相同签名的构造函数。

    From the JLS :

    8.8.2施工单位签字

    在一个类中声明两个具有重写等效(_§8.4.2)签名的构造函数是一个编译时错误。在一个类中声明签名具有相同擦除(_§4.6)的两个构造函数是编译时错误。

        4
  •  3
  •   Steven Schlansker    15 年前

    为了回答你新编辑的问题,目的是如果你有一个类,它可以有两个逻辑上不同的动作,但恰好是相同的签名。

    例如,假设您有一个关注某人姓名和出生地的人类。

    public Person(String name) { ... }
    public Person(String placeOfBirth) { ... }
    

    显然,这行不通。

    你必须使用工厂:

    public static Person personWithName(String name) { ... }
    public static Person personFromPlace(String placeOfBirth) { ... }
    

    显然是人为的例子,但这是一般的想法…

        5
  •  2
  •   AaronM    15 年前

    你不会的,无论如何也不能。它不会将类文件编译成字节码,因为程序无法区分它们来决定使用哪个。

        6
  •  1
  •   DVK    15 年前

    KujaAn——即使有一个技术上有效的方法(Java中没有其他的答案),这样的想法也很少有用例。

    一个可能的用例是基于某些外部条件的不同的构造函数实现——例如,如果某个构造函数不可用,它可以分配某些内存;如果程序中的某个公共池可用,则可以重新使用该内存。

    另一个例子是一个构造函数,如果当前的体系结构支持该系统调用,它将使用更高效的系统调用来实现某些事情。顺便说一下,这两个例子在Java中都有点难以想象,但在C++领域更容易想象,但是你希望得到整体的想法。

    在任何一种情况下,这实际上都可以通过拥有您提到的工厂或具有单个构造函数进行编码,后者实现某种基于环境的决策,并调用具有不同签名的辅助方法来实际执行所需的依赖于实现的初始化,例如(在伪代码中,独立于语言)。

    function helper_initializer(signature for case 1) {
    
    }
    function helper_initializer(signature for case 2) {
    
    }
    function constructor() {
       // constructor logic here
       if (environmental_consdition() == 1) {
          this->helper_initializer(signature for case 1);
       } else {
          this->helper_initializer(signature for case 2);
       }
    }