当前位置: 首页 > 知识库问答 >
问题:

构造函数重载-Java中的最佳实践[已关闭]

蒋健
2023-03-14

构造函数也可以像任何其他方法一样重载,我知道这一事实。由于一项任务,我决定使用具有多个构造函数的抽象超类:

抽象超类:

protected ListSortierer()
{
  this( null, null );
}

protected ListSortierer( List<E> li )
{
  this( li, null );
}

protected ListSortierer( Comparator<E> comp )
{
  this( null, comp );     
}

protected ListSortierer( List<E> li, Comparator<E> com )
{
  this.original = Optional.ofNullable( li );
  this.comp = Optional.ofNullable( com );
}

为了访问这些构造函数中的每一个,我还需要子类中的多个构造函数。

泡泡ort.java:

public ListBubbleSort()
{
  super();
}

public ListBubbleSort( List<E> li )
{
  super( li );
}

public ListBubbleSort( Comparator<E> com )
{
  super( com );
}

public ListBubbleSort( List<E> li, Comparator<E> com )
{
  super( li, com );
}

在这种情况下,子类的每个构造函数都立即调用超类的构造函数。我突然想到,我可以再次引用自己的构造函数并传递null值:

public ListBubbleSort()
{
  this( null, null );
}

public ListBubbleSort( List<E> li )
{
   this( li, null );
}

public ListBubbleSort( Comparator<E> com )
{
   this( null, com );
}

public ListBubbleSort( List<E> li, Comparator<E> com )
{
   super( li, com );
}

这样做将允许我省略抽象超类中的3个重载构造函数,但会强制每个子类遵循相同的模式。

我的问题是:在一致性的情况下,什么是更好的方法?处理抽象超类或子类中的缺失值?它对实例化有什么不同,还是只是一个意见问题?

共有3个答案

曾典
2023-03-14

这样做将允许我省略抽象超类中的3个重载构造函数,但会强制每个子类遵循相同的模式

通过抽象方法或接口实现契约。你不能确定每个子类都会有这些构造函数,或者至少你不能确定每个子类都会正确地添加这些构造函数。

因此,考虑到封装,这些构造函数在超类中的表现更好。

龙嘉玉
2023-03-14

关于问题本身:我认为这两种选择都不理想。

您努力编写尽可能少的代码。您在添加重载时很小心,因为它们看起来很方便。事实上,你应该做相反的事情:认真思考你真正的用例是什么,并且只支持那些。

在您的例子中,整个练习的重点似乎是允许使用不同的实现进行排序。从这个意义上讲,你更应该研究一下战略模式。

换句话说:你的第一个想法总是喜欢组合而不是继承。当您的设计导致您遇到此类问题时,更好的答案可能是从您当前的设计中退一步,找到一种方法,将不同的排序作为某种“服务”来启用,而不是将列表本身放在一起进行排序。

秦德海
2023-03-14

在一致性的情况下,什么是更好的方法?

>

  • 使所有子构造函数私有。
  • 介绍静态工厂方法。

    ListBubbleSort.withList(List<E> list)
    ListBubbleSort.withComparator(Comparator<E> comparator)
    

    调用适当的super构造函数。不要传递任何nulls。

    public static <E> ListBubbleSort withList(List<E> list) {
        return new ListBubbleSort(list);
    }
    
    private ListBubbleSort(List<E>) {
        super(list);
    }
    
    protected ListSortierer(List<E>) {
        // initialise only the list field
        this.origin = list;
    }
    

    不要使用可选作为字段。

    这个。原始=可选。不可抗力(李)

    如果有3个参数,请考虑构造器模式。

    处理抽象超类或子类中缺少的值?

    构造函数应该提供初始值。您没有传递初始值,只是指示它们不存在。

    默认情况下,null是引用类型的初始值。因此,如果未给出字段的值,则无需重新分配字段。

    它对实例化有什么不同,还是只是一个意见问题?

    可读性,维护。

    我推荐阅读约书亚·布洛赫的《有效Java》:

    创建和销毁对象

    • 第1项:考虑静态工厂方法而不是构造函数
    • 第2项:当面对许多构造函数参数时考虑一个构建器

  •  类似资料:
    • 问题内容: 有一些类似的话题,但我找不到一个有足够答案的。 我想知道Java中构造函数重载的最佳实践是什么。关于这个问题我已经有了自己的想法,但我想听听更多的建议。 我指的是简单类中的构造函数重载和继承已重载类(意味着基类具有重载构造函数)时的构造函数重载。 问题答案: 虽然没有“官方指导方针”,但我遵循亲干原则。使重载构造函数尽可能简单,最简单的方法是它们只调用this(…)。只需要检查一次参数

    • 问题内容: 有一些与此类似的话题,但是我找不到一个足够答案的话题。 我想知道Java中构造函数重载的最佳实践是什么。我已经对这个主题有自己的想法,但是我想听听更多的建议。 我既指的是简单类中的构造函数重载,也指继承已经重载的类时的构造函数重载(这意味着基类具有重载的构造函数)。 谢谢 :) 问题答案: 虽然没有“官方指南”,但我遵循KISS和DRY的原则。使重载的构造函数尽可能简单,最简单的方法是

    • 问题内容: 对于直接构造函数和设置 程序的Java 参数,是否存在标准可接受的约定? (我已经看到了C ++的答案,但是两个社区之间的实践通常有所不同) 假设我有一个带有foo字段的C类。 我通常看到以下三个选项: 1)使用带下划线的实际字段名称: 2)使用实际的字段名称,只需在设置中使用“ this”: 3)完全不一致的事情,例如: 我倾向于使用2,但我想知道什么是正确的做法。 问题答案: 选项

    • null 我不太确定如何处理我的代码,以下是我得到的: 我只是不知道我应该打什么。我相信我已经完成了第一个重载构造函数,但我对此还是新手。 那么,我应该做些什么来使重载构造函数工作呢? 我对Java和面向对象编程非常陌生。

    • 本文向大家介绍C++中构造函数重载,包括了C++中构造函数重载的使用技巧和注意事项,需要的朋友参考一下   当类中没有定义构造函数时,C++编译器自动提供无参构造函数和拷贝构造函数   当类中定义了任意的拷贝构造函数,C++不提供无参构造函数。 系统自动提供的构造函数   无参构造函数      函数体为空   拷贝构造函数      简单的进行成员变量的值复制      Test t1;    

    • 这个问题是由打字错误或无法再复制的问题引起的。虽然类似的问题可能在这里是主题,但这个问题的解决方式不太可能对未来的读者有所帮助。 Java构造函数不工作。 我需要制作三个构造函数和一个打印方法。然后制作三个对象并打印它们。如果我在标题中写的问题有误,请原谅我。我几乎不知道我的代码是怎么回事。但它就在这里。谁能告诉我它有什么问题以及我如何解决它。 下面是错误:Minor.java:51:错误:没有为