浅谈 PHP 面向对象基础 简单总结

面向对象的三个特点:继承、封装和多态

类 是对 对象 的 抽象,在 类中 可以定义 对象的 属性和方法 的描述;

对象 是 类 的实例,类 只有被实例化后才能被使用。


instanceof  (1)判断一个对象是否是某个类的实例,(2)判断一个对象是否实现了某个接口。

// 用于检测当前对象属于哪个类
$obj = new A();
if ($obj instanceof A) {
   echo 'A';
}

一般在调用类的属性和方法的时候会使用:$this->name 或 $this->name()来完成。下面通过一个简单的例子来说明一下$this->$name的这种用法。

class Test{
    public $name = "abc";
    public $abc = "test";
    public function Test(){
        $name1 = "name";
        echo $this->name;   // 输出 abc
        echo $this->$name1;  // 输出 abc,因为 $name1 的值是name,相当与这里替换成 echo $this->name;
        $name2 = $this->$name1;  // $name2 的值是 abc
        echo $this->$name2;  // 输出 test,同上,相当与是 echo $this->abc;
    }
}
new Test();

构造方法 __construct 和 析构函数 __destruct(如果类名和方法名相同,则会当做构造函数来执行)

class BaseClass {
   function __construct() {
       echo "In BaseClass constructor";
   }
}
class SubClass extends BaseClass {
   function __construct() {
       parent::__construct();                // 要执行父类的析构函数,必须在子类的析构函数体中显式调用parent::__construct()
       echo "In SubClass constructor";       // 如果不引用父类的析构函数的话,则会自动调用本类的析构函数。
   }
}
class OtherSubClass extends BaseClass {
    // inherits BaseClass's constructor      // 子类如果自己没有定义析构函数,则会继承父类的。
}
$obj = new BaseClass();                      // In BaseClass constructor
$obj = new SubClass();                       // In BaseClass constructor   // In SubClass constructor
$obj = new OtherSubClass();                  // In BaseClass constructor

成员常量 (不会改变的量,是一个恒值)

class ClassName{
    const PI = 3.14159;
    public function aaa(){
        echo self::PI; //          类内推荐使用这种方法调用类成员属性
    }
}
echo ClassName::PI;  //3.14159     类外直接调用常量
$a = new ClassName();
$a->aaa();           //3.14159

私有成员 private 将数据完全隐藏起来,只能在类中被访问,类外与子类不能访问。

保护成员 protected 可以在本类和子类中被访问,其他地方则不能被调用。

class ClassName{
    protected $carName = '奥迪';
}
class car extends ClassName{
    public function say(){
        echo '父类:'.$this->carName; //$this只能在类的内部使用,"::"可以在没有声明任何实例的情况下访问类中的成员 (如下)
    }
}
$a = new car();
$a->say();           // 父类:奥迪
$b = new ClassName();
$b->carName          // 会报错 因为在类外部是无法访问protected修饰的常量,得写一个方法,要用public修饰。

  • “::”操作符

关键字::变量名/常量名/方法名

parent::关键字:可以调用父类中的公共的成员变量、公共的成员方法和公共的常量。

self::关键字:可以调用当前类中的静态成员和静态常量。

类名::关键字:可以调用本类中的公共的变量、公共的常量和公共的方法。

class ClassName{
    const PI = 3.14159;
    public function aaa(){
        return self::PI;
    }
    public function bbb(){
        return ClassName::aaa();
    }
    public function ccc(){
        return $this->carName;
    }
    protected $carName = '奥迪';
    private $carNames = '宝马';
}
class car extends ClassName{
    public function say(){
        echo '父类:'.parent::ccc();
        echo '父类:'.parent::bbb();
    }
}
$a = new car();
echo $a->say();            // 父类:奥迪父类:3.14159
echo $a->bbb();            // 3.14159
echo $a->carName;          // 会报错 因为在类外部是无法访问protected修饰的常量,得写一个方法,要用public修饰。

  • static关键字

  1. 关键字static修饰的成员属性称为 静态属性,成员方法称为 静态方法,它属于类本身而不属于类的任何实例。相当于存在类中的全局变量,可以在任何位置通过类名访问。如下:Web::change()

  2. “::”称为范围解析操作符,用于访问静态成员、静态方法和常量,还可以用于覆盖类中的成员和方法。

  3. 如果要在类内部的成员方法中的访问 静态属性 或者 要在类内部的成员方法中引用 静态方法 ,则只需要“self::静态属性/静态方法”即可。如下:self::$num,self::change()

class Web{
    static $num = 1;
    static function change(){
        echo "第".self::$num."位访客。";
        self::$num++;
    }
    public function fun(){
        echo self::change().'fun.';
    }
    public function webfun(){
        return self::$num.'&'.Web::$num;
    }
}
$web = new Web();
$web->change();                         // 第1位访客。
$web->change();                         // 第2位访客。
Web::change();                          // 第3位访客。fun.
Web::change();                          // 第4位访客。
echo Web::$num."\n";                    // 第5位访客。6
echo $web->webfun();                    // 6&6

  • 抽象类和接口

抽象类(abstract)和接口(Interface)都不能被实例化的特殊类。注:它们都是配合面向对象的多态性一起使用的。

  • 抽象类:
  1. 抽象类 是不能被实例化的类,只能作为其它类的父类使用。使用abstract关键字来声明。
  2. 抽象类 要只要包含一个抽象方法,且抽象方法中没有方法体,必须要在子类中来调用完成。注:抽象方法也是用abstract来修饰,且后面跟“;”号。
  3. 当子类继承抽象类以后,子类必须把父类中的抽象方法全部都实现,否则子类中还存在抽象方法,所以还是抽象类,也不能实例化对象。
  4. 抽象类:
abstract class Person{
    protected $name;
    protected $country;
    public function __construct($name="",$country="china"){
        $this->name = $name;
        $this->country = $country;
    }
    abstract function say();
    abstract function eat();
}
Class ChineseMan extends Person{
    public function say(){
        echo $this->name."是".$this->country."人";
    }
    public function eat(){
        echo $this->name."使用筷子吃饭";
    }
}
$chinaeseMan = new ChineseMan("知青");  // ChineseMan类中少Person类中两个抽象方法任何一个都会报错,必须全部实现,才能new
$chinaeseMan->say();  // 知青是china人
$chinaeseMan->eat();  // 使用筷子吃饭
  • 接口:
  1. PHP只支持单继承,如果想要多继承,就要使用接口,PHP可以实现多个接口。
  2. 接口中声明的方法必须是抽象方法,接口中不能声明变量,只能使用const关键字声明为常量的成员属性,且接口中的所有成员都必须具备public的访问权限,所以public 、abstract 可不写。
  3. 接口中 成员只能是常量 成员方法只能是抽象方法,且在子类必须把父类中抽象方法全部实现,否则子类中还存在接口,就不能实例化对象。
  4. 抽象类:
interface Person1{
    const SITENAME = '我在学习PHP';
    function show();
    function code();
}
interface Person2{      // 多个接口继承可使用extends 如: interface Person2 extends Person1
    function hello();
}
class Worker implements Person1,Person2{   // 继承接口使用implements关键字,多个接口用","拼接
    public function show(){
        return self::SITENAME;
    }
    public function code(){
        return '我在写代码';
    }
    public function hello(){
        return 'PHP是非常好的一种语言';
    }
}
$worker = new Worker();  // Worker类中少Person1或者Person2两个接口中任何一个方法都会报错,必须全部实现,才能new实例化对象
echo $worker->show();  // 我在学习PHP
echo $worker->code();  // 我在写代码
echo $worker->hello();  // PHP是非常好的一种语言
echo Person1::SITENAME; // 我在学习PHP

面向对象的多态

不同的对象,收到同一消息将可以产生不同的结果,这种现象称为多态性。

多态性的一般定义为:同一个操作作用于不同的类的实例,将产生不同的执行结果。即不同类的对象收到相同的消息时,将得到不同的结果。

多态即多种表现方式:,也作一个对外接口,多个内部实现方法。

实现多态有两种实现方法:

通过继承实现多态

abstract class parent1{
    abstract function travel();
}
// 通过继承实现多态
class car extends parent1{
    public function travel(){
        echo "开着小车去旅游";
    }
}
class bus extends parent1{
    public function travel(){
        echo "坐着大巴去旅游";
    }
}
function check($obj){
    if($obj instanceof car){
        $obj->travel();
    }elseif($obj instanceof bus){
        $obj->travel();
    }else{
        echo "Error: 对象错误!";
    }
}
check(new car()); // 开着小车去旅游
check(new bus()); // 坐着大巴去旅游

通过接口实现多态  

interface parent2{
    function travel();
}
class cars implements parent2{
    public function travel(){
        echo "开着小车去旅游";
    }
}
class buss implements parent2{
    public function travel(){
        echo "坐着大巴去旅游";
    }
}
function checkInterface($obj){
    if($obj instanceof cars){
        $obj->travel();
    }elseif($obj instanceof buss){
        $obj->travel();
    }else{
        echo "Error: 对象错误!";
    }
}
checkInterface(new cars()); // 开着小车去旅游
checkInterface(new buss()); // 坐着大巴去旅游

面向对象的其他关键字

  • final关键字 (最终的、最后的)

两种格式:

class parent1{
    final function travel(){
        echo '该方法在子类中不可被重写,也不可在被覆盖';
    }
}
final class parent1{
    // 该类不能再被继承,也不能在有子类
}

  • clone关键字 (克隆对象)

使用clone克隆的对象与原对象没有任何关系,它是将原对象从当前位置重新复制了一份,也就是相当于在内存中新开辟了一块空间。

对象克隆成功后,它们中的成员方法、属性以及值是完全相同的。如果要为克隆后的副本对象在克隆时候重新为成员赋初始值,就要使用魔术方法 __clone

 

class book{
    public function __construct($param){
        $this->param = $param;
    }
    public function type(){
        return $this->param;
    }
    public function __clone(){
        return $this->param = '克隆';
    }
}
$book1 = new book('原本');
echo $book1->type();         // 原本
$book2 = clone $book1;
echo $book2->type();         // 克隆

  • __set() 和 __get()方法

__set() 和 __get()方法 用于对私有成员进行 赋值 或者 获取值 的操作。

__set() 为私有的成员属性设置值,它不需要任何返回值。

__get() 在对象的外部获取私有成员属性的值,它返回一个允许对象在外部使用的值。

class Person{
    private $name;
    private $sex;
    private $age;
    public function __get($property_name){
        echo "在直接获取私有属性值的时候,自动调用了这个__get()方法";
        return $this->$property_name;
    }
    public function __set($property_name, $value){
        echo "在直接设置私有属性值的时候,自动调用了这个__set()方法为私有属性赋值";
        $this->$property_name = $value;
    }
}
$p1 = new Person();
$p1->name = "张三";           // 在直接设置私有属性值的时候,自动调用了这个__set()方法为私有属性赋值
$p1->age = 20;                // 在直接设置私有属性值的时候,自动调用了这个__set()方法为私有属性赋值
echo "姓名:".$p1->name;      // 在直接获取私有属性值的时候,自动调用了这个__get()方法 姓名:张三
echo "性别:".$p1->sex;       // 在直接获取私有属性值的时候,自动调用了这个__get()方法 性别:
echo "年龄:".$p1->age;       // 在直接获取私有属性值的时候,自动调用了这个__get()方法 年龄:20

  • __isset() 和 __unset()方法

__isset()  可以对共有的成员属性进行检测,对于私有的成员属性无法检测。

如果类中存在 ”__isset()“方法,当在类外使用isset()函数检测对象中的私有成员属性时,就会自动调用“__isset()”方法完成对私有成员属性的检测。

在面向对象中,通过”unset()”函数可以对共有的成员进行 删除 操作,但是对于私有的成员属性,就必须有“__unset()”方法才能完成删除。

class Person {
    private $name;
    private $sex;
    private $age;
    public function __get($property_name) {
        if(isset($this->$property_name)){
            return $this->$property_name;
        }else{
            return '该参数不存在';
        }
    }
    public function __set($property_name, $value) {
        $this->$property_name = $value;
    }
    public  function __isset($nm) {
        echo "isset()函数测定私有成员时,自动调用";
        return isset($this->$nm);
    }
    public  function __unset($nm) {
        echo "当在类外部使用unset()函数来删除私有成员时自动调用的";
        unset($this->$nm);
    }
}
$p1 = new Person();
$p1->name = "this is a person name";          
var_dump(isset($p1->name));                 // isset()函数测定私有成员时,自动调用   bool(true)
echo $p1->name;                             // this is a person name
unset($p1->name);                           // 当在类外部使用unset()函数来删除私有成员时自动调用的
echo $p1->name;                             // isset()函数测定私有成员时,自动调用   该参数不存在

  • __call()方法

当程序试图调用不存在或不可见的成员方法时,PHP会先调用__call()方法来存储方法名及其参数。其中,方法参数是以数组形式来存在的。

class Fir {
    public function exist(){
        echo '调用方法存在';
    }
    public function __call($funName, $param) {
        echo '当方法不存在时候会自动调用此方法';
        echo '不存在的方法名为'.$funName;
        var_dump($param);
    }
}
$p1 = new Fir();
$p1->exist();                                // 调用方法存在
$p1->noexist('noExist','this is name');       // 当方法不存在时候会自动调用此方法 不存在的方法名为noexist array(2) { [0]=> string(7) "noExist" [1]=> string(12) "this is name" }

  • __toString()方法

作用:当使用echo 或print输出对象时,将对象转化为字符串。另外,__toString()需要return一个返回值。

输出对象时,应该注意echo或print函数后要直接跟要输出的对象,中间不要加多余的字符。否则__toString()方法不会被执行。

class Fir {
    public function __toString(){
        return '直接打印 new对象的时候 自动调用执行';
    }
}
$p1 = new Fir();
echo $p1;                // 直接打印 new对象的时候 自动调用执行

  • __autoload()方法

在指定路径下自动查找和该类名称相同的文件,如果找到,继续执行,否则报错。 

<?php
//  文件名为Fir.php
class Fir {
    public function __toString(){
        return '直接打印 new对象的时候 自动调用执行';
    }
}
function __autoload($className){            // 当new的类不存在时候 自动调用 __autoload()函数 并且 把new的类名作为参数传进去
    $classPath = $className.'.php';
    if (file_exists($classPath)) {
        include_once($classPath);           // $className = 'Fir'  相当于引入 Fir.php文件
    }else{
        echo '类路径错误';
    }
}
echo new Fir();                             // 当直接打印对象的时候 则调用自动__toString()函数 输出结果   直接打印 new对象的时候 自动调用执行。

 

 

【基于Python的大麦网自动抢票工具的设计与实现】 随着互联网技术的发展,网络购票已经成为人们生活中不可或缺的一部分。尤其是在文化娱乐领域,如音乐会、演唱会、戏剧等活动中,热门演出的门票往往在开售后瞬间就被抢购一空。为了解决这个问题,本论文探讨了一种基于Python的自动抢票工具的设计与实现,旨在提高购票的成功率,减轻用户手动抢票的压力。 Python作为一种高级编程语言,因其简洁明了的语法和丰富的第三方库,成为了开发自动化工具的理想选择。Python的特性使得开发过程高效且易于维护。本论文深入介绍了Python语言的基础知识,包括数据类型、控制结构、函数以及模块化编程思想,这些都是构建抢票工具的基础。 自动化工具在现代社会中广泛应用,尤其在网络爬虫、自动化测试等领域。在抢票工具的设计中,主要利用了自动化工具的模拟用户行为、数据解析和定时任务等功能。本论文详细阐述了如何使用Python中的Selenium库来模拟浏览器操作,通过识别网页元素、触发事件,实现对大麦网购票流程的自动化控制。同时,还讨论了BeautifulSoup和requests库在抓取和解析网页数据中的应用。 大麦网作为国内知名的票务平台,其网站结构和购票流程对于抢票工具的实现至关重要。论文中介绍了大麦网的基本情况,包括其业务模式、用户界面特点以及购票流程,为工具的设计提供了实际背景。 在系统需求分析部分,功能需求主要集中在自动登录、监控余票、自动下单和异常处理等方面。抢票工具需要能够自动填充用户信息,实时监控目标演出的票务状态,并在有票时立即下单。此外,为了应对可能出现的网络延迟或服务器错误,工具还需要具备一定的错误恢复能力。性能需求则关注工具的响应速度和稳定性,要求在大量用户同时使用时仍能保持高效运行。 在系统设计阶段,论文详细描述了整体架构,包括前端用户界面、后端逻辑处理以及与大麦网交互的部分。在实现过程中,采用了多线程技术以提高并发性,确保在抢票关键环节的快速响应。此外,还引入了异常处理机制,以应对网络故障或程序错误。 测试与优化是确保抢票工具质量的关键步骤。论文中提到了不同场景下的测试策略,如压力测试、功能测试和性能测试,以验证工具的有效性和稳定性。同时,通过对抢票算法的不断优化,提高工具的成功率。 论文讨论了该工具可能带来的社会影响,包括对消费者体验的改善、对黄牛现象的抑制以及可能引发的公平性问题。此外,还提出了未来的研究方向,如增加多平台支持、优化抢票策略以及考虑云服务的集成,以进一步提升抢票工具的实用性。 本论文全面介绍了基于Python的大麦网自动抢票工具的设计与实现,从理论到实践,从需求分析到系统优化,为读者提供了一个完整的开发案例,对于学习Python编程、自动化工具设计以及理解网络购票市场的运作具有重要的参考价值。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值