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 "
"; } //析构函数 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

文件2

//Test2.php

文件3

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

你可能感兴趣的:(08-类与对象)