【问题标题】:Constructor overloading same arguments构造函数重载相同的参数
【发布时间】:2014-07-02 04:20:38
【问题描述】:

假设我有 2 个字段的类:x 和 y,类型为 double。是否可以定义 2 个构造函数,因此构造函数 1 将创建对象,将其 x 属性设置为构造函数中的参数,将 y 设置为默认值,反之亦然?

public class Test {

    private int x;
    private int y;

    public Test(int x) {
        this.x = x;
    }

    public Test(int y) {
        this.y = y;
    }
}

我正在尝试类似的方法,但我知道它不会工作,因为规则过载

【问题讨论】:

  • 你可以这样做,但你需要一些第二个参数来区分重载。此时,您可能只想将两个参数设为xy

标签: java constructor overloading


【解决方案1】:

不,你不能那样做。通常你会做这样的事情:

private Test(int x, int y) {
    this.x = x;
    this.y = y;
}

public static Test fromX(int x) {
    return new Test(x, 0);
}

public static Test fromY(int y) {
    return new Test(0, y);
}

即使您没有有重载问题,您也可能需要考虑这种模式(公共静态工厂方法又调用私有构造函数) - 它清楚地说明了您的值的含义'正在传递的意思是。

【讨论】:

    【解决方案2】:

    不,您不能有两个具有相同签名的方法或构造函数。你可以做的是命名静态工厂。

    public class Test {
    
        private int x;
        private int y;
    
        private Test(int x, int y) {
            this.x = x;
            this.y = y;
        }
    
        public static Test x(int x) { return new Test(x, 0); }
        public static Test y(int y) { return new Test(0, y); }
    }
    
    Test x1 = Test.x(1);
    Test y2 = Test.y(2);
    

    【讨论】:

      【解决方案3】:

      不,x 和 y 具有相同的类型,因此两个构造函数将具有相同的类型签名,并且方法解析基于参数类型,而不是名称;编译器没有办法区分。

      无论参数名称是什么,编译器都会查找“Test.Test(int)”。

      该语言需要添加额外的功能,例如命名参数,才能执行您想要的操作。

      如果 Java 曾经使用 C# 之类的语法进行属性初始化,您将能够使用该惯用语,使用默认的无参数构造函数。

      除了使用显式工厂方法的替代方法之外,您还可以为您的参数传入一个 HashMap。

       public Test(HashMap<string,int> args) {
            if(args.containsKey("x"))
               x = args.get("x");
            if(args.containsKey("y"))
               y = args.get("y");
       }
      

      但在大多数情况下,静态工厂方法更简洁。如果您需要更多,您可能需要首先考虑为什么需要这样的习语,并修改您的类设计。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-09-14
        • 2017-07-28
        • 2012-07-22
        • 2012-11-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-05-23
        相关资源
        最近更新 更多