08-类与对象

类与对象

php的类与对象这节,和其它面向对象语言可谓是基本一样,如果说你学了Java或者C++,理解起来就十分容易,当然php自己也拓展了许多类的其它功能。我们一起探究下

直接看php类的代码,学习它的类基本语法,我们可以看出,php类的定义还是和Java很像的

class People
{
    private $age;
    private $name;
    //构造函数
    public function __construct($age,$name)
    {
        $this->age = $age;
        $this->name = $name;
    }
    //方法getInfo
    public function getInfo()
    {
        echo "age: ".$this->age." name: ".$this->name.self::num;
        echo "<hr>";
    }
    //析构函数
    public function __destruct()
    {
        // TODO: Implement __destruct() method.
        echo "我被释放了";
    }
}

1.创建对象的六大方法

get_class(对象):可以查看这个对象的类名

//father类
class Father
{
    //构造函数
    public function __construct()
    {

    }
    //类里创建Father对象,返回给外界
    public function creatF()
    {
        return new self();
    }
    //类里创建Father对象,返回给外界
    public function creatFs()
    {
        return new static();
    }
    //析构函数
    public function __destruct()
    {
        // TODO: Implement __destruct() method.
    }
}

//Son类继承Father类
class Son extends Father
{
    //Son类定义创建父亲对象的方法
    public function creatS()
    {
        return new parent; // TODO: Change the autogenerated stub
    }
}
  1. 通过new直接创建

     $f1 = new Father();
     echo get_class($f1);//Father
    
  • 通过已经创建的对象间接创建新对象

      $f1 = new Father();
      $f2 = new $f1();
      echo get_class($f2);//Father
    
  • 通过类变量创建对象,php函数有函数变量,就是变量的值等于函数名,类变量也是如此,一个变量的值等于类的名称,可以用这个变量直接创建对象.

      $num = "Father";
      $f3 = new $num();
      echo get_class($f3);//Father
    
  • 通过类方法self创建对象

      //在类里随便创建个函数,函数功能实现返回self创建对象就行
      $f1 = new Father();
      $f4 = $f1->creatF();
      echo get_class($f4);//Father
    
  • 通过类方法static创建对象

      //在类里随便创建个函数,函数功能实现返回static创建的对象
      $f1 = new Father();
      $f5 = $f1->creatFs();
      echo get_class($f5);//Father
    
  • 通过子类的间接创建目标父类对象,返回给外界

      $s = new Son;
      $f6 = $s->creatS();
      echo get_class($f6);//Father
    

总结,虽然我们列出来6种创建对象的方法,其实最多的还是第一种,其它5种也得能看懂。

2.类常量

类常量就是类里面始终不会变化的变量,用const修饰,且创建时常量前面不用加$符号
且前面不加权限修饰符public/protected/private,常量不可修改

class Test_1
{
    const num = 10;
    public function getNum()
    {
        echo Test_1::num;
        echo self::num;
    }
}

//类常量在类方法里面通过两种方式访问
//1 类名::常量
//2 self::常量
//类常量在类外面访问也是两种方式
//1 类名::常量
//2 实例对象::常量

$t1 = new Test_1();
$t1->getNum();//10 10
echo $t1::num;//10
echo Test_1::num;//10

3.类文件的自动加载

当我们需要调用其它php文件的类时,需要引入其它类对应的php文件,这个时候我们需要去找php文件地址,而且代码会出现大量require/include的字样,为了省去引入文件的过程,我们可以通过spl_autoload_register(function)实现自动加载外部类

文件1

//Test1.php
<?php
class Class1{

}

文件2

//Test2.php
<?php
class Class2{

}

文件3

<?php
//声明这个,就可以在调用外部类时,自动加载文件,不用写加载php文件了
spl_autoload_register(
    function ($name)
    {
        include_once $name.".php";
    }
);
$t1 = new Class1();//自动加载
$t2 = new Class2();//自动加载

4.对象的封装

对象通过public/private/protected访问控制符和get与set方法对类进行完成的封装,除此以外,php还提供了让类的外部对象可以直接访问类里任何变量,甚至可以直接修改类里的变量.

class Father
{
    private $age;
    //构造函数
    public function __construct($age)
    {
        $this->age = $age;
    }
    //析构函数
    public function __destruct()
    {
        // TODO: Implement __destruct() method.
    }
    //设置私有age的值
    public function setAge($age)
    {
        $this->age = $age;
    }
    //返回私有age值
    public function getAge()
    {
        return $this->age;
    }
    //可以直接访问类的全部变量
    public function __get($name)
    {
        return $this->$name;
    }
    //可以直接修改类的全部变量
    public function __set($name, $value)
    {
        $this->$name = $value;
    }
    //查询类是否包含这个属性
    public function __isset($num)
    {
        return isset($this->$num);  
    }   
    //删除类的某个属性
    public function __unset($num)
    {
        unset($this->$num);
    }
}

//正常过程,没有写__get与__set函数前
$f1 = new Father(20);
$f1->age = 21;//error
echo $f1->age;//error
$f1->setAge(21);//通过方法间接修改age
echo $f1->getAge();//21
//通过设置__get,可以直接访问原来不可以直接访问的变量
//通过设置__set,可以直接修改原来不可以直接修改的变量
$f1 = new Father(20);
$f1->age = 21;
echo $f1->age;//21
//通过设置__isset(),可以查看类是否存在某个属性
echo isset($f1->age);//1,存在
//通过设置__unset(),可以删除类的对应的属性
unset($this->age);//类的age属性被删除

5.类的静态属性和方法

php类的静态属性和方法规则和Java一样,用static修饰

  • 静态属性和静态方法属于全部类共有的。
  • 静态方法只可以调用静态方法和静态属性
  • 静态方法和属性访问格式 类名::静态方法/属性
    class Test
    {
        //静态属性
        public static $num = 10;
        public $arr = 20;
        //静态方法
        public static function getNum()
        {
            echo Test::$num;
        }
        public static function getArr()
        {
            echo $this->arr;//error,静态方法不可以访问非静态属性和方法
        }

    }
    echo Test::$num;//10,通过类名直接访问
    Test::getNum();//10,通过类名直接访问

6.对象的克隆和拷贝

对象变量之间的赋值是引用赋值,指向同一块内存,
对象的克隆是值拷贝,指向两块内存,只是对象的值一样。

class Test_2
{
    private $age;
    public function __construct($age)
    {
        $this->age = $age;
    }

    public function __get($name)
    {
        return $this->$name;
    }

    public function __set($name, $value)
    {
        $this->$name = $value;
    }
}
$t1 = new Test_2(10);
echo $t1->age;//10
$t2 = $t1;
$t2->age = 20;
echo $t1->age." ".$t2->age;//20 20
$t3 = clone $t1;
echo $t1->age." ".$t3->age;//20 20
$t3->age = 30;
echo $t1->age." ".$t3->age;//20 30

7.抽象方法与抽象类

包含抽象方法的类就是抽象类,抽象类不能被构造,只能由子类继承后实现其全部抽象方法

//抽象类,不能创建对象
abstract class F
{
    abstract public function eat();
    abstract public function sleep();
    public function see()
    {
        echo "i am seeing";
    }
}
//继承抽象类,实现全部抽象方法
class S extends F
{
    public function eat()
    {
        echo "i am eating";
    }
    public function sleep()
    {
        echo "i am sleeping";
    }
}
$s1 = new S;
$s1->eat();//i am eatting

8.接口

接口就是一组规范化的属性和方法集合体,一个类实现了某接口必须实现对应接口的全部方法

  • 接口的属性必须是常量
  • 接口的方法必须是public修饰符
    interface face1
    {
        const num = 100;
        public function add();
        public function go($num);
    }
    
    class S1 implements face1
    {
        public function add()
        {
            echo "add";
        }
    
        public function go($num)
        {
            echo $num;
        }
    }
    $s1 = new S1();
    $s1->add();//add
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,222评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,455评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,720评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,568评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,696评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,879评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,028评论 3 409
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,773评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,220评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,550评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,697评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,360评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,002评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,782评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,010评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,433评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,587评论 2 350

推荐阅读更多精彩内容

  • 常量 public class Demo3 { int num1 ; // 常量作为全局变量中没有默认值,必须赋值...
    果冻_4c9b阅读 108评论 0 0
  • Swift1> Swift和OC的区别1.1> Swift没有地址/指针的概念1.2> 泛型1.3> 类型严谨 对...
    cosWriter阅读 11,093评论 1 32
  • 一、Python简介和环境搭建以及pip的安装 4课时实验课主要内容 【Python简介】: Python 是一个...
    _小老虎_阅读 5,726评论 0 10
  • 把当前目录作为Root Document只需要这条命令即可:php -S localhost:3300 也可以指定...
    绚烂的时光阅读 728评论 0 1
  • 飞翔 不一定需要翅膀 梦想 不一定得到赞扬 怀揣一颗平静的心 却在喧闹的世界里 饱经风霜 曾以为 坚定了信念 忘记...
    Eimbro阅读 176评论 0 0