面向对象的PHP(5)

时间:2024-05-04 23:04:49

OOP的好处

  • 封装

封装可以隐藏实现细节,使代码模块化,代码重用

  • 继承

继承可以扩展已存在的代码模块(class),代码重用

  • 多态

为了类在继承和派生的时候,保证实例的某一属性正确调用,接口重用

关键的OOP概念

实体的性质和行为的具体定义称为类(class)

类用于表示要在应用程序中处理的实际事务

每个实体都包含一组性质和行为,在OOP中分别称为属性(property)和方法(method)

<?php
    //创建类
    class xiu {
        private name;
        private age;
        protected function kang(){
            echo "$this->name";
        }
        protected function sear(){
            echo "this->age";
        }
    }
?>

创建了一个名为xiu的类,定义了两个属性(name,age)和两个方法(kang,sear)

  • 对象

可以在类的基础上创建实体的特定实例,特定实例称为对象(object)

对象使用new关键字创建

//创建类名为xiu的对象
$xiu = new xiu();
  • 属性

明属性

在类开始处声明属性,此时可以为属性赋初始值

//声明两个属性(name,age)
class xiu {
    public name = "xiaoming";
    private age = 18;
}

属性可以不需要声明,可以由类对象同时创建和赋值(一般不建议)

用属性

与变量不同,属性要使用->操作符引用

xiu类包括属性name、age,如果创建了xiu的类型的对象就可以如下引用其属性

$xiu -> name;
$xiu -> age;

在定义属性类中引用属性时,还是使用 -> 操作符,但此时不使用相应的类名,而是使用$this关键字

$this表示要引用当前类中(要访问或操作的属性所在的类)的属性

function setName($name){
    $this -> name = $name;
}

性作用域

·public

可以通过在属性前面添加关键字public来声明公共作用域中的属性

class xiu{
    public $name = "user";//创建公共属性$name
}
//公共属性可以由相对应的对象直接操作和访问
$xiu = new xiu();//创建class为xiu的对象
$name = $xiu -> name;
echo "$name";//返回"user"

·private

private属性只能在定义属性的类中被访问,也不能由其子类使用

class xiu{
    private $name;//设置私有属性
    //私有属性必须使用公共接口来访问
    public function getName($name){//设置公共接口public
        echo $this -> name = $name;//将$name赋值给私有属性name并输出
    }
}
$xiu = new xiu();//创建对象
$xiu -> getName("user");//输出"user"

·protected

跟函数需要只在函数内部使用的变量一样,类也可以包含只在内部使用的属性称为保护属性(protected)

在继承的子类中也可以访问和操作保护属性(而private不能访问父类)

class xiu {
    protected $name;
}

·final

设置final作用域时,子类无法覆盖这个值

class xiu {
    final $name;
}

·static

静态类作用域(。。。)

__set()方法设置属性

class xiu {function __set($rongName,$rongValue){
         echo "$rongName";//返回属性名
         echo "$rongValue";//返回属性值
    }
}
$xiu = new xiu();
$xiu -> value = "user";//设置属性时,会自动调用__set()方法,返回 value user

可以使用以上方法扩展类

class xiu {function __set($rongName,$rongValue){
         $this -> $rongName = $rongValue;
    }
}
$xiu = new xiu();
$xiu -> value = "user";//添加一个属性

__get()方法获取属性

class xiu {
    private $name = "user";
    function __get($rongName){
        return $this -> $rongName;
    }
}
$xiu = new xiu();
echo $xiu -> name; //获取属性值时,会自动调用__get()方法,返回"user"

建定制获取方法和设置方法

自定义获取方法和设置方法

class xiu {
    private $name;
    //获取方法
    public function getName(){
        return $this->name;
    }
    //设置方法
    public function setName($name){
        $this -> name = $name;
    }
}
$xiu = new xiu();
$xiu -> setName("user");//设置属性
echo $xiu -> getName();//获取属性
  • 常量

在类中可以创建常量,用来表示不会改变的值

class xiu {
    const PI = 3.14159625;//设置常量
}
echo xiu::PI;//输出3.14159625 
  • 方法

明方法

可以使用与函数相同的语法创建方法,区别:方法声明前面一般会有作用域描述符

class xiu {
    public function fangFa(){
        retuen 2*3;
    }
}

用方法

class xiu {
    public function fangFa(){//创建方法
        return 2*3;
    }
}
$xiu = new xiu();//创建对象
$kang = $xiu -> fangFa();//调用方法并赋值给$kang
echo $kang;//输出6

法作用域

·public

公共方法可以在任何位置任何时间访问,在方法前面添加public或不添加任何关键字都可以声明一个公共办法

class xiu {
    public static function fangFa(){//创建公共方法
        echo "添加public关键字";
    }
    function fangFa2(){//创建公共方法
        echo "不添加public关键字";
    }
}
//第一种调用方法
xiu::fangFa();//输出"添加public关键字"
//第二种调用方法
$xiu = new xiu();
$xiu -> fangFa2();//输出"不添加public关键字"

·private

私有方法只能在本类中使用,不能被实例化的对象调用,也不能由子类使用

class xiu {
    private function fangFa(){//创建私有方法
        echo "私有方法";
    }
}

·protected

该类方法可以在本类或子类中使用

class xiu {
    private $name;
    //__construct()允许在实例化一个类之前先执行构造方法
    function __construct($name){
        //verifyEIN()方法验证$sear的语法是否正确
        if($this->verifyEIN($name)){
            echo "$name";
        }
    }
    protected function verifyEIN($name){
        return true;
    }
}
$xiu = new xiu("user");//输出"user"

·abstract

抽象方法(abstract)方法只在父类声明,在子类实现,只有声明为abstract的类可以声明抽象方法

abstract function xiu {
    abstract function kang();
    abstract function sear();
    abstract rong();
}

·final

final方法可以防止被子类覆盖

class xiu {
    final function getName(){
        //...
    }
}

·static

静态方法(。。。)

型提示

将class为xiu的对象传递给kang()方法

private function kang(xiu $xiu){
    //...
}

构造函数和析构函数

  • 构造函数

构造函数可以在对象实例化之前自动执行的代码

构造函数可以接受参数,能够在创建对象时赋给特定的对象属性

构造函数可以调用类方法或其他函数

类的构造函数可以调用其他构造函数,包括父类的构造函数

__construct关键字来识别构造函数(关键字前面有两个下划线)

<?php
    class Book{
        private $name;
        private $age;
        private $sex;
        function __construct($name){//声明构造函数
            $this -> setName($name);
            $this -> getAge();
            $this -> getSex();
        }
        private function setName($name){
            $this -> name = $name;
            echo $name;
        }
        private function getAge(){
            echo $this -> age = "20";
        }
        private function getSex(){
            echo $this -> sex = "男";
        }
    }
    $Book = new Book("小明");//输出"小明20男"
?>

用父类构造函数

<?php
    class Xiu{
        function __construct(){
            echo "输出父类构造函数";
        }
    }
    //创建Xiu的子类,使用关键字extends
    class Kang extends Xiu {
        function __construct(){
            parent :: __construct();//必须使用关键字parent显式调用父类构造函数
            echo "输出子类构造函数";
        }
    }
    $sear = new Kang();//输出"输出父类构造函数输出子类构造函数 "
?>

用无关的构造函数

(。。。)

<?php
    class xiu {
        function __construct(){
            echo "调用无关构造函数";
        }
    }
    class kang {
        function __construct(){
             new xiu();
        }
    }
    $kang = new kang();//输出"调用无关构造函数 "
?>
  • 析构函数

跟构造函数制订对象创建过程一样,析构函数修改对象撤销过程

__destruct()关键字来识别析构函数(关键字前面有两个下划线)

<?php
    class xiu {
        function __destruct(){
            echo "创建析构函数";
        }
    }
    $xiu = new xiu();//输出"创建析构函数"
?>

脚本结束时,PHP会撤销存储中的所有对象

实例化的类和实例化时创建的信息都留在内存中,不需要显式的声明析构函数

实例化创建了存储在数据库中的数据,就该在对象撤销时撤销这些数据,为此就应该创建一个析构函数

静态类成员

<?php
    class xiu {
        private static $age = 0;//设置静态属性
        function __construct(){
            echo $this -> getAge();
        }
        private function getAge(){
            //静态属性和方法只能使用self关键字和类名来引用
            return self::$age++;//设置属性加1
        }
    }
    $xiu = new xiu();//输出0
    $xiu = new xiu();//输出1
?>

instanceof关键字

使用instanceof关键字可以确定一个对象是类的实例、类的子类还是实现了某个特定接口

<?php
    //创建两个类
    class xiu{}
    class kang{}
    //创建xiu类对象
    $xiu = new xiu();
    //var_dump()可以打印出类型
    var_dump($xiu instanceof xiu);//对象$xiu是类xiu的对象所以输出true
    var_dump($xiu instanceof kang);//对象$xiu不是类kang的对象所以输出true
?> 

辅助函数

建类别名

class_alias()函数创建类别名

class xiu {
    function __construct(){
        echo "成功";
    }
}
class_alias("xiu","kang");//将xiu类设置别名kang
$kang = new kang();//输出"成功"

定类是否存在

class_exists()函数判断上下文是否存在指定的类

class xiu {
    function __construct(){
        echo "成功";
    }
}
echo class_exists("xiu");//因为存在xiu类,所以输出1(true)

定对象上下文

get_class()函数判断上下文是否存在对象,如果存在返回该对象所属的类名

class xiu {}
$kang = new xiu();
echo get_class($kang);//返回"xiu"

解类方法

get_class_methods()函数返回指定类中的方法,返回一个数组

class xiu {
    function kang(){}
    function sear(){}
}
print_r( get_class_methods("xiu"));//返回"Array ( [0] => kang [1] => sear ) "

解类属性

get_class_vars()函数返回指定类中的属性,返回一个关联数组

class xiu {
    public $name = "user";
    public $age = "20";
}
print_r( get_class_vars("xiu"));//返回"Array ( [name] => user [age] => 20 )  "

解声明类

get_declared_classes()函数返回PHP中所有的类,返回一个数组

print_r(get_declared_classes());

解对象属性

get_object_vars()函数返回指定对象的已定义的属性和值,如果没有值就返回null,返回一个关联数组

class xiu {
    public $name = "user";
    public $age;
}
$xiu = new xiu();
print_r(get_object_vars($xiu));//"Array ( [name] => user [age] => ) "

定对象的父类

get_parent_class()函数返回指定类的父类名

class xiu {};
class kang extends xiu{};//创建xiu的子类
echo get_parent_class("kang");//返回"xiu"

定接口是否存在

interface_exists()函数判断指定接口是否存在

(。。。)

定对象类型

is_a()函数判断指定对象是否是指定类的对象(或者指定的子类的对象)

class xiu {};
$xiu = new xiu();
var_dump(is_a($xiu,"xiu"));//返回true

定对象的子类类型

is_subcalss_of()函数判断指定对象是否是指定类的子类对象

class xiu {};
class kang extends xiu{};
$kang = new kang();
var_dump(is_subclass_of($kang,"xiu"));//返回true

定方法是否存在

method_exists()函数判断指定对象是否包含指定方法

class xiu {
    function getName(){}
}
$xiu = new xiu();
echo method_exists($xiu,"getName");//返回1(true)

自动加载对象

(。。。)