4.PHP面向对象

1. 面向对象的基本概念

1.1 什么是面向对象编程。

准确的说面向对象编程我们叫 OOP.面向对象的编程分为三部分:面向对象分析(Object Oriented Analysis,OOA)、面向对象设计(Object Oriented Design,OOD),以及面向对象编程(Object Oriented Programming)。面向对象编程的两个中个重要的概念是类和对象。

1.2. 类

世间万物皆对象,万事万物皆对象。当然,这是在 js 当中的一个概念。在其他的编程语言当中,我们说世间万物都具有它自身的属性和方法,通过这些属性和方法,可以将不同的事物区分开来,这就是我们面向对象类的抽象。例如,人具有身高。体重和肤色等等这些属性。还可以吃饭,学习走路可以做一些活动。这些活动就是人具有的功能。而前面所说的体重,肤色,身高等等这些是什么呢?是属性。所以我们就可以把人看作是程序当中的一个类。那么人的身高可以看做什么?可以看做类的属性走路啊,吃饭呀,可以看做类的方法。所以什么是类,类是属性和方法的集合.是面向对象编程最核心的东西。也是它的基础。所以通过类,我们可以将一些零散的用来去实现某一个功能的代码进行一些管理。比如说,我们可以创建一个运动类。爱运动类里面包括有这么些个属性姓名身高体重年龄。和性别,然后我再定义几个方法,他能踢足球,他能打篮球啊,能举重能跳高。能吃能玩。

1.3. 对象

类只是具备某项功能。一个抽象模型实际应用当中呢,我们需要使用的是对象。所以我们就需要从那当中去实例化出来这个对象,然后去使用这些对象。对象呢,是类进行实例化之后的一个产物。它是一个实体,是一个独立的个体。例如,我们仍然以人为例。"黄种人是人"这句话没错,但是反过来说 "人是黄种人",就有问题,因为除了黄种人,还有白人,黑人等就,这里的"黄种人"就是"人"这个类中的一个实例对象。

1.4. 面向对象的三大特征

面向对象编程的大大特征就是封装性,继承性,多态性

1.4.1. 封装性

封装性也可称之为信息隐藏,就是把一个类的使用和实现分开,只保留有限的接口(方法)与外部练习。同时也避免程序之间的 相互依赖而产生的不便。

1.4.2. 继承性

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

1.4.3. 多态性

同一个类的不同对象,调用一个方法可以获得不同的结果。增强程序的灵活性和重用性。

2. PHP 对象

2.1. 类的定义

和很多其他面向对象的语言一样,PHP 通过 class 关键字加类名来定义类。



2.2. 成员方法

类中的函数被称为成员方法,函数与成员方法唯一的区别就是函数实现的是某个独立的功能。而成员方法实现的是类的一个行为,它是类的其中一部分。
关键字(修饰符) 成员方法

';
        echo $age.'
'; echo $height.'
'; // return ; } } ?>

2.3. 类的实例化

首先我们要实例化对象(通过 new 关键字 实例化对象),才能通过对象执行对应的行为方法。通过对象->成员方法 来调用成员方法。

=180){
            return $name.'符合打篮球的身体素质要求!';
        }else{
            return $name.'不符合打篮球的身体素质要求!';
        }
    }
}
$s1=new SportObject();
echo $s1->bealBasketBall('张三',20,170,'男');
$s2=new SportObject();
echo $s1->bealBasketBall('李四',40,181,'男');
?>

2.4. 成员变量

类中的变量,也称为成员变量。有些人也把它叫做属性或者字段。成员变量的是用来保存数据信息。或者与成员方法进行一些交互来实现某项功能。
定义成员变量和成员方法:
关键字(修饰符) 成员变量名

关键字可以使用public ,private, protected, static 中的任意一个。

访问成员变量和成员方法的方法一样,对象->成员变量

class SportObject{
    // 声明成员变量。
    public $name;
    public $height;
    public $sex;
    public function boolFootBall($name,$height,$sex){
            return $name.'是个足球运动员';
    }
}
$s1=new SportObject;
$s1->name='佚名';
var_dump($s1);
// $s1->boolFootBall('佚名');

不管是”this->" 还是"对象名->"哪种格式,后面的变量名是没有$符号的.

2.5. 类常量

常量是在程序运行期间,不可改变的量,我们说他是一个恒值,举例圆周率就是一个常量。定义常量,我们使用关键字 const。

class SportObject{
    const SPORT_TYPE="体育运动";
    public $name;
    function setName($name){
        $this->name=$name;
    }
    function getName(){
        return $this->name;
    }
}
$s1=new SportObject;
$s1->setName('aaa');
echo $s1->getName().'
'; echo $s1->name.'
'; echo SportObject::SPORT_TYPE.'通过类::常量名';

2.6 构造函数和析构函数

2.6.1 构造函数

当一个类实例化为一个对象的时候,可能可能会随着对象的初始化而初始化一些成员变量。就是给一些成员变量复制值。这种情况下我们就可以使用构造函数。因为咱对象实例化过程当中构造函数是自动执行的。

class Person{
    public $name;
    public $age;
    public $sex;
    public $height;
    // 我们可以通过"__construct()"
    public function __construct(){
        echo '123';
    }
}

$p1=new Person;
// 如果成员变量过多,写起来比较麻烦
// $p1->name='aa';

构造函数是在初始化对象时使用的,如果类中没有构造方法,PHP 会自动生成一个构造函数,自动生成的构造方法是没有参数的。

2.6.2 析构函数

析构函数的作用和构造方法方法刚好相反,是对象被销毁时被调用的,作用是释放内存。

name=$name;
        $this->height=$height;
        $this->age=$age;
        $this->sex=$sex;
        echo $this->sayHi();
    }
    public function sayHi(){
        return "你好,我叫$this->name ,我今年$this->age 岁了,身高$this->height,性别$this->sex";
    }
    // 析构函数
    public function __destruct(){
        echo '已经被释放掉了';
    }
}
$p2=new Person("佚名",180,23,'女');

2.7 继承和多态

其实继承和多态啊最根本的作用就是完成代码的重用。

2.7.1 继承

子类继承父类的所有成员变量方法,包括构造方法,当子类被实例化的时候,PHP 会先在子类当中找构造方法,如果子类已经有自己的构造方法。PHP 会先调用子类的方法。当子类当中没有的时候,PHP 才会去调用。父类当中的构造方法,这就是继承。

// 父类(基类)
class SportClass{
    // 定义成员变量
    public $name;//姓名
    public $age;//年龄
    public $weight;//体重
    public $sex;//性别
    public function __construct($name,$age,$weight,$sex){
        $this->name=$name;
        $this->age=$age;
        $this->weight=$weight;
        $this->sex=$sex;
    }
    function sayHi(){
        echo '你好,我是'.$this->name;
    }
}

/**子类(派生类)BealBasketBall*/
class BealBasketBall extends SportClass{//定义子类,继承父类
    // 定义成员变量  身高
    public $height;
    public function __construct($name,$height){
        $this->height=$height;
        $this->name=$name;
    }  

    // function sayHi(){
    //     echo '你好,我是'.$this->name;
    // }
}

$b1=new BealBasketBall('曾辉',198);

2.7.2 多态

多态好比有一个成员类,方法是让大家去游泳,这时有人带着游泳圈还有人拿着浮板。还有人什么也不带。虽然是同一种方法,但是却产生了不同的形态,这就叫多态。

多态存在两种形式,覆盖和重载。
1).所谓的覆盖,在子类中重写父类的方法。而在子类的对象当中,虽然调用的是父类当中相同的方法,但返回的结果是不一样的。上面的那个例子当中都调用了父类当中的说明方法。但是返回的结果却不同。
2).再就是重载,重载是类的多态的另外一种体现。函数在重载的时候会有一个标识符。被当做多个函数名称。而且呢,能够通过函数的参数的个数或者参数的类型,将这些同名的函数区分开来,(方法名称是相同的),可能是参数的数量或者参数的类型不同。以便于去使用和调用的时候不发生混淆。
PHP所提供的重载(overloading)是指动态地创建类属性和方法。我们是通过魔术方法(magic methods)来实现的。

class A{
    function __call($name,$num){
        echo "方法名称:".$name.'
'; echo '参数存在的个数:'.count($num).'
'; if(count($num)==1){ echo $this->list1(); } if(count($num)==2){ echo $this->list2(); } } public function list1($a){ return "这是list1函数,:参数:$a"; } public function list2($a,$b){ return "这是list1函数,:参数1:$a ,参数2:$b "; } } $a=new A; $a->list(1);

2.8 "$this->" 和"::"的使用

PHP通过为变量this->和域的操作符"::"来访问自己的成员变量和成员方法的

1.this->

在本类内部我们可以通过this访问当前实例化对象,调用方法或成员变量的话则使用 "this->成员变量" || "this->成员方法" 来访问。所以 this-> 只在类的内部使用

class Demo{
    function exam(){
        if(isset($this)){
            echo '$this的值:'.get_class($this);
        }else{
            echo '$this 未定义';
        }
    }
}
$d1=new Demo;
$d1->exam();

2. 操作符::
$this只能在类的内部去使用。操作符"::"可以在没有声明任何实例的情况下,访问类当中的成员方法或成员变量。

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

关键字有三种情况:

  • parent: 可以调用父类中的 成员变量,成员方法和常量
  • self:可以调用当前类中的 静态成员和常量
  • 类名:可以调用本类中的静态变量,常量和静态方法
class A{
    const NAME_='A';
    public $name;
    public $age;
    public $sex;
    public function __construct($name,$age,$sex){
        $this->name=$name;
        $this->age=$age;
        $this->sex=$sex;
    }
}

class B extends A{
    const NAME_='B';
    public $height;
    public $weight;
    public function __construct($name,$age,$sex,$height,$weight){
        parent::__construct($name,$age,$sex);  
        $this->height=$height;
        $this->weight=$weight;
    }
    public function a(){
        self::NAME_;
        parent::NAME_;
    }
}
$b1=new B('姓名','年龄','xingbie','身高','体重');
B::NAME_;

2.9 修饰符

public、private、protected、static和final。这些关键字是用来限定类成员(包括方法和变量)的访问权限。

2.9.1 public(公共成员)

顾名思义就是可以公开的,没有必要去隐藏的一些数据信息。可以用public来去修饰当前的成员方法或者成员变量。它可以在程序的任何位置出现(类的内部,类的外部)。可以被其他的类和对象去调用。子类呢可以继承和使用父类当中所有的,公共成员。

class Person{
    public $name="李雷";
    public function fn(){
        // 1.可以在类的内部访问,对当前类的 内部可见
        echo $this->name;
    }
}

class Students extends Person{
    public function fn1(){
        // 2.可以在子类的内部访问,对子类的内部可见
        echo $this->name;   
        $this->fn();
    }
}
// 3.在类的外部可见
$s1=new Person();
$s1->fn();
$s2=new Students();
$s2->fn();
$s2->fn1();

2.9.2 private(私有成员)

被private关键字所修饰的成员方法和变量,只能在所属类的内部被调用和修改,不可以在类外部访问,在子类中也不可以。

name=$name;
    }
    public function getName(){
        echo $this->name;
    }
    private function c1(){
        echo '123';
    }
}

class Histoty extends Book{
    public function getBookName(){
        // 2.在子类内部不可见 不可访问继承来的父类中的私有成员变量 私有方法
        echo $this->name;
        $this->c1();
    }
}
// $b1=new Book;
// $b1->setName('PHP');
// $b1->getName();
// 3.在类的外部不可访问 私有成员变量或私有成员方法
// $b1->name='js';
// $b1->c1();

$h1=new Histoty();
$h1->getBookName();

对于成员方法和成员变量,如果没有指定关键字,那就默认是public。

2.9.3 protected(保护成员)

被protected 修饰的类成员,可以在当前类和子类中被调用。去其他地方则不可以访问。

class Person{
    protected $money=10;
    public function fn(){
        echo $this->money;
        // 1.在当前的内部可以访问
    }
}
class Stu extends Person{
    public function fn1(){
        echo $this->money;
        // 2\. 可以在子类的内部访问
    }
}
// 3\. 在类的外部不能直接访问,
$p1=new Person;
$p1->fn();
// echo $p1->money;
$s1=new Stu;
$s1->fn1();

2.10 静态成员(变量,方法)

不是所有的方法都要通过创建对象来去调用的,我们可以。通过给变量或者方法加上static关键字来直接调用。也叫做访问静态成员。

//关键字::静态成员

关键字可以有两种:

  • self,在类的内部调用静态成员是使用。
  • 静态成员所在的类名,在类的外部调用类内部的静态成员时所使用。
    在静态方法当中只能调用静态变量,而不能调用普通的变量。而普通方法里面可以调用静态变量。
    使用静态成员,除了可以不需要实例化对象外,另一个作用就是在对象被销毁后,仍然保留被修改的静态数据,以便于下次继续使用。
class Book{
    static $num=0;//声明一个静态变量$num,初始值为0;
    public function showMe(){
        echo '您是第'.self::$num.'位访客';
        self::$num++;//
    }
}
$b1=new Book();
$b1->showMe();
$b2=new Book();
$b2->showMe();
echo '一共有'.Book::$num.'位访客';

2.11 final 关键字

被final修饰过的类和方法就是"最终的版本",如果类被final修饰过,该类不可以再被继承,也不能再有子类。

final class Book{
    public $name='';
    public function __construct($name){
        $this->name=$name;
    }
}
class Histoty extends Book{
    public $height='';   
}
//结果: Fatal error: Class Histoty may not inherit from final class (Book)

如果方法被final修饰过,方法在子类中不可以进行重写,也不可能被覆盖。


class Book{
    public $name='';
    public function __construct($name){
        $this->name=$name;
    }
    final public function getName(){
        echo $this->name;
    }
}
class Histoty extends Book{
    public $height='';   
    public function  getName(){
        echo '123';
    }
}
//结果:Fatal error: Cannot override final method Book::getName() in

2.12 对象类型检测

instanceof操作符可以检测当前对象是属于哪一个类。

ObjectName instanceof ClassName

class Book{
    public $name='';
    public function __construct($name='佚名'){
        $this->name=$name;
    }
}
class History{

}
$a=new Book;
$b=new History;
// var_dump($a instanceof Book);//true
var_dump($b instanceof Book);//false

3.魔术方法(__)

3.1 __get和__set() 方法

这两个魔术方法的作用分别是:

  • 当程序试图去写入一个不存在或者不可见的成员变量的时候PHP就会执行__set()方法。__set()方法呢,包括有两个参数,分别是变量名称和变量的值,这两个参数不可省略。

  • 当程序调用一个未定义或者不可见的成员变量的时候,可以通过__get()方法来去读取变量的值.__get()这个方法有一个参数表示你要调用的这个变量名称。

$name)){//判断变量是否被声明
            echo '变量'.$name.'值:'.$this->$name.'
'; }else{ echo '变量'.$name.'未定义'; $this->$name=0; echo $this->$name; } } public function __set($name,$value){ if(isset($this->$name)){ echo '私有成员'; echo '变量'.$name.'赋值:'.$value.'
'; }else{ $this->$name=$value; echo '变量不存在'; } } } $b=new SportClass(); // echo $b->type; // echo $b->sex; // $b->type='213'; $b->sex=234; echo $b->sex;

3.2 __tostring()方法

当使用echo或print输出对象时,将对象转化为字符串。

class SportClass{
    private $type='21312';
    public function __tostring(){
        return $this->type;
    }
}
$b=new SportClass;
echo $b;

3.3 __autoload()方法

尝试加载未定义的类是,触发__autoload()方法,__autoload()接受一个参数,参数是类的名称。

function __autoload($classname){
    $class_path=lcfirst($classname).'Class.php';
    if(file_exists($class_path)){
        include_once($class_path);
    }
}

$b=new BaseFile;
var_dump($b);
$c=new Base();
var_dump($c);

3.4 中文字符串截取类

在PHP当中我们经常要去对字符串进行一些截取。如果是英文字符串的话,我们可以直接使用substr()函数来去完成。但是当出现中文字符串的时候,如果你依然使用这个substr()函数,就有可能会出现乱码的情况。因为一个汉字是由两个字节组成的。所以当截取的字符如果出现奇数的时候,就有可能将一个汉字给拆分开来。从而导致输出一个不完整的汉字,显示出来就是乱码。

你可能感兴趣的:(4.PHP面向对象)