构造函数 ,是一种特殊的方法。主要用来在创建对象时初始化对象, 即为对象成员变量赋初始值,总与new运算符一起使用在创建对象的语句中。特别的一个类可以有多个构造函数 ,可根据其参数个数的不同或参数类型的不同来区分它们 即构造函数的重载。
1.构造函数的命名必须和类名完全相同。在java中普通函数可以和构造函数同名,但是必须带有返回值;
2.构造函数的功能主要用于在类的对象创建时定义初始化的状态。它没有返回值,也不能用void来修饰。这就保证了它不仅什么也不用自动返回,而且根本不能有任何选择。而其他方法都有返回值,即使是void返回值。尽管方法体本身不会自动返回什么,但仍然可以让它返回一些东西,而这些东西可能是不安全的;
3.构造函数不能被直接调用,必须通过new
运算符在创建对象时才会自动调用;而一般的方法是在程序执行到它的时候被调用的;
5.构造函数有回滚的效果,构造函数抛出异常时,构造的是一个不完整对象,会回滚,将此不完整对象的成员释放(c++)
6.当一个类只定义了私有的构造函数,将无法通过new关键字来创建其对象,当一个类没有定义任何构造函数,C#编译器会为其自动生成一个默认的无参的构造函数。
C++构造函数
C++语言为类提供的构造函数可自动完成对象的初始化任务,全局对象和静态对象的构造函数在main()函数执行之前就被调用,局部静态对象的构造函数是当程序第一次执行到相应语句时才被调用。然而给出一个外部对象的引用性声明时,并不调用相应的构造函数,因为这个外部对象只是引用在其他地方声明的对象,并没有真正地创建一个对象。
C++的构造函数定义格式为:
class <类名>
{
public:
<类名>(参数表)
//...(还可以声明其它成员函数)
};
<类名>::<函数名>(参数表)
{
//
函数体
}
如以下定义是合法的:
class T
{
public:
T(int a=0){i=a;}//构造函数允许直接写在类定义内,也允许有参数表。
private:int i;
};
如果一个类中没有定义任何的构造函数,那么
编译器只有在以下三种情况,才会提供默认的构造函数:
2、如果类的基类有构造函数(可以是用户定义的构造函数,或编译器提供的
默认构造函数);
3、在类中的所有非静态的对象
数据成员,它们对应的类中有构造函数(可以是用户定义的构造函数,或编译器提供的默认构造函数)。
<类名>::<类名>(){},即不执行任何操作。
例子
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
|
#include <iostream>
using
namespace
std;
class
time
{
public
:
time
()
//constructor.构造函数
{
hour=0;
minute=0;
sec=0;
}
void
set_time();
void
show_time();
private
:
int
hour,minute,sec;
};
int
main()
{
class
time
t1;
t1.show_time();
t1.set_time();
t1.show_time();
return
0;
}
void
time
::set_time()
{
cin>>hour>>minute>>sec;
}
void
time
::show_time()
{
cout<<hour<<
":"
<<minute<<
":"
<<sec<<endl;
}
|
程序运行情况:
0:0:0
10 11 11 回车
10:11:11
任何时候,只要创建类或结构,就会调用它的构造函数。类或结构可能有多个接受不同参数的构造函数。构造函数使得程序员可设置默认值、限制实例化以及编写灵活且便于阅读的代码。
构造函数
void
__construct( [mixed args [, ...]] )
php 5 允行开发者在一个类中定义一个方法作为构造函数。具有构造函数的类会在每次创建对象时先调用此方法,所以非常适合在使用对象之前做一些初始化工作。
注:如果子类中定义了构造函数则不会暗中调用其父类的构造函数。要执行父类的构造函数,需要在子类的构造函数中调用
parent::__construct()。
例子 19-6. 使用新标准的构造函数
1
2
3
4
5
6
7
8
9
|
<?php
classBaseClass{
function__construct(){
print
"InBaseClassconstructor/n"
;}}
classSubClassextendsBaseClass{
function__construct(){
parent::__construct();
print
"InSubClassconstructor/n"
;}}
$obj
=newBaseClass();
$obj
=newSubClass();
?>
|
为了实现向后兼容性,如果 php 5 在类中找不到
__construct()函数,它就会尝试寻找旧式的构造函数,也就是和类同名的函数。因此唯一会产生兼容性问题的情况是:类中已有一个名为
__construct()的方法,但它却又不是构造函数。
void
__destruct( void )
php 5 引入了析构函数的概念,这类似于其它面向对象的语言,如 C++。析构函数会在到某个对象的所有引用都被删除或者当对象被显式销毁时执行。
例子 19-7. 析构函数示例
<?php
class MyDestructableClass {
function __construct() {
print "In constructor/n";
$this->name = "MyDestructableClass";
}
function __destruct()
{
print "Destroying " . $this->name . "/n";
}
}
$obj = new MyDestructableClass();
?>
和构造函数一样,父类的析构函数不会被引擎暗中调用。要执行父类的析构函数,必须在子类的析构函数体中显式调用
parent::__destruct()。
注:析构函数在脚本关闭时调用,此时所有的头信息已经发出。
注:试图在析构函数中抛出一个异常会导致致命错误。
构造函数的声明与其它操作的声明一样,只是其名称必须是两个下划线__construct( )。这是PHP5中的变化;PHP4的版本中,构造函数的名称必须与类名相同。为了向下兼容,如果一个类中没有名为__construct( )的方法,PHP将搜索一个与类名相同的方法。
格式:function __construct ( [参数] ) { ... ... }
例子:
<?php
class person{
public $name;
public $age;
function _ _construct(){ // 构造函数
$this->name="lisi";
$this->age=28;
}
function say(){
echo "my name is ".$this->name."<br>";
echo "my age is ".$this->age."<p>";
}
}
$per=new person();
$per->say();
$per->name="zhangsan";
$per->age=26;
$per->say();
?>
C#构造函数例子
构造函数是在创建给定类型的对象时执行的类方法。构造函数具有与类相同的名称,它通常初始化新对象的
数据成员。
在下面的示例中,使用一个简单的构造函数定义了名为 Taxi 的类。然后使用 new
运算符来实例化该类。在为新对象分配内存之后,new运算符立即调用 Taxi 构造函数。
publicclass Taxi
{
public bool isInitialized;
public Taxi()
{
isInitialized = true;
}
}
class TestTaxi
{
static void Main()
{
Taxi t = new Taxi();
System.Console.WriteLine(t.isInitialized);
}
}
javascript实例
在本例中,我们将展示如何使用 constructor 属性。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
|
<
html
>
<
body
>
<
script
type
=
"text/javascript"
>
var test=newBoolean();
if(test.constructor==Array)
{
document.write("ThisisanArray");
}
if(test.constructor==Boolean)
{
document.write("ThisisaBoolean");
}
if(test.constructor==Date)
{
document.write("ThisisaDate");
}
if(test.constructor==String)
{
document.write("ThisisaString");
}
</
script
>
</
body
>
</
html
>
|
JAVA例子
public class UserManagerImpl implements UserManager {
private UserDao userDao;
public UserManagerImpl(UserDao userDao){
this.userDao=userDao;
}
public void save(String username,String password){
this.userDao.save(username, password);
}
}
注意: 由于Java不允许像C++那样为函数的参数提供
缺省值,因此在构造函数中也不能使用缺省值.
构造函数的特点:
1.它的函数名与类名相同;
2.它可以重载;
3.不能指定返回类型,即使是void也不行;
4.虽然在一般情况下,构造函数不被显式调用,而是在创建对象时自动被调用。但是并不是不能被显式调用。有些时候是一定要显式调用的,只要是父类有带参的构造函数,在子类中就必须显式的调用父类的构造函数,因为子类的构造器在实例化时无法找到父类的构造函数(当父类有自己写的无参构造函数时,子类也不用显式调用)。