为什么面向对象编程中需要构造函数?

5

我刚接触面向对象编程,还处于学习阶段。

为什么我们需要构造函数?我们可以通过编写“初始化函数”来初始化属性(变量)的值,为什么还要编写构造函数呢?

基本上,即使通过编写初始化变量的函数也能实现相同的结果,为什么我们还要编写构造函数呢?

8个回答

10
构造函数就是“初始化函数”。
不需要调用两个函数。
object = new Class;
object.initialize();

你只需要调用即可。
object = new Class();

构造函数中的逻辑可以与初始化函数中的逻辑完全相同,但更加整洁,避免您将函数命名为initialize(),我将其命名为initialize_variables(),其他人将其命名为init_vars()等......保持一致性是有用的。
如果您的构造函数非常大,仍然可能希望将变量初始化拆分为单独的函数,并从构造函数调用该函数,但那是一个特定的例外情况。

这并不完全正确。在许多编程语言中,构造函数不能调用其他构造函数,因此需要一个单独的初始化函数,该函数可以由外部调用或由每个构造函数重载调用。还有一些模式是对象预先构建,第一次使用时进行初始化。还有非常有用的模式,要求命名的静态工厂方法调用私有或受保护的构造函数。 - Xharlie
1
这是一个“标准”之外的例外情况,您可能希望使用单独的函数来初始化变量(或执行每个对象实例共享的其他处理)。这并不会削弱构造函数的实用性,也不意味着应该用变量初始化函数替换构造函数。在特定情况下,没有任何阻止您将构造函数留空并调用其他函数,但这并不改变面向对象编程范式中构造函数的概念。 - Jon Story
1
我并不是在争论构造函数的无用性,只是认为构造函数 != 初始化方法。它们都有存在的理由。这个答案表明初始化方法永远不会超过重构工具,以便所有代码都不会捆绑到一个构造函数方法中。坦白地说,这并不是真的。 - Xharlie
是的,你说得对 :) 引用你的问题:“我们为什么需要构造函数”。初始化方法的一个用途是从构造函数中重构代码,我只是举了一个例子,说明为什么您仍然希望使用构造函数而已。这并不是详尽无遗的列表。无论如何,我已经解释了我的理由,我相信我们需要构造函数。 - Jon Story
这不是我的问题。我在我的评论之前发布了一个答案。请阅读它。如果你仍然认为我在争论构造函数是无用的,那我放弃了。你可以自由地想你喜欢的。 - Xharlie
显示剩余2条评论

5
答案很简单:为什么要写构造函数?因为在 C 语言中,可以这样写:`int i;`。在上面的例子中,如果像这样写,数据类型和变量定义了,如果你这样定义,那么内存就会分配给变量 `i`。因此,在这里我们定义类名和变量名(对象名),我们可以为类名分配内存。
例如:`myClass objectName;`
但是,在 C++ 中,`new` 关键字用于动态内存分配,所以我们可以为我们的类分配动态内存。在这里,我的例子中 `myClass` 是我们的类,我们想要分配到动态内存。
所以,
`myClass objectName = new myClass();`
构造函数只是为类变量分配内存的称呼。

3
构造函数的作用就是初始化变量/值。它是“初始化函数”。使用构造函数而不是普通函数来初始化变量的唯一原因是为了防止不同的人使用不同的函数名称,避免歧义,并且更容易使用构造函数,它会在类运行时自动实例化,而不必编写单独的代码进行实例化。这可能看起来很微小,似乎不需要太多的工作,但对于一个较大的程序来说,问题就很真实了。

2

通常将必须的内容放入构造函数中,将可选的内容放入Initialise函数中。

例如,考虑一个需要电源的放大器,它应该在构造函数中提供。逻辑上,您可能想要打开它并设置其功率级别,但有人可能会认为您可能要稍后再做这件事。伪代码如下:

class Amplifier
{
    public Amplifier(PowerSource powerSource)
    {
        // create amplifier...
    }

    public int PowerLevel;

    public void Initialise()
    {
        // turn on...
    }
}

上面的例子有些幼稚,但它说明了其中的概念。然而,这总是一个设计问题,不同的人有不同的意见。
然而,某些类的对象在构造阶段必须执行明显的设置操作。在这些情况下,需要构造函数的要求非常容易理解。例如,如果您的对象可能需要可变数量的内存,则构造函数是分配内存的逻辑位置,析构函数或终结器是释放内存的逻辑位置。

1
即使您不使用构造函数,每当您创建对象时,语言翻译器都会隐式调用它。为什么?
原因是它用于对象初始化,这意味着我们在类内部声明的变量(实例)将被初始化为它们的默认值。
class Person {
    //Class have two parts
    //1.Data(instance variable)
    //2.Methods(Sub-routine)
    String name;
    int age;
  }
  public class Stack{
      public static void main(String[] args){
         Person person1 = new Person();
         System.out.println("Name: "+person1.name);
         System.out.println("Age: " + person1.age);
      }
  }

输出- 名字: null 年龄: 0

“null”和“0”是默认值,由默认构造函数隐式设置。


1
当我们通过创建实例或对象来初始化类时,构造函数会自动调用。每次创建对象时需要执行大量代码时,这非常有帮助。
最好的构造函数用法可以在创建“图形用户界面”时看到。在为应用程序构建GUI时,我们需要将GUI设计代码和应用程序的业务逻辑分开。在这种情况下,我们可以在构造函数中编写用于设计GUI的代码,并在各自的方法中编写业务逻辑。这使代码整洁而清晰。
此外,当创建对象时,全局变量可以使用构造函数将它们初始化为默认值。如果不初始化全局变量,则编译器将使用默认构造函数隐式地进行初始化。
因此,构造函数是一个非常明智的概念,起初可能会显得奇怪,但随着你编写更多的代码,你会意识到它的重要性。

0

因为构造函数的作用就是为了避免使用“初始化函数”。

此外,您可以拥有任意数量的构造函数:只需提供一些参数即可,具体取决于您想要如何初始化对象。


1
关于“所有构造函数都调用Object类的构造函数”的说法并不适用于所有编程语言,有些语言没有根Object类,而其他语言则可以选择不同的Object类。 - mmmmmm
你是对的,我已经考虑了你的评论。 - Makoto
对象构造不是多态。 - mmmmmm

0

构造函数是一种特殊的成员函数,其名称与类名相同,并在创建该类的对象时调用。它们用于初始化对象中的数据字段。

构造函数具有以下属性:

  1. 它与类名相同。

  2. 每当创建类的对象时都会调用它。

  3. 它没有返回类型,甚至没有void。
  4. 它可以有参数。
  5. 构造函数可以重载。
  6. 当编译器在类中找不到任何构造函数时,将自动创建默认构造函数。
  7. 带参数的构造函数可以使用this()方法调用默认构造函数。
  8. 构造函数可以为静态数据字段初始化而是静态的。
  9. 它不会被隐式继承。

更多信息请参见https://en.wikipedia.org/wiki/Constructor_(object-oriented_programming)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接