面向对象
面向对象已经很熟悉了,基本上就一句话总结,类是虚指,对象是类的实例
对象内容
- 类 − 定义了一件事物的抽象特点。类的定义包含了数据的形式以及对数据的操作
- 对象 − 是类的实例
- 成员变量 − 定义在类内部的变量。该变量的值对外是不可见的,但是可以通过成员函数访问,在类被实例化为对象后,该变量即可称为对象的属性
- 成员函数 − 定义在类的内部,可用于访问对象的数据
例如1
2
3$mercedes = new Car ();
$bmw = new Car ();
$audi = new Car ();
类定义
定义类通常语法格式如下:1
2
3
4
5
6
7
8
9
10
class phpClass {
var $var1;
var $var2 = "constant string";
function myfunc ($arg1, $arg2) {
[..]
}
[..]
}
类使用class关键字后加上类名定义
类名后的一对大括号内可以定义变量和方法
类的变量使用var来声明,也可以直接初始化值
函数定义不变,但是函数只能通过实例化的类来使用
1 |
|
- $this 代表自身的对象
- PHP_EOL为换行符
创建对象
创建对象使用new关键字来实例化1
2
3$runoob = new Site;
$taobao = new Site;
$google = new Site;
调用成员方法
1 | // 调用成员函数,设置标题和URL |
完整演示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
class Site {
/* 成员变量 */
var $url;
var $title;
/* 成员函数 */
function setUrl($par){
$this->url = $par;
}
function getUrl(){
echo $this->url . PHP_EOL;
}
function setTitle($par){
$this->title = $par;
}
function getTitle(){
echo $this->title . PHP_EOL;
}
}
$runoob = new Site;
$taobao = new Site;
$google = new Site;
// 调用成员函数,设置标题和URL
$runoob->setTitle( "菜鸟教程" );
$taobao->setTitle( "淘宝" );
$google->setTitle( "Google 搜索" );
$runoob->setUrl( 'www.runoob.com' );
$taobao->setUrl( 'www.taobao.com' );
$google->setUrl( 'www.google.com' );
// 调用成员函数,获取标题和URL
$runoob->getTitle();
$taobao->getTitle();
$google->getTitle();
$runoob->getUrl();
$taobao->getUrl();
$google->getUrl();
运行结果1
2
3
4
5
6菜鸟教程
淘宝
Google 搜索
www.runoob.com
www.taobao.com
www.google.com
构造函数
使用 _construct(mixed $args[,$…])来定义构造函数
1 | function __construct( $par1, $par2 ) { |
用法与C++一样
析构函数
使用_destructor来定义析构函数1
2
3
4
5
6
7
8
9
10
11
12
13
class MyDestructableClass {
function __construct() {
print "构造函数\n";
$this->name = "MyDestructableClass";
}
function __destruct() {
print "销毁 " . $this->name . "\n";
}
}
$obj = new MyDestructableClass();
析构函数如果没有特别操作可以不写,系统会自动调用终结对象生命周期
继承
使用extends关键字来继承一个类,PHP为单继承语言1
2
3class Child extends Parent {
// 代码部分
}
继承的类会拥有被继承类的所有函数和方法,除构造和析构函数
方法重写
如果父类继承的方法不能满足子类的需求,就可以对其进行重写,也可以称为覆盖1
2
3
4
5
6
7
8
9function getUrl() {
echo $this->url . PHP_EOL;
return $this->url;
}
function getTitle(){
echo $this->title . PHP_EOL;
return $this->title;
}
访问控制
和C++基本一直,都有三个访问控制
- public 公有
- protected 受保护
- private 私有
属性的访问控制
如果使用var定义,则默认为公有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
/**
* Define MyClass
*/
class MyClass
{
public $public = 'Public';
protected $protected = 'Protected';
private $private = 'Private';
function printHello()
{
echo $this->public;
echo $this->protected;
echo $this->private;
}
}
$obj = new MyClass();
echo $obj->public; // 这行能被正常执行
echo $obj->protected; // 这行会产生一个致命错误
echo $obj->private; // 这行也会产生一个致命错误
$obj->printHello(); // 输出 Public、Protected 和 Private
/**
* Define MyClass2
*/
class MyClass2 extends MyClass
{
// 可以对 public 和 protected 进行重定义,但 private 而不能
protected $protected = 'Protected2';
function printHello()
{
echo $this->public;
echo $this->protected;
echo $this->private;
}
}
$obj2 = new MyClass2();
echo $obj2->public; // 这行能被正常执行
echo $obj2->private; // 未定义 private
echo $obj2->protected; // 这行会产生一个致命错误
$obj2->printHello(); // 输出 Public、Protected2 和 Undefined
方法的访问控制
方法和函数基本一致
没有设置关键字,则默认为公有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
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
/**
* Define MyClass
*/
class MyClass
{
// 声明一个公有的构造函数
public function __construct() { }
// 声明一个公有的方法
public function MyPublic() { }
// 声明一个受保护的方法
protected function MyProtected() { }
// 声明一个私有的方法
private function MyPrivate() { }
// 此方法为公有
function Foo()
{
$this->MyPublic();
$this->MyProtected();
$this->MyPrivate();
}
}
$myclass = new MyClass;
$myclass->MyPublic(); // 这行能被正常执行
$myclass->MyProtected(); // 这行会产生一个致命错误
$myclass->MyPrivate(); // 这行会产生一个致命错误
$myclass->Foo(); // 公有,受保护,私有都可以执行
/**
* Define MyClass2
*/
class MyClass2 extends MyClass
{
// 此方法为公有
function Foo2()
{
$this->MyPublic();
$this->MyProtected();
$this->MyPrivate(); // 这行会产生一个致命错误
}
}
$myclass2 = new MyClass2;
$myclass2->MyPublic(); // 这行能被正常执行
$myclass2->Foo2(); // 公有的和受保护的都可执行,但私有的不行
class Bar
{
public function test() {
$this->testPrivate();
$this->testPublic();
}
public function testPublic() {
echo "Bar::testPublic\n";
}
private function testPrivate() {
echo "Bar::testPrivate\n";
}
}
class Foo extends Bar
{
public function testPublic() {
echo "Foo::testPublic\n";
}
private function testPrivate() {
echo "Foo::testPrivate\n";
}
}
$myFoo = new foo();
$myFoo->test(); // Bar::testPrivate
// Foo::testPublic
接口
使用interface来定义接口
与定义类的方法唯一不同的就是,在接口中的所有方法都是空的,而且必须为公有的,这是接口的特性
使用implements来实现接口
1 |
|
常量
可以把在类中始终保持不变的值定义为常量。在定义和使用常量的时候不需要使用$符号
使用const关键字来定义常量1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class MyClass
{
const constant = '常量值';
function showConstant() {
echo self::constant . PHP_EOL;
}
}
echo MyClass::constant . PHP_EOL;
$classname = "MyClass";
echo $classname::constant . PHP_EOL; // 自 5.3.0 起
$class = new MyClass();
$class->showConstant();
echo $class::constant . PHP_EOL; // 自 PHP 5.3.0 起
抽象类
使用abstract关键字来定义抽象类
抽象方法只能在抽象类中定义,抽象类中可以定义非抽象的方法
被定义为抽象类,不能实例化为对象,必须通过继承来在子类中实现方法
1 |
|
运行结果1
2
3
4ConcreteClass1
FOO_ConcreteClass1
ConcreteClass2
FOO_ConcreteClass2
static关键字
static就是静态的,使用方法基本就与C++一致,可以直接访问不实例化类
静态属性不能通过一个类已实例化的对象来访问,静态方法可以
静态属性一旦定义,值就不可以再改变,并且生命周期只有程序结束时随着程序生命周期结束而结束
1 |
|
运行结果1
2foo
foo
final关键字
如果父类中有方法被声明为final,则子类无法覆盖该方法
如果一个类被声明为final,则不能被继承
调用父类构造方法
要执行父类的构造方法,需要在子类的构造方法中调用parent::__construct()
1 | <?php |
运行结果1
2
3
4BaseClass 类中构造方法
BaseClass 类中构造方法
SubClass 类中构造方法
BaseClass 类中构造方法
总结
1.PHP的面向对象基本与C++一致,含义也基本相同,不多说
2.调用父类的构造函数需要使用parent::__construct()
3.静态属性一旦定义,值就不可以再改变,并且生命周期只有程序结束时随着程序生命周期结束而结束
4.PHP继承时没有访问控制之分,默认为public,继承父类中除了private的所有属性和方法