0

0

php如何定义一个类和对象?php面向对象编程之类与对象

穿越時空

穿越時空

发布时间:2025-09-14 22:45:01

|

515人浏览过

|

来源于php中文网

原创

类是PHP中定义对象的模板,包含属性和方法;对象是类的实例。使用class定义类,通过new创建对象。构造函数__construct用于初始化对象,析构函数__destruct在对象销毁时调用。可见性修饰符public、protected、private控制成员访问权限,实现封装。继承通过extends实现,子类可扩展父类功能,需显式调用parent::__construct()以执行父类构造函数。OOP的核心价值在于封装、继承和多态,提升代码复用性、可维护性和扩展性,适用于复杂项目开发。

php如何定义一个类和对象?php面向对象编程之类与对象

在PHP中,定义一个类就像是绘制一张蓝图,它描述了一类事物的共同特征(属性)和行为(方法)。而对象,则是这张蓝图的具体实现,是类的实例化。简单来说,类是抽象的模板,对象是具体的实体。

解决方案

要定义一个PHP类,我们使用

class
关键字,后面跟着类的名称,然后是一对花括号
{}
。在这个花括号内部,我们可以定义类的属性(变量)和方法(函数)。

brand = $brand;
        $this->model = $model;
        $this->color = $color;
        echo "一辆新的 {$this->color} {$this->brand} {$this->model} 被制造出来了!\n";
    }

    // 方法(行为),描述车能做什么
    public function startEngine() {
        if ($this->engineStatus === "off") {
            $this->engineStatus = "on";
            echo "{$this->brand} {$this->model} 的引擎启动了。\n";
        } else {
            echo "{$this->brand} {$this->model} 的引擎已经启动了。\n";
        }
    }

    public function stopEngine() {
        if ($this->engineStatus === "on") {
            $this->engineStatus = "off";
            echo "{$this->brand} {$this->model} 的引擎关闭了。\n";
        } else {
            echo "{$this->brand} {$this->model} 的引擎已经关闭了。\n";
        }
    }

    public function getEngineStatus() {
        return $this->engineStatus;
    }

    // 析构函数:当对象不再被引用或脚本结束时自动调用
    public function __destruct() {
        echo "{$this->brand} {$this->model} 的生命周期结束了。\n";
    }
}

// 创建(实例化)对象:使用 'new' 关键字
$myCar = new Car("Toyota", "Camry", "Blue"); // 调用构造函数

// 访问对象的属性
echo "我的车是:{$myCar->color} 的 {$myCar->brand} {$myCar->model}\n";

// 调用对象的方法
$myCar->startEngine();
echo "引擎状态: " . $myCar->getEngineStatus() . "\n";
$myCar->stopEngine();
echo "引擎状态: " . $myCar->getEngineStatus() . "\n";

echo "\n";

$anotherCar = new Car("Honda", "Civic", "Red");
$anotherCar->startEngine();
$anotherCar->startEngine(); // 尝试再次启动
$anotherCar->stopEngine();

// 当脚本执行完毕,或者对象被显式销毁(如 unset($myCar)),析构函数会被调用。
// 这里,它们会在脚本结束时自动调用。

?>

在这个例子里,

Car
是一个类,它定义了所有汽车都可能有的品牌、型号、颜色等属性,以及启动、停止引擎等行为。
$myCar
$anotherCar
则是
Car
类的两个具体实例,它们各自拥有自己的属性值,并且可以执行类定义的方法。通过
new Car(...)
这个操作,我们就完成了从抽象的“汽车”概念到具体的“我的丰田凯美瑞”或“另一辆本田思域”的转变。

为什么我们要用类和对象?面向对象编程的核心价值是什么?

在我刚接触编程的时候,写代码总是习惯性地从头到尾一条龙式地写下来,遇到重复逻辑就复制粘贴或者封装成函数。这对于小脚本来说确实没问题,但一旦项目规模稍微大一点,比如要管理几十种不同类型的用户、订单、商品,那代码就会变得异常混乱,改一个地方可能牵一发而动全身,维护起来简直是噩梦。这就是面向对象编程(OOP)真正展现其价值的地方。

立即学习PHP免费学习笔记(深入)”;

对我来说,OOP的核心魅力在于它提供了一种更贴近现实世界思维的组织代码的方式。我们不再把数据和处理数据的逻辑分开来考虑,而是将它们紧密地“捆绑”在一起,形成一个独立的、有行为能力的“对象”。这种“捆绑”带来的直接好处就是封装性(Encapsulation)。它意味着一个对象内部的实现细节可以被隐藏起来,外部只需要知道如何与它交互(通过公共方法),而不需要关心它是如何工作的。这极大地降低了系统的复杂度,提高了代码的模块化程度。

再者,OOP通过继承(Inheritance)机制,让我们可以基于现有类创建新类,共享和扩展功能。想象一下,你定义了一个通用的

Vehicle
(交通工具)类,然后可以轻松地派生出
Car
Motorcycle
Truck
等子类,它们自动拥有
Vehicle
的所有特性,同时又能添加自己特有的属性和行为。这不仅减少了代码重复,也让代码结构更加清晰,易于扩展。

最后,多态性(Polymorphism)则允许我们用统一的接口处理不同类型的对象。比如,所有的

Vehicle
子类都可以有一个
drive()
方法,但
Car
drive()
可能是踩油门,
Motorcycle
drive()
可能是拧油门。通过多态,我们可以编写更通用、更灵活的代码,提高系统的可维护性和适应性。在我看来,这些特性共同构筑了一个强大的框架,让大型项目的开发和维护变得更加可控和高效,也让程序员能够以更高级别的抽象来思考问题,而不是纠结于底层实现的每一个细节。

类属性与方法:可见性修饰符到底意味着什么?

在PHP中,当我们定义类的属性和方法时,前面通常会加上

public
protected
private
这些关键字,它们就是所谓的“可见性修饰符”。这些修饰符决定了类成员(属性或方法)在什么范围内可以被访问。这听起来可能有点抽象,但实际上,它们是实现封装性的关键工具,能够帮助我们更好地控制代码的结构和行为。

  • public
    (公共的):这是最宽松的修饰符。被
    public
    修饰的属性或方法,可以在任何地方被访问——无论是类的内部、类的外部,还是子类。这就像是一个敞开的门,所有人都可以进来。对于那些需要对外提供服务或数据,且没有副作用的成员,我们通常会使用
    public
    。比如上面
    Car
    类的
    startEngine()
    方法,用户当然需要能够直接调用它来启动汽车。

  • protected
    (受保护的)
    protected
    修饰的成员,只能在定义它们的类及其子类中被访问。外部代码(非该类或其子类)无法直接访问它们。这就像是一个家庭内部的秘密,只有家庭成员(父类和子类)知道,外人无权干涉。
    protected
    常用于那些子类可能需要重写或访问的内部实现细节,但又不想完全暴露给外部的成员。

    citySHOP多用户商城系统
    citySHOP多用户商城系统

    citySHOP是一款集CMS、网店、商品、分类信息、论坛等为一体的城市多用户商城系统,已完美整合目前流行的Discuz! 6.0论坛,采用最新的5.0版PHP+MYSQL技术。面向对象的数据库连接机制,缓存及80%静态化处理,使它能最大程度减轻服务器负担,为您节约建设成本。多级店铺区分及联盟商户地图标注,实体店与虚拟完美结合。个性化的店铺系统,会员后台一体化管理。后台登陆初始网站密匙:LOVES

    下载
  • private
    (私有的):这是最严格的修饰符。
    private
    修饰的成员,只能在定义它们的类内部被访问。即使是子类,也无法直接访问父类的
    private
    成员。这就像是一个人的私人日记,只有他自己能看,连他的孩子(子类)都不能直接翻阅。
    private
    非常适合那些完全是类内部实现细节的属性或方法,它们不应该被外部或子类修改,以确保类的内部状态一致性和安全性。例如,
    Car
    类中的
    $engineStatus
    我设置为
    private
    ,就是为了强制外部必须通过
    startEngine()
    stopEngine()
    方法来改变引擎状态,而不是直接修改
    $engineStatus
    ,这可以避免一些不合逻辑的操作(比如直接把引擎状态设为“炸毁”)。

选择合适的可见性修饰符是一个设计上的考量。一开始学习时,很多人可能会习惯性地把所有东西都设为

public
,因为这样最简单,不会遇到访问权限问题。但随着项目复杂度的增加,你会发现这种做法会导致代码耦合度高,内部状态容易被外部意外破坏。因此,一个好的实践是尽可能地限制可见性,除非有明确的理由需要暴露。这通常被称为“最小权限原则”,它能让你的代码更加健壮和易于维护。

构造函数
__construct()
的作用与常见误区?

__construct()
是PHP中一个非常特殊的方法,我们称之为“构造函数”。它的主要作用是在一个新对象被创建(即使用
new
关键字实例化类)时,自动执行一些初始化操作。你可以把它想象成是对象的“出生证明”或者“初始化设置”,当一个新生命诞生时,它需要被赋予一些基本的属性和状态。

在上面的

Car
例子中,当我们写
$myCar = new Car("Toyota", "Camry", "Blue");
时,
__construct("Toyota", "Camry", "Blue")
方法就会被自动调用。它接收了品牌、型号和颜色作为参数,并将这些值赋给了
$this->brand
$this->model
$this->color
,从而确保了每个
Car
对象在被创建时,都拥有了其独特的初始身份。如果没有构造函数,我们就需要在创建对象后手动逐一设置这些属性,这不仅繁琐,也容易遗漏。构造函数的存在,保证了对象在创建之初就处于一个有效且有意义的状态。

常见误区和需要注意的地方:

  1. 忘记在子类中调用父类的构造函数:这是一个非常常见的错误。当你有一个子类继承了父类,并且子类也有自己的构造函数时,PHP默认不会自动调用父类的构造函数。这意味着父类中定义的任何初始化逻辑都不会执行。

    class SportsCar extends Car {
        public $turbo;
    
        public function __construct($brand, $model, $color, $turbo) {
            // 错误示范:忘记调用父类的构造函数
            // $this->brand = $brand; // 需要手动赋值,或者...
            // $this->model = $model;
            // $this->color = $color;
            $this->turbo = $turbo;
            echo "一辆运动型汽车 {$this->color} {$this->brand} {$this->model} 被制造出来了!\n";
        }
    }
    
    // 正确的做法是在子类构造函数中显式调用 `parent::__construct()`:
    class CorrectSportsCar extends Car {
        public $turbo;
    
        public function __construct($brand, $model, $color, $turbo) {
            parent::__construct($brand, $model, $color); // 关键一步!
            $this->turbo = $turbo;
            echo "一辆带涡轮的运动型汽车 {$this->color} {$this->brand} {$this->model} 被制造出来了!\n";
        }
    }
    
    // $mySportsCar = new SportsCar("Ferrari", "488", "Red", true); // brand, model, color可能未被初始化
    $myCorrectSportsCar = new CorrectSportsCar("Porsche", "911", "Yellow", true);
    echo "我的运动车是:{$myCorrectSportsCar->color} 的 {$myCorrectSportsCar->brand} {$myCorrectSportsCar->model}\n";

    如果不调用

    parent::__construct()
    SportsCar
    对象在创建时,其从
    Car
    类继承的
    $brand
    ,
    $model
    ,
    $color
    属性将不会被初始化,可能会导致后续操作出现问题。

  2. 构造函数不返回值

    __construct()
    方法设计上就是用来初始化对象的,它不应该有任何返回值(即使你写了
    return
    语句,PHP也会忽略)。

  3. 过度复杂化构造函数:有时候,为了初始化对象,我们可能会在构造函数中执行很多复杂的操作,比如数据库连接、文件读写等。虽然这在某些情况下是合理的,但如果构造函数变得过于庞大和复杂,可能会导致对象创建过程变得缓慢,并且难以测试。更好的做法是让构造函数保持简洁,只负责必要的属性赋值,将其他复杂逻辑委托给其他方法或服务。

在我看来,

__construct()
是构建健壮对象的第一道防线。合理地使用它,能够确保每个对象在诞生之初就具备了正确的基础,为后续的操作打下坚实的基础。

相关专题

更多
php文件怎么打开
php文件怎么打开

打开php文件步骤:1、选择文本编辑器;2、在选择的文本编辑器中,创建一个新的文件,并将其保存为.php文件;3、在创建的PHP文件中,编写PHP代码;4、要在本地计算机上运行PHP文件,需要设置一个服务器环境;5、安装服务器环境后,需要将PHP文件放入服务器目录中;6、一旦将PHP文件放入服务器目录中,就可以通过浏览器来运行它。

2534

2023.09.01

php怎么取出数组的前几个元素
php怎么取出数组的前几个元素

取出php数组的前几个元素的方法有使用array_slice()函数、使用array_splice()函数、使用循环遍历、使用array_slice()函数和array_values()函数等。本专题为大家提供php数组相关的文章、下载、课程内容,供大家免费下载体验。

1605

2023.10.11

php反序列化失败怎么办
php反序列化失败怎么办

php反序列化失败的解决办法检查序列化数据。检查类定义、检查错误日志、更新PHP版本和应用安全措施等。本专题为大家提供php反序列化相关的文章、下载、课程内容,供大家免费下载体验。

1498

2023.10.11

php怎么连接mssql数据库
php怎么连接mssql数据库

连接方法:1、通过mssql_系列函数;2、通过sqlsrv_系列函数;3、通过odbc方式连接;4、通过PDO方式;5、通过COM方式连接。想了解php怎么连接mssql数据库的详细内容,可以访问下面的文章。

952

2023.10.23

php连接mssql数据库的方法
php连接mssql数据库的方法

php连接mssql数据库的方法有使用PHP的MSSQL扩展、使用PDO等。想了解更多php连接mssql数据库相关内容,可以阅读本专题下面的文章。

1416

2023.10.23

html怎么上传
html怎么上传

html通过使用HTML表单、JavaScript和PHP上传。更多关于html的问题详细请看本专题下面的文章。php中文网欢迎大家前来学习。

1234

2023.11.03

PHP出现乱码怎么解决
PHP出现乱码怎么解决

PHP出现乱码可以通过修改PHP文件头部的字符编码设置、检查PHP文件的编码格式、检查数据库连接设置和检查HTML页面的字符编码设置来解决。更多关于php乱码的问题详情请看本专题下面的文章。php中文网欢迎大家前来学习。

1445

2023.11.09

php文件怎么在手机上打开
php文件怎么在手机上打开

php文件在手机上打开需要在手机上搭建一个能够运行php的服务器环境,并将php文件上传到服务器上。再在手机上的浏览器中输入服务器的IP地址或域名,加上php文件的路径,即可打开php文件并查看其内容。更多关于php相关问题,详情请看本专题下面的文章。php中文网欢迎大家前来学习。

1306

2023.11.13

Golang gRPC 服务开发与Protobuf实战
Golang gRPC 服务开发与Protobuf实战

本专题系统讲解 Golang 在 gRPC 服务开发中的完整实践,涵盖 Protobuf 定义与代码生成、gRPC 服务端与客户端实现、流式 RPC(Unary/Server/Client/Bidirectional)、错误处理、拦截器、中间件以及与 HTTP/REST 的对接方案。通过实际案例,帮助学习者掌握 使用 Go 构建高性能、强类型、可扩展的 RPC 服务体系,适用于微服务与内部系统通信场景。

6

2026.01.15

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
PHP课程
PHP课程

共137课时 | 8.7万人学习

JavaScript ES5基础线上课程教学
JavaScript ES5基础线上课程教学

共6课时 | 7万人学习

PHP新手语法线上课程教学
PHP新手语法线上课程教学

共13课时 | 0.9万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号