简体   繁体   English

名称与类名不同的构造方法

[英]Constructor with name different to the class name

In Java, is it possible to have two constructors of the same class with different names? 在Java中,是否可能具有相同名称的两个相同类的构造函数? For example, let's say I have the class Test , I would like to have something like this 例如,假设我有Test类,我想拥有这样的东西

class Test
    HashMap<Integer,Double> hsI;
    HashMap<Double,Double> hsD;

    Test() {
        hsi = new HashMap<>();
    }

    Test2() {
        hsi = new HashMap<>();
        hsD = new HashMap<>();
    }
}

Edit: I'm going to explain why I would like this. 编辑:我将解释为什么我想要这个。

I have a class like this, let's call it Class1 : 我有一个这样的课程,我们称之为Class1

public class Class1 {
private HashMap<Integer,ClassContainer> hm;

private class ClassContainer {

    ClassContainer {
    hm1 = new HashMap<>();
    hm2 = new HashMap<>();
    hm3 = new HashMap<>();
    }

    HashMap<Double,Double> hm1;
    HashMap<Double,Double> hm2;
    HashMap<Double,Double> hm3;

... //more code
    }

So I want to do a few subclasses of Class1 , but in this classes I don't need all the hashmaps of ClassContainer , I want to save space. 所以我想做一些Class1子类,但是在这些类中,我不需要ClassContainer所有哈希图,我想节省空间。 For example, Class2 will extend Class1 but will only need hm2; 例如,Class2将扩展Class1,但只需要hm2; Class3 will extend Class1 but will only need hm2 and hm3. Class3将扩展Class1,但只需要hm2和hm3。

I would like a way to initialise just the necessary parts of ClassContainer to save memory. 我想要一种初始化ClassContainer的必要部分以节省内存的方法。 And I want to use subclasses because they share a lot of code. 我想使用子类,因为它们共享许多代码。

No, a constructor must have the same class name. 否,构造函数必须具有相同的类名。 The closest thing you can do is inheritance: 您可以做的最接近的事情是继承:

class Test {
   HashMap<Integer, MyObject> hsI; // a map has two type arguments

   Test() {
      hsi = new HashMap<>();
   }
}

class Test2 extends Test {
   HashMap<Double, MyObject> hsD;

   Test2() {
      super();
      hsD = new HashMap<>();
   }
}

No, it is not. 不它不是。 Constructors must have the same name as the class, and must return nothing. 构造函数必须与该类具有相同的名称,并且不得返回任何内容。 However, their signatures can change in the amounts and types of arguments. 但是,它们的签名可以更改参数的数量和类型。 You could do, for example the following: 您可以执行以下操作:

class Test {
    HashMap<Integer> hsI;
    HashMap<Double> hsD;

    Test() {
       hsi = new HashMap<>();
    }

    Test(int i) {
        hsi = new HashMap<>();
        hsD = new HashMap<>();
    }
}

However, it seems like you want to have inheritance (a subclass of Test called Test2 that has hsD .) 但是,似乎您想要继承( Test名为Test2的子类,它具有hsD

if you have multiple contstructors, i recommend to use a Factory class instead. 如果您有多个构造函数,我建议改用Factory类。 Here you can add multiple static functions that are returning a new instance of this class. 在这里,您可以添加多个静态函数,这些函数将返回此类的新实例。

This is always recommended when using multiple constructors because you can give the methods any name you want. 在使用多个构造函数时,始终建议这样做,因为您可以为方法指定任何名称。

It is impossible to declare two constructors with different names. 不能声明两个具有不同名称的构造函数。 However, you can have two constructors with different parameters: 但是,可以有两个带有不同参数的构造函数:

class Test 
HashMap<Integer> hsI;
HashMap<Double> hsD;

    Test() {
       hsi = new HashMap<>();
    }

    Test2(String exampleArg) {
        hsi = new HashMap<>();
        hsD = new HashMap<>();
    }
}

In the example above, exampleArg is a dummy argument that is simply meant to distinguish the two constructors. 在上面的示例中, exampleArg是一个伪参数,仅用于区分两个构造函数。

You can't. 你不能

What you can do is provide static builder methods instead (which can have any names). 您可以做的是改为提供静态生成器方法(可以使用任何名称)。 You'll end up with multiple constructors, but you can make them private and only expose the static builders: 您将获得多个构造函数,但可以将它们设为私有,并且仅公开静态构造器:

class Test {
    private final Set<Integer> ints;
    private final Set<Double> doubles;

    private Test(Set<Integer> ints) {
        this(ints, null);
    }
    private Test(Set<Integer> ints, Set<Double> doubles) {
        this.ints = ints;
        this.doubles = doubles;
    }

    public static Test test1() {
        return new Test(new HashSet<Integer>());
    }
    public static Test test2() {
        return new Test(new HashSet<Integer>(), new HashSet<Double>());
    }
}

Then you can call use that like: 然后,您可以像这样使用:

Test test1 = Test.test1();
Test test2 = Test.test2();

I also took the liberty to fix a couple of typos in your code: a map takes two generic arguments, it's always better to define a reference as the most abstract type possible (use Map and Set instead of HashMap / HashSet when declaring your reference types). 我还自由地修复了代码中的几个拼写错误:映射有两个通用参数,将引用定义为最抽象的类型总是更好(在声明引用类型时使用MapSet而不是HashMap / HashSet )。

You should use inheritance. 您应该使用继承。 If you want to be picky, use a factory. 如果要挑剔,请使用工厂。

Regards, 问候,

Javier B. 哈维尔·B。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM