构造函数作用是啥

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了构造函数作用是啥相关的知识,希望对你有一定的参考价值。

构造函数的作用是在创建对象时进行初始化工作,最常见的就是对成员变量赋值。构造函数是一种特殊的成员函数,它的名字和类名相同,没有返回值,不需要用户调用,而是在创建对象时自动执行。

构造函数的作用就是用来实例化的,打个比方:就是将画在图纸上的高楼模型变成真实的建筑。在这个例子中this指的就是point。它用来区分是point的x还是传进来的x(也就是括号里的x)。

拓展资料:

构造函数的功能主要用于在类的对象创建时定义初始化的状态。它没有返回值,也不能用void来修饰。这就保证了它不仅什么也不用自动返回,而且根本不能有任何选择。

参考技术A

拷贝构造函数是程序更加有效率,因为它不用再构造一个对象的时候改变构造函数的参数列表。设计拷贝构造函数是一个良好的风格,即使是编译系统提供的帮助你申请内存默认拷贝构造函数。

构造函数是在创建给定类型的对象时执行的类方法。构造函数具有与类相同的名称,它通常初始化新对象的数据成员。

拓展资料

构造函数(constructor)是一种特殊的方法 。主要用来在创建对象时初始化对象, 即为对象成员变量赋初始值,总与new运算符一起使用在创建对象的语句中 。

参考技术B 这个问题这么长时间没有合适的回答么?要搞清这个问题,首先要清楚构造函数的意义:构造函数并不是为了“初始化类”,至少不完全是。不然它就会改叫“Initializer”而不是“Constructor”。构造的内涵比初始化要丰富。尽管大多数情况下,我们对类的构造内容限于给它的属性赋值,但这仅仅是对简单的使用场景。对于复杂的设计模式,构造函数还要完成其他任务,从抽象的类去“建设”一个功能化的实例。比如依赖注入,最流行的模式就是使用构造函数。
假设你的类要使用一个服务,这个服务的作用是在类的方法工作时记录一些日志。但是日志的记录有可能会写在文本文件中、数据库中或直接打印在屏幕上。但是我们知道SOLID设计原则要求我们的类不应该知道这些细节,我们只要在需要调用日志功能的时候使用类似ILog.Write()之类的方法。那么这个ILog服务怎么“来到”我们的实例当中呢?假如你用属性赋值的方法,看上去可行,但是你会发现我们还是“知道”了这个ILog服务实例的存在,这破坏了SOLID原则,你在“使用服务”这外增加了“获取服务”这一不相关的任务,这时候就可以使用构造函数,在构造函数的参数中传入(ILog logService)这样一个实例,交给一个私有成员_logService,然后在类中使用_logService.Write()就好了。你可能会说,这不是换汤不换药吗?你把属性赋值变成了传参,不还是得写成ctor(logService);这样,logService哪来呢?这时候就要更进一步使用诸如Autofac之类的IOC类库,去完成依赖的注册。不过这些话题就有些远了。
总的来说,构造函数的意义在于“实例化一个具体功能的类”,这当然包括了“初始化”的部分,你可以查阅一些扩展资料,看看“初始化”之外的部分有多么神奇。
参考技术C 在对象编程语言中,一般在定义了一个类型之后,为了能使用它,必须把这个类型具体化,也就是指定为一个具体的对象。而构造函数就是从定义出发,建立与定义相对应的对象。用计算机语言来说,光有定义是不能使用,必须通过构造函数来分配内存空间给可使用的对象。 参考技术D 构造函数你也别想的太复杂,他起的作用你可以看作是初始化对象。
也就是说,当你实例一个对象的时候,肯定会先去执行构造函数,其实就是初始化该对象内部定义的属性。
当然就像你说的,你完全可以不用构造函数,在实例化对象以后,给其赋值也是可以的。
这个看个人开发的习惯和需求了。

记录文件、类和构造函数的正确方法是啥?

【中文标题】记录文件、类和构造函数的正确方法是啥?【英文标题】:What is the proper way to document files, classes and constructors?记录文件、类和构造函数的正确方法是什么? 【发布时间】:2011-08-10 03:52:58 【问题描述】:

为构造函数和类以及仅包含单个类的文件一致地编写注释块的最有用/最标准/最不令人惊讶的方法是什么?

类的注释块,而不是构造函数 构造函数的注释块,而不是类 构造函数和类的注释块 -> 在这种情况下,每个应该包含什么样的细节?

然后是文件本身?如果它只包含一个类,它是否需要一个注释块?那里应该有哪些细节?

我想尽量避免类、构造函数和文件注释块之间的重复。

【问题讨论】:

(相关) What are the valid and readable approaches to commenting in php5 语法“正确方式”由工具完成解析后生成的最终用户文档的外观定义。这在很大程度上是实现定义的。文档内容的质量取决于用户在使用之前是否仍需阅读源代码。 -- 此外,IDE 自动完成友好的文档语法的奖励积分。 【参考方案1】:

这在很大程度上取决于您的背景以及与您共事的人或您之后的人的假定技能水平。

如果您发布一个框架、一个库或类似的东西,您通常会假设您的用户具有所有技能水平,因此您可能希望尽可能多地记录琐碎的废话以减少负载您的社区必须处理的问题。

让我从一个我认为文档可能是一个主要痛苦的例子开始。

绝对需要什么

如果你想使用 PHPDoc,你需要一个文件 doc 块,然后是另一个 doc 块(通常是类 doc 块)。

那些**需要*拥有@package 标签。其他一切都是可选的。

到目前为止,我会说即使@package 标签也是可选的,因为您可能能够为项目自动生成它。如果我没记错的话,PHPDoc 甚至可以让你为所有没有标签的东西设置一个默认包。

对于一般文档,让我从一个示例开始(一个更长的示例在末尾​​strong>):

你能解释多少次“uri”是什么意思:

请注意,对于getUri,它解释了 URI 的含义(只是为了在我假设的评论中讨论一些事情),而它不在 isAbsUri 中,因为您至少可以说“abs 意味着绝对”两次。


如果您不是开源项目(或需要提供COMPLETE!!!11eleven api 文档):

强烈建议使用适当、长且描述性的类、变量和方法名称而不是文档。

在 doc 块中再次写一些东西没有任何好处,因为它是 2011 年,我们有 120 个字符宽的终端和自动完成功能,所以不再需要为了保存一些字符而缩写所有内容。

我什至认为记录琐碎的事情会伤害您和您的团队,因为这会迫使您将时间浪费在没有人从您那里获得价值的事情上 养成总是编写琐碎文档而不阅读它们的习惯没有了。

一个好的注释应该解释为什么做某事,而代码本身应该解释如何做而不需要进一步的 cmets。

我最喜欢的冗余文档示例是这个:

class myClass 
/**
 * Constructor
 */
public function __construct() 

一些指导方针说你必须记录一切,你最终会让人一次又一次地陈述显而易见的事情。

这并没有增加任何价值,但在阅读代码时会浪费时间。

正确命名示例:

class Person  
/** 
 * Set a persons weight in Kilogram
 *
 * @param float $kg Weight in Kilogram
 */
public function setWeight($kg) 

此代码易于记录,因为您需要解释“kg”的含义,因为有些人可能使用不同的系统,而您无法在 Google 上搜索“kg”。

我赞成写作

class Person  
/** 
 * @param float $kilogram
 */
public function setWeight($kilogram) 

doc 块是多余的,因为在Person 上调用setWeight 确实可以预期为一个人设置权重。不用再写出来了。

使用 $kilogramm 作为参数还可以省去在文档中解释它的麻烦,我想说,根据您的环境,如果每个人真的不知道测量值,都可以在谷歌上搜索“公斤”单位。


@PHPDoc 文档

当然都是我的拙见 如果您不使用类型提示,请始终使用@param 标签。 始终使用@return 标签 根本不要使用@author 标签。 Collection code ownership is more valuable 并且信息无论如何都在源代码控制存储库中。 仅在必要时使用@copyright 标签。我喜欢只拥有 LICENSE 文件,但我不是律师,所以可能有必要。

内联 cmets:

public function generateReport() 
  // get the db connection
  $reg = WhateverGlobalStorage::get(“db“);
  // auth
  if(!$reg->getOne("SELECT view_report FROM USER ...")) 
  // template
  $id = $reg->getOne("select ... "); 
  // render
  new ReportTemplate($id); // ...

如果这些是单独的“块”,只需将它们移动到描述性命名函数中

public function generateReport() 
  $this->checkAuthentication();
  $template = this->createReportTemplate();
  $this->renderReport($template);

// Not perfect but at least you can grasp what the method does much quicker

其他资源:

我在一些会议上就该主题发表的演讲幻灯片:Slideshare: clean-code-stop-wasting-my-time

还有一些更小的、更年长的咆哮:they-told-you-to-document-everything-they-lied

书籍参考:

Clean Code: A Handbook of Agile Software Craftsmanship

Refactoring: Improving the Design of Existing Code

一个更长的例子

abstract class xyzRequest 
 /**
   * Initializes this xyzRequest.
   *
   * Available options:
   *
   *  * logging: Whether to enable logging or not (false by default)
   *
   * @param  xyzEventDispatcher $dispatcher  An xyzEventDispatcher instance
   * @param  array  $parameters  An associative array of initialization parameters
   * @param  array  $attributes  An associative array of initialization attributes
   * @param  array  $options     An associative array of options
   *
   * @return bool true, if initialization completes successfully, otherwise false
   *
   * @throws <b>xyzInitializationException</b> If an error occurs while initializing this xyzRequest
   */
  public function initialize(xyzEventDispatcher $dispatcher, $parameters = array(), $attributes = array(), $options = array()) 

让我们逐行查看该文档告诉您的内容。 (我在这里开个玩笑来表达我的意思)

* Initializes this xyzRequest.

所以在 xyzRequest 上调用 ->initialize 会初始化该请求?真的吗?好吧,如果你这么说!

   * Available options:
   *
   *  * logging: Whether to enable logging or not (false by default)

我们被告知第三个参数的选项,而不是第二个或第三个参数的选项,但如果我们知道框架,也许我们知道那些? (由于我们无法弄清楚 ->initialize 在没有人告诉使用的情况下做了什么,我们可能没有那么聪明......)

   * @param  xyzEventDispatcher $dispatcher  An xyzEventDispatcher instance

是的,类型提示就在那里。因此,如果该方法需要一个“xyzEventDispatcher 实例”,我们需要传入一个“xyzEventDispatcher 实例”。很高兴知道。

   * @param  array  $parameters  An associative array of initialization parameters
   * @param  array  $attributes  An associative array of initialization attributes
   * @param  array  $options     An associative array of options

好的。所以它不是一个线性阵列。但是我需要将“初始化参数”传递给我本可以想出的“初始化”方法。

我仍然不知道我实际上需要在那里传递什么,但只要它记录在案就可以了!

   * @return bool true, if initialization completes successfully, otherwise false

所以布尔返回值是“真”表示“好”,“假”表示坏”。

   * @throws <b>xyzInitializationException</b> If an error occurs while initializing this xyzRequest
   */

所以如果我们在执行函数命名的过程中发生错误,就会抛出异常?

因此异常用于错误情况。好的。很高兴知道。

没有告诉我返回 false 和异常之间的区别。 @throws 自身很好,因为它添加了信息 顺便说一句:为什么这是粗体而不是@link

【讨论】:

【参考方案2】:

我个人认为类和方法文档是最重要的文档。当我编写代码时,当代码完成向我显示属于某个方法的文档时,我需要 IDE 的帮助。这样我可以很容易地找到我需要的方法。

由于我尝试将类的显式初始化保持在最低限度,因此我不使用构造函数 cmets。因此,我尽量避免使用构造函数本身。

方法或函数中的代码应尽可能清晰,使用声明性变量名称并使其尽可能小。只有当我做了一些意想不到的事情时,例如集成问题,我才会评论它们。

【讨论】:

【参考方案3】:

就我个人而言,我只会在构造函数中有什么特别的地方需要评论(比如特殊的初始化)。

我不会说这是“最有用”的方式,但它使代码保持整洁,并且实际上不需要重复两次相同的事情(如果你担心的话)。

【讨论】:

【参考方案4】:

评论所有内容 - 文件(作者、版权、描述等)、类(描述、代码示例)、方法和属性。 Here 是 phpDoc cmets 的一个很好的例子。

【讨论】:

-1 ZF 提供的文档数量对于公共框架是可行的,但不一定适用于每个应用程序。我还认为,关于 ctor 和 getter 和 setter 的简短描述是完全多余的。 @biakaveron 你的意思是说,特别是对构造函数、setter 和 getter 的简短描述会导致更容易的代码重用?如果有,为什么? @Rupert。我的意思不是用大文本块发表评论。如果代码很简单 - 使用短 cmets。但是,无论如何,总是评论它!现代 IDE 会自动生成一个 phpDoc 存根,所以您只需稍微修正一下即可。 评论不仅仅是描述。下面的@param cmets 将有助于理解构造函数参数。 IDE 代码建议也使用 phpDoc cmets。 那么,方法名应该类似于registerNewUserWithIdAndPasword()? :) 我更喜欢短名称和长 cmets。

以上是关于构造函数作用是啥的主要内容,如果未能解决你的问题,请参考以下文章

java 自定义构造方法,默认函数,看下面的例子,作用,区别,是啥?

Dart:这些方括号在构造函数中的作用是啥? [复制]

javascript:new Option(text, value),我想知道Option的构造函数是啥样的?

java中静态方法,静态变量,静态初始化器,构造函数,属性初始化都是啥时候调用的? 它们的先后顺序。

C#:如果一个类有两个构造函数,这些构造函数共享一些代码的最佳方式是啥? [复制]

记录文件、类和构造函数的正确方法是啥?