PHP 面对对象编程

本文详细讲解了面向对象编程的基础概念,包括类、对象、封装性、继承和多态性。通过PHP实例演示类定义、成员方法、实例化、成员变量、常量、构造方法和析构方法,以及继承与多态的实现。还介绍了`$this->`和`::`的用法以及数据隐藏的策略,包括public、private和protected。最后,涵盖静态变量和结束语部分的总结。
摘要由CSDN通过智能技术生成

1. 面对对象的基本概念

1. 类

通过属性可以区分不同的物质,类是属性和方法的集合,是面对对象编程的核心和基础,通过类能对零散的用于实现某项功能的代码进行有效的管理

2. 对象

类只是具备某项功能的抽象模型,在实际应用中还需要对类进行实例化,这就能引入对象的概念;
对象是对类进行实例化后的产物,是一个实体;
对象和类的关系可理解为:对象是 “有血有肉的、能摸得到的且看得见的” 一个类;

3. 面向对象编程的三大特点

面向对象编程的三大特点:封装性、继承性和多态性

1. 封装性

封装性,也称为信息隐藏;即将一个类的使用和实现分开,只保留有限的接口(方法)与外部联系;
对于用到该类的开发人员,只要知道这个类如何使用即可,不用关心这个类如何实现;
这样就能让开发人员能把精力更多地集中起来专注别的事情,同时也能避免因程序之间的相互依赖而带来不便;

2. 继承性

继承性即派生类(子类)自动继承一个或多个基类(父类)中的属性与方法,并能重写和添加新的属性或方法
继承这个特性简化了对象和类的创建,提高了代码的可重用性;
继承分单继承和多继承,PHP支持的是单继承,即一个子类有且只有一个父类;

3. 多态性

多态性是指同一个类的不同对象,调用同一个方法能获得不同的结果,这种结果被称为多态性;多态性增强了软件的灵活性和可重用性;

2. PHP与对象

1. 类的定义

PHP和很多对象语言一样,PHP也是通过 class 关键字加类名来定义类的;
类定义的格式如下:

<?php
    //定义一个类
    class First{
        //...
    }
?>

两个大括号之间的就是类的全部内容;First 是一个简单的类,仅有类的骨架,什么功能也没有实现,这并不影响它的存在;
一个类,即一对大括号之间的全部内容,都要放在一个代码段中,即一个<?php ...>不能分割成多块,如下的方式是不被允许的:

<?php
    //定义一个类
    class First{
        <?php
        //...
    }
    }
?>

2. 成员方法

类中的函数称为成员方法;函数和成员方法间唯一的区别是:函数实现的是某个独立的功能;而成员方法实现的是类的一个行为,是类的一部分

例子:创建一个员工类,并添加成员方法;将员工类命名为 Employee,并添加成员方法 work()

<?php
    //定义员工类
    class Employee{
        //声明成员方法
    function work($name,$height,$age,$sex){
        //方法功能的实现
        echo "姓名:".$name;
        echo "年龄:".$age;
        echo "身高:".$height;
        echo "性别:".$sex;
    }
    }
?>

work()该成员方法的作用是输出员工的基本信息,包括姓名、身高、年龄、性别;这些信息是通过work()成员方法的参数传递;

3. 类的实例化

类的成员方法已添加,然后就是使用成员方法,但使用成员方法不像使用函数那么简单;
首先要对类进行实例化,实例化是通过关键字 new 来声明一个对象;再使用下面的格式调用要使用的成员方法:
对象名->成员方法
类是一种抽象描述,是功能相似的一组对象的集合;若想使用类中的方法或变量,首先要把它落实到一个实体上,即对象上

例子:以Employee类为例,实例化一个对象并调用成员方法work()

<?php
//定义一个类
class Employee{
    //声明方法
    function work($name,$height,$age,$sex){
        //方法功能的实现
        echo "姓名:".$name."<br>";
        echo "身高:".$height."<br>";
        echo "年龄:".$age."<br>";
        echo "性别:".$sex."<br>";
    }
}
$emp=new Employee();
$emp->work("王五","164",32,"男");
?>

运行结果如下所示:
2021-11-25

上述的例子,不仅创建的类,同时也对类进行实例化操作,最后输出信息;

4.成员变量

类中的变量,称为成员变量(也称为属性或字段);成员变量用来保存数据信息,或通过成员方法进行交换式来实现某项功能;
定义成员变量的格式为:
关键字 成员变量名
关键字可使用public、private、static、final中的任意一个,所哟的示例都使用pubic关键字来修饰;
访问成员变量成员的方法是一样的;把成员方法换成成员变量即可,格式为:
对象名 -> 成员变量
例子:

<?php
//定义员工类
class Employee{
    //定义成员变量
    public $name;
    public $height;
    public $age;
    public $sex;
    function work($name,$height,$age,$sex){
        $this->name=$name;
        $this->height=$height;
        $this->age=$age;
        $this->sex=$sex;
        //方法功能的实现
        echo "姓名:".$this->name."<br>";
        echo "身高:".$this->height."<br>";
        echo "年龄:".$this->age."<br>";
        echo "性别:".$this->sex."<br>";
    }
}
//实例化对象,并传递参数
$emp= new Employee();
//调用方法
$emp->work("王五","167",33,"男");
?>

运行结果如下所示:
2021-11-25

$this -> 的作用是调用类中成员变量或成员方法;无论是使用$this ->还是 “对象名 ->” 的格式,后面的变量是没有$符号的,如$this ->word、$sport ->work,这是一个出错概率很高的错误;

5. 类常量

类中有变量,也会有变量;常量是不会改变的量,即恒量,如圆周率是一个常量;
使用 const定义常量;

例子:const U=3.1415926;

例子:先声明一个常量,在声明一个变量,实例化对象后分别输出它们的值;

<?php
//定义员工类
class Employee{
    //定义常量
    const NAME="Python语言!";
    //定义成员变量
    public $str;
    //声明set方法
    function setStr($name){
        $this -> str = $name;
    }
    //声明get方法
    function getStr(){
        return $this -> str;
    }
}
//实例化
$emp = new Employee();
//调用set方法
$emp -> setStr("是门好语言!");
//输出变量NAME
echo Employee::NAME."->";
echo $emp -> getStr();
?>

运行结果如下所示:2021-11-25

通过上述例子得出,常量和变量的输出时不一样的;常量不需要实例化对象,直接由“类名::常量名”调用;
常量的输出格式为:
类名::常量名
类名和常量名之间的两个冒号“::”称为作用域操作符,使用这个操作符可在不创建对象的情况下调用类中的常量、变量和方法;

6. 构造方法和析构方法

1. 构造方法

类被实例化时,会随对象初始化而初始化一些成员变量;
例子:在Employee类的基础上添加一些成员变量;

<?php
//定义员工类
class Employee{
    //定义成员变量
    public $name;
    public $height;
    public $age;
    public $sex;
    public $city;
}
//实例化对象
$emp = new Employee();
//为成员变量赋值
$emp -> name="王思";
$emp -> height="166";
$emp -> age=23;
$emp -> sex="女";
$emp -> city="天津";

?>

从上述例子得出,当赋予的初始值较多,写起来麻烦;所以,PHP 引入构造方法,构造方法是生成对象时自动执行的成员方法,作用是初始化对象;
构造方法可以不带参数,也可以带多个参数;
构造方法的定义格式如下:

void__construct([mixed args[,```]])

定义中的 “__” 是两条下划线;
例子:

<?php
//定义员工类
class Employee{
    //定义成员变量
    public $name;
    public $height;
    public $age;
    public $sex;
    public $city;
    
    //声明构造方法
    public function __construct($name,$height,$age,$sex,$city){
        $this -> name = $name;
        $this -> age = $age;
        $this -> height = $height;
        $this -> sex = $sex;
        $this -> city = $city;
    }
    
    //声明成员方法
    function work(){
        //方法功能的实现
        echo "姓名:".$this -> name."<br>";
        echo "身高:".$this -> height."<br>";
        echo "年龄:".$this -> age."<br>";
        echo "性别:".$this -> sex."<br>";
        echo "所在城市:".$this -> city."<br>";
    }
}

//实例化对象,并传达参数
$emp = new Employee("王思","165",23,"女","天津");
//调用方法
$emp -> work();
?>

运行结果如下所示:
2021-11-25

上述例子在实例化对象时只需要一条语句就能完成对成员变量的赋值;
构造方法是在初始化对象时使用的,若类中没有构造方法,PHP将会自动生成一个;
自动生成的构造方法没有任何参数,没有任何操作;

2. 析构方法

析构方法的作用和构造方法正好相反,当对象被销毁时调用,作用是释放内存;
定义析构方法的格式为:

void__destruct(void)

例子:先声明一个对象emp,再销毁该对象;

<?php
//定义员工类
class Employee{
    //定义成员变量
    public $name;
    public $height;
    public $age;
    public $sex;
    public $city;
    //声明析构方法
    public function __construct($name,$height,$age,$sex,$city){
        $this -> name = $name;
        $this -> age = $age;
        $this -> height = $height;
        $this -> sex = $sex;
        $this -> city = $city;
    }
    //声明成员方法
    function work(){
        //方法功能的实现
        echo "姓名:".$this -> name;
        echo "年龄:".$this -> age;
        echo "身高:".$this -> height;
        echo "性别:".$this -> sex;
        echo "所在城市:".$this -> city;
    }
    //析构方法
    function __destruct(){
        echo "<p><b>对象被销毁</b></p>";
    }
}
//实例化对象,并传递参数
$emp = new Employee ("吴宝","170",30,"男","广州");
?>

运行结果如下所示:
2021-11-25

PHP使用的是一种 “垃圾回收” 机制,能自动清除不再使用的对象,释放内存;
即使使用 unser()函数,析构方法也会自动被调用,上述例子只是明确析构方法在何时被调用;
一般情况是不需要手动创建析构方法的;

7. 继承和多态的实现

继承和多态最根本的作用是完成代码的重用;

1. 继承

子类继承父类的所有成员变量和方法,包括构造方法;当子类被实例化时,PHP会先在子类中查找构造方法,若子类有自己的构造方法,会先调用子类中的构造方法:当子类中没有时,PHP会去调用父类中的构造方法,这就是继承;
继承通过关键字extends来声明,格式如下:

class subClass extends superClass{
...
}

subClass 为子类名字,superclass 为父类名称;
例子:用Employee类生成两个子类 —— EmployeeName和EmployeeCity,这两个子类使用不同的构造方法实例化两个对象,并输出信息;

<?php
//父类
class Employee{
    //定义成员变量
    public $name;
    public $height;
    public $age;
    public $sex;
    public $city;
    //声明构造方法
    public function __construct($name,$height,$age,$sex,$city){
        $this -> name = $name;
        $this -> height = $height;
        $this -> age = $age;
        $this -> sex = $sex;
        $this -> city = $city;
    }
    //声明成员方法
    function work(){
        //方法功能的实现
        echo "这句话不显示";
    }
}
//子类继承父类
class EmployeeName extends Employee{
    function __construct($name,$age,$sex){
        $this -> name = $name;
        $this -> age = $age;
        $this -> sex = $sex;
    }
    //定义方法
    function work(){
        if($this -> age >50){
            return $this -> name.",此员工已达到退休年龄";
        }else{
            return $this -> name.",此员工年龄符合要求";
        }
    }
}
//子类EmployeeCity
class EmployeeCity extends Employee{
    function work(){
        if($this ->age >50){
            return $this -> name.",此员工已达到退休年龄";
        }else{
            return $this -> name.",此员工年龄符合要求";
        }
    }
}

//实例化子类对象
$empname = new EmployeeName("王武",23,"男");
$empcity = new EmployeeCity("李霸","178",55,"男","天津");
echo $empname -> work()."<br>";
echo $empcity -> work();
?>

运行结果如下所示:
2021-11-25

2. 多态

多态会产生不同的形态;
多态存在两种形式:覆盖和重载
覆盖,就是在来子类中重写父类的方法,而在子类的对象中虽然调用的是父类中相同的犯法,但返回的结果是不同的;
重载,这是多态的另一种实现;函数的重载是指一个标识符被用作多个函数,且能够通过函数的参数个数或参数类型将这些同名函数区分开来,以使调用不发生混淆;
好处是可实现代码重用,即不用为了不同的参数类型或参数个数而多个函数;
多个函数个数使用同一个名字,虽然名称相同,但根据参数个数或各参数数据类型的不同,调用对应的函数;

8. “$this->”和"::"的使用

子类不仅能调用自己的变量和方法,也能调用父类中的父类变量和方法,而对于不同的类成员同样能调用;
PHP是通过伪变量"$this->"和作用域操作符"::"来实现这些功能;

1. $this->

调用成员的方法,即用对象名加方法名,格式为 ”对象名->方法名“
在定义类(如Employee类)时,无法得到对象名称是什么,这时候若想掉员工类中的方法,要使用伪变量 $this->;
$this的意思是本身,所以 t h i s − > 只 能 在 内 部 使 用 ; 例 子 : 当 类 被 实 例 化 后 , this->只能在内部使用; 例子:当类被实例化后, this>使this同时被实例化为类的对象,这是对$this使用get_class()函数,将返回类的类名;

<?php
//创建类
class Employee{
    //创建方法
    function className(){
        //判断this是否存在
        if(isset($this)){
            //输出this所在类的类名
            echo "\$this的值是:".get_class($this);
        }else{
            echo "$this 为空";
        }
    }
}
$emp=new Employee();
//调用className方法
$emp -> className();
?>

运行结果如下所示:
2021-11-25

说明:get_class() 函数返回对象所属的类名,若不是对象,返回FALSE;

2. 操作符 “::"

伪变量“$this”只能在类的内部使用,操作符 “::" 更为强大,它能在没有声明任何实例的情况下访问类中的成员方法或成员变量;
使用操作符 "::" 的通用格式为:
关键字::变量名/常用名/方法名
关键字分为以下3种情况:
parent:能调用父类中成员变量、成员方法和常量;
self:能调用当前类中的静态成员和常量;
类名:能调用该类中的变量、常量和方法;
例子:依次使用类名、parent关键字和self关键字调用变量和方法;

<?php
//创建类
class Employee{
    const NAME = "php 语言";
    function __construct(){
        echo "您使用的语言是:".Employee::NAME;
    }
}
class TwoEmployee extends Employee{
    const NAME = "这是一门好语言!";
    function __construct(){
        parent::__construct();
        echo "您使用的语言是:".self::NAME;
    }
}
//类的实例化
$twoemp = new TwoEmployee();
?>

运行结果如下所示:2021-11-25

9. 数据隐藏

1. public(公共成员)

即能公开、没有隐藏的数据信息;能在程序中的任何位置(类内、类外)被其他的类和对象调用;
子类能继承和使用父类中所有的公共成员;
所有的变量被默认声明为public,而所有的方法默认状态下也是public,所以对变量和方法使用显得十分混乱;
为了解决上述问题,就要使用到关键字private;

2. private(私有成员)

private关键字修饰的变量和方法,只能在所属类的内部被调用和修改,不能在类外被访问,在子类中也不行;
例子:

<?php
//创建类
class Employee{
    private $name = "张武";
    //设置私有变量和方法
    public function setName($name){
        $this -> name = $name;
    }
    //get
    public function getName(){
        return $this -> name;
    }
}
//Employee的子类
class EmployeeC extends Employee{

}
$empc = new EmployeeC();
//正确操作私有变量
$empc -> setName("Python");
echo "<br>";
//错误操作私有变量
echo Employee::$name;
?>

若没哟指定关键字,默认就是public;

3. protected(受保护成员和变量)

private关键字能将数据全部隐藏起来,除了在类的内部外,在其他地方都不能被调用,子类也不能;
若对于有些变量希望被调用,但对于另外的类来说,还要做到封装;这时就可以使用protected关键字;
protected修饰的类成员,能在类的内部和子类中被调用,在其他地方都不可以被调用;
例子:声明一个protected变量,在子类的方法中调用一次,最后在类外直接调用一次;

<?php
//创建类
class Employee{
    //声明变量
    protected $name="王某";
}
//Employee的子类
class EmployeeC extends Employee{
    public function name(){
        echo "对于protected修饰的变量,在子类中能直接被调用";
    }
}
//实例化
$empc = new EmployeeC();
$empc -> name();
//直接对受保护变量进行操作
$empc -> name ="张某";
?>

10. 静态变量(方法)

不是所有的变量(方法)都需要通过创建对象来调用,还能通过变量(方法)加上static关键字来直接调用;
调用静态成员的格式为:
关键字:静态成员
关键字可以是:

  • self,在类的内部调用静态成员时时使用;
  • 静态成员所在类的类名,在类外调用类内部的静态成员时时使用;

在静态方法中,只能调用静态变量,而不能调用普通变量;而普通方法则能调用静态变量;
使用静态成员,除不需要实例化对象外,另一个作用就是在对象被销毁后,仍能够保存被修改的静态数据,以便下次继续使用;
例子:先声明静态变量$num,再声明一个方法,在方法的内部调用静态变量$num,再给$num变量加1;实例化Numbers这个类,生成两个对象,并调用类中的方法;

<?php
//创建类
class Numbers{
    static $number = 0;
    //声明方法
    public function count(){
        //输出静态变量
        echo "当前点击量:".self::$number."次";
        //静态变量加1
        self::$number++;
    }
}
$num1 = new Numbers();
//调用cont方法
$num1 -> count();
echo "<br>";
$num2 = new Numbers();
$num2 -> count();
echo "<br>";
//直接使用类名加方法名调用静态方法
echo "当前点击量:".Numbers::$number."次";

?>

运行结果如下所示:

2021-11-25

若将上述代码中的静态变量改为普通变量,如“private $num 0;”,结果就一样;
静态成员不用实例化对象,当类第一次被加载时就已被分配好了内存空间,直接调用静态成员变量的速度会快一点;
若静态成员声明过多,空间一直被占用,会影响系统的功能;

结束语

若这篇文章有帮到你,给个赞,收个藏,欢迎大家留言评论;
若文章有什么错误,欢迎大家指教。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值