oop类的继承与类静态成员学习
<?php namespace controller; // 1.变量 实现数据的复用 函数是实现代码块的复用 // 2.类是具有相同属性和方法的对象集合 // 3.对象是复合数据类型 // 4.oop 三大特性:封装 继承 多态 // 5.封装:隐藏对象的属性或方法(实现细节),目的是为了控制在程序中属性的读或者修改的访问级别,使用者只需要通过外部接口以特定的权限来使用类成员 class Player{ // 成员属性 前一定要有 访问修饰符 public protected private public $name;//抽象属性 null public $height; public $team; // protected只能被本类和子类访问 protected $playNump = 18; // 只能被本类访问 private $weight; // 如何给 protected private属性赋值 // __construct()魔术方法构造函数 构造器 类实例化一次就被自动调用一次 // __get __set __call __callStatic public function __construct($name,$height,$team, $playNump,$weight) { // 1.初始化类成员 让类/实例化的状态稳定下来 // 2.给对象属性进行初始化赋值 // 3.可以给私有成员,受保护的成员初始化赋值 $this->name = $name; $this->height = $height; $this->team = $team; $this->playNump = $playNump; $this->weight = $weight; } public function jog() { // $this 本对象 return "$this->name is jogging,whose playNum is $this->playNump<br>"; } public function shoot() { return "$this->name is shooting,weighing $this->weight<br>"; } } // // 类的实例化 new $j对象引用 // $jordan = new Player; // $james = new Player; // //对象成员的访问 对象引用->属性名称/方法名称() // $jordan->name = 'xiaoqi'; // $james->name = 'youyou'; // echo $james->name.'<br>'; // echo $james->jog(); // echo $jordan->name.'<br>'; // echo $jordan->jog(); // // echo $j->playNump // $jordan = new Player('Jordan','205cm','Bulk',23,'80kg'); // echo $jordan->name.'<br>'; // echo $jordan->shoot(); ?>
<?php // 父类 class Product { public $name; public $price; protected $discount = 5; public function __construct($name,$price) { $this->name = $name; $this->price = $price; } public function show() { return "{$this->name}的单价为{$this->price}元"; } final public function display() { return "现在为您展示的商品是{$this->name},它目前的市场价为{$this->price}元。"; } } // // 示例用法 // $product = new Product("苹果",5.99); // echo $product->show();//输出:苹果的单价为5.99元 ?>
<?php // 类的继承(扩展)通过extends关键字实现 //php oop具有单继承的诟病->带来程序的高耦合性:如果程序通过深层次继承绑定到某个具体的类,即使对父类做一些简单的修改1,也会对子类带来严重的破坏 // // trait trait是为类似php的单继承语言而准备的一种代码复用机制 class Son extends Product { // 属性扩展 private $num; // 重写父类构造器 public function __construct($name,$price,$num) { // parent关键字 调用父类中的成员方法 parent::__construct($name,$price); $this->num = $num; } // 重写父类中的普通方法 public function show() :string { return parent::show() .", 数量{$this->num}个,双十一期间打{$this->discount}折"; } // 方法扩展 public function total() { return "商品{$this->name}的总价为".($this->price * $this->num) . '元'; } // 子类不能重写父类中带有final关键字修饰的普通方法 可继承 // public function display() // { // } } ?>
<?php // 类的静态成员 static关键字 标志静态属性/方法 静态成员能为本类调用 为所有实例共享 // 优点: // 1.内存即使存在多个实例,静态成员在内存中只占一份, 为所有实例所共享,普通成员以实例的方法会创建多个内存 // 2.静态成员的执行效率比实例化高,不用创建对象就可以直接调用 // 缺点:静态成员不自动进行销毁,而实例化的则可以销毁 class user{ public static $name = '海绵宝宝'; protected $_config = [ 'auth_on'=>'true', 'auth_type'=>1//认证方式 1。实时认证 2.登陆认证 ]; public static $nation = 'China'; private $salary; static $count = 0;//记录已登录用户的总数 public function __construct($name,$salary) { // 静态成员与类的实例无关 不能用$this访问,用self::类的引用 访问静态成员 self::$name = $name; $this->salary = $salary; self::$count ++; } public static function getCount(){ return sprintf('目前该网站的在线人数为%d<br>', self::$count); } //对象被销毁时自动调用 public function __destruct() { self::$count--; } //静态上下文中不能访问普通属性 // public static functiom getConfig() // { // return sprintf('认证开关:%s<br>,认证类型%d', // $this->_config['auth_on'], // $this->_config['auth_type']); // } public functioN getConfig() { return sprintf('认证开关:%s<br>,认证类型%d',$this->_config['auth_on'],$this->_config['auth_type']); } } //1.静态成员不能访问类中的普通属性(此时还不存在对象) // 2.普通成员是对象级别的存在,只能通过对象访问 默认都提供了$this指针 // 静态成员是类级别的存在 随着类的加载而加载 没有提供$this指针,优先于对象存在 只能用类引用self::访问 ?>
<?php // 加载类文件 类的自动加载器 require 'autoload.php'; $son1 = new Son('显示器',1230,9); $son2 = new Son('电脑',1230,9); echo $son1->price.'<br>'; // echo $son1->discount.'<br>';//Fatal error: Uncaught Error: Cannot access protected property Son::$discount echo $son1->show().'<br>'; echo $son1->display().'<br>'; echo '<bre>'; var_dump($son1); var_dump($son2); // object(Son)#4 (3) #2对象id 每new一次得到不同的示例 就会产生一个新的对象id // 单例模式 类只能被实例化一次 只能产生唯一的对象id $james = new Player('Jordan','205cm','Bulk',23,'80kg'); var_dump($james); echo '<hr>'; var_dump($james instanceof player); var_dump($son1 instanceof Son); ?>
<?php // 加载类文件 类的自动加载器 require 'autoload.php'; $user1 = new User('巧克力',35); $user2 = new User('牛奶巧克力',38); $user3 = new User('酒精巧克力',39); unset($user3);//自动调用_destruct echo User::getCount(); echo User::$name; // 使用对象引用也可以访问静态成员 不推荐 // echo $user1->getCount(); echo User::$nation; echo $user2->getConfig(); ?>
<?php require 'autoload.php'; // (new Product)->show(); $p1 = new Product('被子',56); echo $p1->show(); // 类(对象实例化的结果)与对象(类实例化的结果) // 对象成员之间的内部访问$this // oop封装性 public private protected修饰对象成员 // private仅限本类中使用 protected本类和子类访问 // 静态成员 static 属于类级别的存在 之间的内部访问 self:: // 类的继承 父类中的方法和属性被继承 ,被重写 parent:: 调用父类成员 ?>
<?php // 类的自动加载 前提 类名称与类文件名称保持一致 prs -4规划 // spl_autoload_register(function($className) // { // require $className .'.php'; // }); spl_autoload_register(function($className) { // 先查看要加载的类 printf('类名:%s<br>',$className); // 将命名空间与类所在的路径进行一一映射 // linux / window \ // 解决在Linux系统中命名空间失效的问题 $file = __DIR__.'\\controller\\'.str_replace('\\',DIRECTORY_SEPARATOR,$className).'.php'; // echo $file; if(!(is_file($file) && file_exists($file))) { throw new \Exception('文件名不合法或者不存在'); } require $file; }); // 2.new 类的实例化 // $j= new Player('Jordan','205cm','Bulk',23,'80kg'); // echo $j->shoot(); ?>
<?php // 抽象类不能被实例化 abstract class aDb{ //抽象方法 public function show(){ } } // 具体类 class work extends aDb{ public function show(){ // #根据自己的需求去实现抽象类 } } ?>