个人PHP学习笔记(五)--面向对象的程序设计

本文是个人PHP学习笔记第五部分,主要介绍了面向对象的程序设计,包括类的创建与实例化、成员属性与方法、封装性、继承性、抽象类与接口、多态性和静态成员。详细讲解了构造方法、析构方法、访问控制关键字以及常用魔术方法等核心概念。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

  • 基本语法
  • 语句结构
  • 函数
  • 数组
  • 面向对象的程序设计
  • 字符串
  • 正则表达式
  • 常用函数
  • 文件系统
  • 图形图像处理
  • MySQL数据库
  • Cookie&Session
  • 错误和异常

面向对象的程序设计


概述

  • 代码更加简洁,易于维护,更强的可重用性:重用性,灵活性,扩展性。
  • 面向对象的思想更加符合人类看待事物的一般规律。
  • PHP不是一个真正的面相对象的编程语言,但面向对象的思想是可以借鉴的,并且大部分可以很好地实现,这在大型项目的设计中是很有优势的。

创建一个类

创建类

keyword class name          //访问控制关键字,默认为public+关键字+类名
{
    ....                    //类的属性
}

实例化对象

$name = new class_name(....)         //变量+关键字+类名+参数列表
<?php
    class name
    {

    }
    $marshall=new name();
    $john=new name();
?>
  • 类是一个抽象的东西,通常不可以拿来直接使用,类实例化的对象才是我们使用的。

成员属性

概述

public $name          //访问控制关键字+属性名

var $name             //早期的PHP写法

<?php
    class emp
    {
        public $name;
        public $sex;
        public $age;
    }
    $marshall=new emp();
?>

访问成员属性

objname -> proname          //对象名+操作符+属性名

<?php
    class emp
    {
        public $name;
        public $sex;
        public $age;
    }
    $marshall=new emp();

    $marshall->name='Marshall';
    $marshall->sex='man';
    $marshall->age='21';

    echo 'Name:'.$marshall->name.'<br/>';
    echo 'age:'.$marshall->age.'<br/>';

    $john=new emp();

    $john->name='John';
    $john->sex='man';
    $john->age='22';

    echo 'Name:'.$john->name.'<br/>';
    echo 'age:'.$john->age.'<br/>';
?>
  • 通过对象访问到的只是对象的属性,赋值操作也是对对象属性的操作,并不会影响到类里面的属性。

成员方法

概述和访问

public function fun_name()          //访问控制关键字,默认为public+function+方法名
{
    ....
}

$objname -> fun_name();             //对象名+操作符+函数名和参数列表

<?php
    class emp
    {
        public function email()
        {
            echo '发送Email。';
        }
    }
    $marshall=new emp();
    $marshall->email();             //访问成员方法
?>

$this关键字

  • 把范围缩小在一个类内,使用了$this语法后,程序只会在类内寻找这个同名成员。
  • 在类的范围内没有找到指定变量,程序会报错。
$this->membername           //关键字+操作符+成员属性或者成员方法名

<?php
    class emp
    {
        public $name;
        public function emp_name()
        {
            echo 'My name is '.$this->name.'.';
        }
    }
    $marshall=new emp();
    $marshall->name='Marshall';
    $marshall->emp_name();
?>

构造方法

  • PHP允许开发者在一个类中定义一个方法作为构造函数。
  • 构造方法是由系统自动调用的,不可以主动调用
<?php
    class emp
    {
        public $name;
        public $age;
        function __construct($f_name,$f_age)
        {
            $this->name=$f_name;
            $this->age=$f_age;
        }
        public function emp_info()
        {
            echo 'Name:'.$this->name.'<br/>';
            echo 'Age:'.$this->age;
            echo '<br/>';
        }
    }
    $marshall=new emp('Mrashall',22);
    $john=new emp('John',20);

    $marshall->emp_info();
    $john->emp_info();
?>
  • 有些创建对象后具有默认的属性值,这可以使用构造函数来实现,类似于函数的默认参数。
<?php
    class character
    {
        public $life;
        public $power;
        public $level;
        function __construct($d_life=100,$d_power=5,$d_level=1)
        {
            $this->life=$d_life;
            $this->power=$d_power;
            $this->level=$d_level;
        }
        public function char_info()
        {
            echo '生命:'.$this->life.'<br/>';
            echo '攻击:'.$this->power.'<br/>';
            echo '等级:'.$this->level.'<br/>';
        }
    }
    $d_cha=new character();
    echo '创建了默认人物:<br/>';
    $d_cha->char_info();

    $cha=new character(150,10,2);
    echo '创建了自定义人物:<br/>';
    $cha->char_info();
?>

析构方法

  • 析构函数允许在销毁一个类之前执行一些操作或完成一些功能。
  • 析构函数会在某个对象的所有引用都被删除或者但前对象被显性销毁时执行。
  • 析构函数的调用是系统自动的。
function __destruct()
{
    ....
}

<?php
    class character
    {
        public $life;
        public $power;
        public $level;
        function __construct($d_life=100,$d_power=5,$d_level=1)
        {
            $this->life=$d_life;
            $this->power=$d_power;
            $this->level=$d_level;
        }
        public function char_info()
        {
            echo '生命:'.$this->life.'<br/>';
            echo '攻击:'.$this->power.'<br/>';
            echo '等级:'.$this->level.'<br/>';
        }
        function __destruct()
        {
            echo '人物创建完成。';
        }
    }
    $cha1=new character(150,10,2);
    echo '创建了自定义人物:<br/>';
    $cha1->char_info();
?>

//显性销毁
<?php
    class character
    {
        public $life;
        public $power;
        public $level;
        function __construct($d_life=100,$d_power=5,$d_level=1)
        {
            $this->life=$d_life;
            $this->power=$d_power;
            $this->level=$d_level;
        }
        public function char_info()
        {
            echo '生命:'.$this->life.'<br/>';
            echo '攻击:'.$this->power.'<br/>';
            echo '等级:'.$this->level.'<br/>';
        }
        function __destruct()
        {
            echo '这个人物被销毁了……';
        }
    }
    $cha=new character(150,10,2);
    echo '创建了自定义人物:<br/>';
    unset($cha);
    $cha->char_info();            //$cha被销毁,使用会报错
?>

封装性

  • 封装性最主要的作用就是把数据封起来,不让外界可以随意访问,修改。
  • 数据更加可靠安全。
  • 封装性有两方面的意义:结构和数据。结构就是使用的类的成员属性和成员函数都是集中放置在类里面。数据就是访问控制关键字。

访问控制关键字public,protected,private

关键字说明
Public公共成员,可以在类的内外部被访问
Protected保护成员,可以在类的内部被访问
Private私有成员,只可以在类的内部被访问
<?php
    class emp
    {
        public $name;
        protected $phone;
        private $add;

        public function one_print()
        {
            echo '我可以被访问';
        }
        protected function two_print()
        {
            echo '我不可以在类外被访问';
        }
        private function three_print()
        {
            echo '我不可以在类外被访问';
        }
    }
    $marshall=new emp();
    $marshall->name='Marshall';
    $marshall->phone='112233';                   //报错
    $marshall->add='Nanjing';                    //报错

    $marshall->one_print();
    $marshall->two_print();                      //报错
    $marshall->three_print();                    //报错
?>
  • 在类中定义一个公有函数,然后通过访问这个函数就可以间接访问到私有或者保护成员。通常被称作接口函数。
<?php
    class emp
    {
        public $name;
        private $phone;
        public function phonenum()
        {
            echo 'My phone number is:'.$this->phone;
        }
        function __construct($n,$p)
        {
            $this->name=$n;
            $this->phone=$p;
        }
    }
    $marshall=new emp('Marshall','112233');
    echo 'My name is:'.$marshall->name.'.<br/>';
    $marshall->phonenum();
?>

//在接口函数中加入判断,防止非法访问
<?php
    class emp
    {
        public $name;
        private $phone;
        public function phonenum($uname,$upass)
        {
            if($uname=='Marshall'&&$upass=='123456')
            {
                echo 'My phone number is:'.$this->phone;   
            }
            else
            {
                echo 'The phone number is private.';
            }
        }
        function __construct($n,$p)
        {
            $this->name=$n;
            $this->phone=$p;
        }
    }
    $marshall=new emp('Marshall','112233');
    echo 'My name is:'.$marshall->name.'.<br/>';
    $marshall->phonenum('Marshall','123456');
    echo '<br/>';
    echo 'My name is:'.$marshall->name.'.<br/>';
    $marshall->phonenum('Marshall','12346');
?>

继承性

  • 继承会影响到类与类,对象与对象之间的关系。
  • 继承就相当于是把父类的成员赋值到子类的过程。
  • 父类的private成员不会被子类继承。
class sonclass_name extends fatherclass_name     //关键字+子类名+关键字+父类名
{
    ....
}

1.继承public成员

<?php
    class info
    {
        public $life;
        public $power;
        function __construct($d_life=100,$d_power=25)
        {
            $this->life=$d_life;
            $this->power=$d_power;
        }
        public function skill()
        {
            echo '技能:升龙拳';
        }
    }
    class marshall_info extends info
    {

    }
    $cha=new marshall_info();
    echo '生命:'.$cha->life.'<br/>';
    echo '攻击:'.$cha->power.'<br/>';
    $cha->skill();
?>

2.继承protected成员

<?php
    class info
    {
        public $life;
        public $power;
        protected $money;
        function __construct($d_life=100,$d_power=25,$d_money=300)
        {
            $this->life=$d_life;
            $this->power=$d_power;
            $this->money=$d_money;
        }
        public function skill()
        {
            echo '技能:升龙拳<br/>';
        }
    }
    class marshall_info extends info
    {
        public function show_money($pass)
        {
            if($pass==123456)
            {
                echo '金钱:'.$this->money.'<br/>';
            }
            else
            {
                echo '密码错误,金钱数量保密。';
            }
        }
    }
    $cha=new marshall_info();
    echo '生命:'.$cha->life.'<br/>';
    echo '攻击:'.$cha->power.'<br/>';
    $cha->skill();
    $cha->show_money(123456);
    $cha->show_money(12345);
?>

抽象类和接口

抽象类和抽象方法

  • 抽象类就是在类中定义了一个父类不曾实现的方法,而规定子类必须实现
  • 把继承做到极致的类就是抽象类。
  • 抽象类和方法使用abstract修饰
abstract class class_name          //关键字+class+类名和参数列表
{
    ....
}

abstract function fun_name();       //关键字+function+方法名和参数列表
//分号结尾,没有函数体
  • 任何一个类,如果它里面至少有一个方法被声明为抽象的,那么这个类就必须被声明为抽象类。
abstract class emp
{
    abstract function emp_info();
    public function emp_show()
    {
        ....
    } 
}
  • 抽象类不能直接被实例化,必须先继承该抽象类,然后再实例化子类。
  • 继承一个抽象类的时候,子类必须实现抽象类中的所有抽象方法。
  • 这些方法的可访问性必须和抽象类中的一致或更宽松。
<?php
    abstract class cala
    {
        abstract protected function area();
        public function show_info()
        {
            echo '这是一个计算面积的方法。<br/>';
        }
    }
    class info extends cala
    {
        private $a;
        private $b;
        function __construct($d_a=1,$d_b=1)
        {
            $this->a=$d_a;
            $this->b=$d_b;
        }
        function area()
        {
            echo '长方形面积为:'.$this->a*$this->b;
        }
    }
    $cf=new info();
    $cf->show_info();
    $cf->area();
?>

接口

  • 接口一种特殊的抽象类,他的全部成员方法都是抽象方法,并且不能在接口中声明变量,只能使用const声明常量属性,所有的成员都必须有public的访问权限。
  • 实际上接口类就是一个类的模板,一个类的规定。
interface inter_name            //关键字+接口名
{
    ....                        //接口内容
}

class class_name implements interface1,interface2,interface3...
{
    ....                        //实现所有类中的方法
}

class class_name extends father_name implements intherface1,...
{
    ....                        //在实现多个接口时,还可以继承别的类
}

<?php
    interface cala_one
    {
        function add();
        function minus();
    }
    interface cala_two
    {
        function multiply();
        function divide();
    }
    class show
    {
        public function show_info()
        {
            echo '计算结果是:<br/>';
        } 
    }
    class cala extends show implements cala_one,cala_two
    {
        private $num1;
        private $num2;
        function __construct($d_num1,$d_num2)
        {
            $this->num1=$d_num1;
            $this->num2=$d_num2;
        }
        public function add()
        {
            echo '$num1+$num2='.($this->num1+$this->num2).'<br/>';
        }
        public function minus()
        {
            echo '$num1-$num2='.($this->num1-$this->num2).'<br/>';
        }
        public function multiply()
        {
            echo '$num1*$num2='.($this->num1*$this->num2).'<br/>';
        }
        public function divide()
        {
            echo '$num1/$num2='.($this->num1/$this->num2);
        }
    }
    $res=new cala(10,5);
    $res->show_info();
    $res->add();
    $res->minus();
    $res->multiply();
    $res->divide();
?>

多态性

  • 由于PHP是弱语言,并不支持完全的多态性。在PHP中,堕胎理解为一段程序能处理多种类型对象的能力。
<?php
    interface equ
    {
        function check();
        function run();
        function stop();
    }
    class fan implements equ
    {
        function check()
        {
            echo '检查风扇。<br/>';
        }
        function run()
        {
            echo '风扇正在运行。<br/>';
        }
        function stop()
        {
            echo '风扇停止运行。<br/>';
        }
    }
    class engine implements equ
    {
        function check()
        {
            echo '检查引擎。<br/>';
        }
        function run()
        {
            echo '引擎正在运行。<br/>';
        }
        function stop()
        {
            echo '引擎停止运行。<br/>';
        }
    }
    class state
    {
        function show_state($equment)
        {
            $equment->check();
            $equment->run();
            $equment->stop();
        }
    }
    class start
    {
        function equ_start()
        {
            $f=new fan;
            $e=new engine;
            $s=new state;

            $s->show_state($f);
            $s->show_state($e);
        }
    }
    $car=new start;
    $car->equ_start();
?>

静态成员

定义与访问静态成员

  • 静态成员属性是一个特殊的成员属性,它被类的所有对象共享
  • 静态属性能被初始化为一个字符串或者一个常量,不能使用表达式。
  • 静态成员存在于类中,不会被实例化到对象中。访问静态成员只能通过类访问。
public static $property          //访问控制关键字,默认为public+关键字static+属性名

classname :: $proname            //类名+作用域限定符+静态属性名

self :: $proname                 //在类内部使用self代替类名

<?php  
    class name  
    {  
      static $myname='Marshall';  
      function getmyname()
      {  
         return self::$myname;  
      }  
    }  
    echo name::$myname;     
    $myn=new name;
    echo $myn->getmyname();  
?>  

静态成员方法与访问

<?php
    class emp
    {
        public $name;
        public function email()
        {
            echo '我会发Email。';
        }
        public static function show_name()
        {
            echo '我是Marshall,';
        }
    }
    emp::show_name();
    $marshall=new emp;
    $marshall->email();
?>

常见关键字和魔术方法

常用关键字

final关键字
  • 如果父类中的方法被声明为final,则子类无法覆盖该方法。
  • 如果一个类被声明为final,则不能被继承。
final class classname          //关键字+class+类名
{
    ....
}

<?php
    final class show
    {
        public function show_info()
        {
            echo 'Final类不能被继承。';
        }
    }
    class func extends show             //继承会报错
    {

    }
    $res=new show();
    $res->show_info();
?>
  • final修饰成员方法
authority final function function_name     //访问控制关键字+关键字+function+方法名,参数列表
{
    ....
}

<?php
    class emp
    {
        private $name;
        private $age;
        public function emp_name($e_name)
        {
            $this->name=$e_name;
            echo 'My name is '.$this->name.'.';
        }
        public final function emp_age($e_age)
        {
            $this->age=$e_age;
            echo 'I am '.$this->age.' years old.';
        }
    }
    class mar extends emp          //mar类继承emp类,成功继承了final方法
    {

    }
    $marshall=new mar();
    $marshall->emp_name('Marshall');
    $marshall->emp_age(21);
?>

<?php
    class emp
    {
        private $name;
        private $age;
        public function emp_name($e_name)
        {
            $this->name=$e_name;
            echo 'My name is '.$this->name.'.';
        }
        public final function emp_age($e_age)
        {
            $this->age=$e_age;
            echo 'I am '.$this->age.' years old.';
        }
    }
    class mar extends emp          
    {
        public function emp_age($e_age)     //覆盖final成员方法会报错
        {
            $this->age=($e_age+20);
            echo 'I am '.$this->age.' years old.';
        }
    }
    $marshall=new mar();
    $marshall->emp_name('Marshall');
    $marshall->emp_age(21);
?>
  • 如类不想被继承,方法不想被子类重写,可以利用final关键字来修饰。
clone关键字
  • 建立对象的副本,可以再实例化一个对象并给属性添加相同的值。
$new_name=clone $objname;           //新对象名+关键字+要复制的对象名

<?php
    class emp
    {
        private $name;
        private $age;
        private $sex;
        public function __construct($name,$age,$sex)
        {
            $this->name=$name;
            $this->age=$age;
            $this->sex=$sex;
        }
        public function info()
        {
            echo 'My name is '.$this->name.', I am '.$this->age.' years old, I am a '.$this->sex.'.<br/>';
        }
    }
    $mar=new emp('Marshall',21,'boy');
    $mar->info();

    $john=clone $mar;
    $john->info();
?>

//利用__clone()方法来做复制的初始化工作

<?php
    class emp
    {
        private $name;
        private $id;
        public function __construct($name,$id=1)
        {
            $this->id=$id;
            $this->name=$name;
        }
        public function __clone()
        {
            $this->id++;
        }
        public function info()
        {
            echo 'My name is '.$this->name.', My ID Number is '.$this->id.'.<br/>';     
        }
    }
    $mar=new emp('Marshall');
    $mar->info();

    $john=clone $mar;
    $john->info();
?>

常用魔术方法

set( ),get( )方法
1.__set()

<?php
    class emp
    {
        public $name;
        private $age;
        private $sex;
        public function __set($varname,$value)
        {
            if($varname=='age')
            {
                if($value>=20&&$value<=65)
                {
                    $this->age=$value;
                }
                else
                {
                    echo 'age number is not correct.';
                }
            }
            if($varname=='sex')
            {
                if($value=='boy'||$value=='girl')
                {
                    $this->sex=$value;
                }
                else
                {
                    echo 'the kind of sex is not correct.';
                }
            }
        }
        public function info()
        {
            echo 'My name is '.$this->name.', I am '.$this->age.' years old, I am a '.$this->sex.'.<br/>';
        }
    }
    $mar=new emp();
    $mar->name='Marshall';
    $mar->age=21;
    $mar->sex='boy';
    $mar->info();

    $mar->age=18;
    $mar->info();

    $mar->sex='other';
    $mar->info();
?>
//虽然两个成员是私有的,但是也可以在类的外部赋值

2.__get()

<?php
    class emp
    {
        private $name;
        private $age;
        private $sex;
        public function __get($varname)
        {
            if($varname=='name')
            {
                echo 'My name is '.$this->name.'.<br/>';
                return;
            }
            else if($varname=='age'||$varname=='sex')
            {
                echo 'Secret.';
            }
            else
            {
                echo 'No such a value.';
            }
        }
        public function __construct($name,$age,$sex)
        {
            $this->name=$name;
            $this->age=$age;
            $this->sex=$sex;
        }
    }
    $mar=new emp('Marshall',21,'boy');
    $mar->name;
    $mar->age;
    $mar->sex;

    $mar->school;
?>
call( ),callStatic( )方法
authority static function __call($varname,$values)
{
    ....
}

public static function __callStatic($varname,$values)
{
    ....
}

1.__call()

<?php
    class emp
    {
        private $name;
        private $id;
        public function __construct($name,$id=1)
        {
            $this->id=$id;
            $this->name=$name;
        }
        public function __call($func_name,$values)     //调用不存在或是不可见的成员方法时自动调用
        {
            echo 'The function which you call can not access or not exist.';
        }
        public function info()
        {
            echo 'My name is '.$this->name.', My ID Number is '.$this->id.'.<br/>';      
        }
        private function show_info()
        {
            echo 'Age:21';
        }
    }
    $mar=new emp('Marshall');
    $mar->info();
    $mar->show_info();
?>

2.__callStatic()

<?php
    class emp
    {
        static function show_info()
        {
            echo 'My name is Marshall.';
        } 
        private static function show_aba()
        {
            echo 'I can send Email.';
        }
        public static function __callStatic($func_name,$values)
        {
            echo 'The function which you call can not access or not exist.';
        } 
    }
    emp::show_info();
    emp::show_aba();
    emp::hello();
?>
  • __callStatic()也一定要声明为公共的静态函数,否则系统就会提示错误。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值