类与对象
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
}
}
-
通过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