面向对象编程
面向对象 oop
面向过程编程:直接面向变量和函数的的编程
oop:直接面向对象编程(封装了变量和函数的一个编程单元)
本质是封装目标是代码复用
类
类:对象的模板,声明的类与这个类所在的文件推荐同名
- 类成员:属性,方法
- 访问控制:
- private :私有成员,仅限本类中访问
- public 公共的
- protected : 受保护成员,仅限本类以及子类访问
声明类
class Product
{
// 属性:变量
public $name;
public $age;
// 方法:函数
// 双下划线的方法:魔术方法,由系统自动调用
// 类实例化的时候会调用它
//构造方法
public function __construct($name,$age)
{
//初始化类成员,让类/实例化状态确定下来
// 1、生成类的实例
// $obj=new Product;
//2、给这个新类赋值属性
//$this:当前类实例的引用
$this->name=$name;
$this->age=$age;
//3、返回这个新对象
// return $obj
}
//实例方法
public function index():string
{
return "$this->name:$this->age";
}
}
类的实例化
运行结果图//加载类文件
require 'product.php';
//new 类实例化
$obj=new Product('name',18);
var_dump($obj);
//两个对象完全对立,却是同一个类的实例
$obj1=new Product('user',22);
var_dump($obj1);
echo $obj->index(),'<br>';
echo $obj1->index();
类的自动加载
创建load.php
在客户端脚本中//类的自动加载器
spl_autoload_register(function($class){
require $class.'.php';
});
require 'load.php';
// 实例化
$obj=new Product('类',18);
var_dump($obj);
运行结果图
类的静态成员
类成员并非全部都要使用‘类实例’方法,也由可以直接用‘类’访问的成员
类实例可以访问静态方法,但不推荐这样用
类实例不能访问静态属性
创建User类
在客户端脚本中class User{
public static $name;
public static $age;
public function __construct($name,$age)
{
//静态成员与实例无关,当然不能使用$this访问,用类的引用
//self:当前类的引用
self::$name=$name;
self::$age=$age;
}
public static function show(){
return self::$name.self::$age;
}
}
运行结果图$ob=new User('姓名',18);
echo User::$name,'<br>';
echo User::$age,'<br>';
echo User::show(),'<br>';
echo $ob->show();
类的继承
继承 extends ,子类,实现类的复用
1、对父类方法的重写
2、对父类功能的扩充
创建子类Subrequire 'load.php';
class Sub extends Product{
public $sex;
public function __construct($name,$age,$sex)
{
// $this->name=$name;
// $this->age=$age;
parent::__construct($name,$age);
$this->sex=$sex;
}
public function index():string
{
return parent::index()."$this->sex";
}
}
在客户端脚本中
$obj2=new Sub('姓名',35,'男');
var_dump($obj2);
运行结果图
trait
理解为一个公共方法集,借用了class语法实现的一个轻量级的‘类’。但不是类,所以不能实例化
效果图trait T
{
public function m(){
return __METHOD__;
}
}
class A{
use T;
}
class B{
use T;
}
echo (new A)->m(),'<br>';
echo (new B)->m(),'<br>';
当父类 trait与当前子类中存在同名成员时trait T1
{
public function m(){
return __METHOD__;
}
}
trait T2
{
public function m(){
return __METHOD__;
}
}
class A{
use T1,T2{
T1::m insteadOf T2;
T2::m as T2m;
}
}
echo (new A)->m(),'<br>';
echo (new A)->T2m(),'<br>';
Tips:当子类与父类存在同名成员时,子类优先,当trait中存在与父类同名的成员时,trait优先