首页 > PHP教程 > PHP类与对象的使用

PHP面向对象编程

面向对象编程(Object Oriented Programming, OOP, 面向对象程序设计)是一种计算机编程架构。

OOP 的一条基本原则是计算机程序是由单个能够起到子程序作用的单元或对象组合而成。

OOP 达到了软件工程的三个目标:重用性、灵活性和扩展性。类是面向对象中的重要概念,而封装和继承是面向对象的重要特点

class

每个类的定义都以关键字 class 开头,后面跟着类名,后面跟着一对花括号,里面包含有类的属性与方法的定义。

类名可以是任何非 PHP 保留字的合法标签。一个合法类名以字母或下划线开头,后面跟着若干字母,数字或下划线。

 一个类可以包含有属于自己的常量,变量(属性)和函数(方法)。

简单的类定义

1
2
3
4
5
6
7
8
9
10
11
 <?php
class phpClass
{
    // 属性
    public $var = 'value';
    // 方法
    public function displayVar() {
        echo $this->var;
    }
}
?>

当一个方法在类定义内部被调用时,有一个可用的伪变量 $this。$this 是一个到主叫对象的引用(通常是该方法所从属的对象,但如果是从第二个对象静态调用时也可能是另一个对象)。 

 

new

要创建一个类的实例,必须使用 new 关键字。类应在被实例化之前定义(某些情况下则必须这样)。 

如果在 new 之后跟着的是一个包含有类名的字符串,则该类的一个实例被创建。如果该类属于一个名字空间,则必须使用其完整名称。

创建一个实例

1
2
3
4
5
6
<?php
$instance = new SimpleClass();
// 也可以这样做:
$className = 'Foo';
$instance = new $className(); // Foo()
?>

在类定义内部,可以用 new self 和 new parent 创建新对象。

当把一个对象已经创建的实例赋给一个新变量时,新变量会访问同一个实例,就和用该对象赋值一样。此行为和给函数传递入实例时一样。可以用克隆给一个已创建的对象建立一个新实例。

 对象赋值

1
2
3
4
5
6
7
8
9
10
<?php
$instance = new SimpleClass();
$assigned   =  $instance;
$reference  =& $instance;
$instance->var = '$assigned will have this value';
$instance = null; // $instance and $reference become null
var_dump($instance);
var_dump($reference);
var_dump($assigned);
?>

以上例程会输出:

NULL

NULL

object(SimpleClass)#1 (1) {

   ["var"]=>

     string(30) "$assigned will have this value"

}

PHP 5.3.0 引进了两个新方法来创建一个对象的实例: 

创建新对象 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<?php
class Test
{
    static public function getNew()
    {
        return new static;
    }
class Child extends Test
{} 
$obj1 = new Test();
$obj2 = new $obj1;
var_dump($obj1 !== $obj2); 
$obj3 = Test::getNew();
var_dump($obj3 instanceof Test); 
$obj4 = Child::getNew();
var_dump($obj4 instanceof Child);
?>

以上例程会输出: 

bool(true)

bool(true)

bool(true)

 

extends

一个类可以在声明中用 extends 关键字继承另一个类的方法和属性。PHP不支持多重继承,一个类只能继承一个基类。

被继承的方法和属性可以通过用同样的名字重新声明被覆盖。但是如果父类定义方法时使用了 final,则该方法不可被覆盖。可以通过 parent:: 来访问被覆盖的方法或属性。

当覆盖方法时,参数必须保持一致否则 PHP 将发出 E_STRICT 级别的错误信息。但构造函数例外,构造函数可在被覆盖时使用不同的参数。

简单的类继承

1
2
3
4
5
6
7
8
9
10
11
12
13
<?php
class ExtendClass extends SimpleClass
{
    // Redefine the parent method
    function displayVar()
    {
        echo "Extending class\n";
        parent::displayVar();
    }
}
$extended = new ExtendClass();
$extended->displayVar();
?>

以上例程会输出: 

Extending class

a default value

 

::class

自 PHP 5.5 起,关键词 class 也可用于类名的解析。使用 ClassName::class 你可以获取一个字符串,包含了类 ClassName 的完全限定名称。这对使用了 命名空间 的类尤其有用。

类名的解析

1
2
3
4
5
6
7
<?php
namespace NS {
    class ClassName {
    }    
    echo ClassName::class;
}
?>

以上例程会输出:

NS\ClassName

 

属性

类的变量成员叫做“属性”。属性声明是由关键字 public,protected 或者 private 开头,然后跟一个普通的变量声明来组成。属性中的变量可以初始化,但是初始化的值必须是常数,这里的常数是指 PHP 脚本在编译阶段时就可以得到其值,而不依赖于运行时的信息才能求值。

在类的成员方法里面,可以用 ->(对象运算符):$this->property(其中 property 是该属性名)这种方式来访问非静态属性。静态属性则是用 ::(双冒号):self::$property 来访问

当一个方法在类定义内部被调用时,有一个可用的伪变量 $this。$this 是一个到主叫对象的引用(通常是该方法所从属的对象,但如果是从第二个对象静态调用时也可能是另一个对象)。

属性声明

1
2
3
4
5
6
7
8
<?php
class SimpleClass
{
   // 正确的属性声明
   public $name = "a";
   public $id = 1;
}
?>

 

类常量 

可以把在类中始终保持不变的值定义为常量。在定义和使用常量的时候不需要使用 $ 符号。

常量的值必须是一个定值,不能是变量,类属性,数学运算的结果或函数调用。

接口(interface)中也可以定义常量。

自 PHP 5.3.0 起,可以用一个变量来动态调用类。但该变量的值不能为关键字(如 self,parent 或 static)。

定义和使用一个类常量

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?php
class MyClass
{
    const constant = 'constant value'
    function showConstant() {
        echo  self::constant . "\n";
    }
}
echo MyClass::constant . "\n"
$classname = "MyClass";
echo $classname::constant . "\n"; // 自 5.3.0 起 
$class = new MyClass();
$class->showConstant(); 
echo $class::constant."\n"; // 自 PHP 5.3.0 起
?>

 

Final 关键字

PHP 5 新增了一个 final 关键字。如果父类中的方法被声明为 final,则子类无法覆盖该方法。如果一个类被声明为 final,则不能被继承。

Final 方法示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?php
class BaseClass {
   public function test() {
       echo "BaseClass::test() called\n";
   }   
   final public function moreTesting() {
       echo "BaseClass::moreTesting() called\n";
   }
class ChildClass extends BaseClass {
   public function moreTesting() {
       echo "ChildClass::moreTesting() called\n";
   }
}
// Results in Fatal error: Cannot override final method BaseClass::moreTesting()
?>

Final 类示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?php
final class BaseClass {
   public function test() {
       echo "BaseClass::test() called\n";
   }   
   // 这里无论你是否将方法声明为final,都没有关系
   final public function moreTesting() {
       echo "BaseClass::moreTesting() called\n";
   }
class ChildClass extends BaseClass {
}
// 产生 Fatal error: Class ChildClass may not inherit from final class (BaseClass)
?>

属性不能被定义为 final,只有类和方法才能被定义为 final。

 

Static(静态)关键字

static 关键字来定义静态方法和属性。static 也可用于定义静态变量以及后期静态绑定。

声明类属性或方法为静态,就可以不实例化类而直接访问。静态属性不能通过一个类已实例化的对象来访问(但静态方法可以)。

由于静态方法不需要通过对象即可调用,所以伪变量 $this 在静态方法中不可用。

静态属性不可以由对象通过 -> 操作符来访问。

用静态方式调用一个非静态方法会导致一个 E_STRICT 级别的错误。

静态属性只能被初始化为文字或常量,不能使用表达式。所以可以把静态属性初始化为整数或数组,但不能初始化为另一个变量或函数返回值,也不能指向一个对象。

静态属性示例 

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
<?php
class Foo
{
    public static $my_static = 'foo'
    public function staticValue() {
        return self::$my_static;
    }
class Bar extends Foo
{
    public function fooStatic() {
        return parent::$my_static;
    }
print Foo::$my_static . "\n"
$foo = new Foo();
print $foo->staticValue() . "\n";
print $foo->my_static . "\n";      // Undefined "Property" my_static  
print $foo::$my_static . "\n";
$classname = 'Foo';
print $classname::$my_static . "\n"; // As of PHP 5.3.0 
print Bar::$my_static . "\n";
$bar = new Bar();
print $bar->fooStatic() . "\n";
?>

静态方法示例

1
2
3
4
5
6
7
8
9
10
<?php
class Foo {
    public static function aStaticMethod() {
        // ...
    }
Foo::aStaticMethod();
$classname = 'Foo';
$classname::aStaticMethod(); // 自 PHP 5.3.0 起
?>

PHP函数、对象定义与使用

关闭
感谢您的支持,我会继续努力!
扫码打赏,建议金额1-10元


提醒:打赏金额将直接进入对方账号,无法退款,请您谨慎操作。