php面向对象编程(oop)基础知识示例解释
面向对象并不是一种技术,而是一种思想,是一种解决问题的最基本的思维方式!如何理解使用?OOP:面向对象编程
(直接代码说明)
1.面向对象的基本概念 示例demo:
1 <?php 2 header("Content-Type: text/html;charset=utf-8"); 3 //如何类的实例化? 例如: $newA= new a(); 利用类得到对象,过程是类的实例化.关键字new完成. 4 //如何定义一个类? 例如: class a{} 类 5 //如何声明定义属性? 例如: public $age 属性 声明的控制修饰符:1.public 2.protected 3.private 6 //如何声明定义方法? 例如: public function user(){} 方法 对象成员(属性,方法)的访问符:-> 7 //如何定义类常量? 例如: const WORK = 'php'; 类常量 访问形式: 类名::常量名 8 //小结: 一个类中只有三个成员:1.属性(变量) 2.方法(函数) 3.类常量(常量) 9 class a{//类 10 public $name;//属性 11 public $age; 12 const WORK = 'php';//类常量 13 public function user($object){//方法 14 echo '名字:'.$object->name.'年龄:'.$object->age.'工作'.self::WORK;//在一个类的内部,使用关键字self代替"当前类名" 15 } 16 } 17 $newA = new a();//实例化对象 ==> class a{} 18 $newA->name='admin_a'; 19 $newA->age = 100; 20 $newA->user($newA); 21 22 23 //如何使用$this? 例如: $this代表当前所属类的"当前对象" ,当前谁调用,谁就是"当前对象" 24 //小结: 属性不能在方法内直接访问,需要先找到其对象才能访问,典型的做法就是在方法内使用$this关键字来代替当前对象. 25 class b{ 26 public $name; 27 public $age; 28 const WORK = 'html'; 29 public function user(){ 30 echo '名字:'.$this->name.'年龄:'.$this->age.'工作'.self::WORK;//$this当前对象 31 } 32 } 33 echo "<pre>"; 34 $newB = new b(); 35 $newB->name='admin_b'; 36 $newB->age = 200; 37 $newB->user($newB);
运行结果如下图:
1 $this 和 self 的区别? 2 3 一个是对象$this 相当于实例化后,可以说除了静态和const常量,基本上都可以使用this联络 4 5 self则是类本身 self可以访问本类中的静态属性和静态方法,可以访问父类中的静态属性和静态方法。用self时,可以不用实例化.
2.面向对象中的魔术方法,__construct():构造方法 示例demo
1 <?php 2 header("Content-Type: text/html;charset=utf-8"); 3 //PHP提供__开头的函数,这些函数无需自己手动调用,会在合适的时机自动调用,这类函数称为魔术函数。 4 //__construct():构造方法 new对象时自动调用 5 class a{ 6 public $name; 7 public $age; 8 const WORK = 'php'; 9 public function __construct($user_name,$user_age){//构造方法 10 $this->name=$user_name; 11 $this->age=$user_age; 12 } 13 14 public function user(){ 15 echo '使用构造方法: 名字:'.$this->name.'年龄:'.$this->age.'工作:'.self::WORK; 16 } 17 } 18 19 $userA= new a('admin_a',100);//对象的属性进行初始化 20 $userA->user(); 21 22 $userB= new a('admin_b',200);//对象的属性进行初始化 23 echo '<pre>'; 24 var_dump($userA,$userB);
运行结果如下图:
3.面向对象中的魔术方法,__destruct():析构方法 示例demo
1 <?php 2 header("Content-Type: text/html;charset=utf-8"); 3 //PHP提供__开头的函数,这些函数无需自己手动调用,会在合适的时机自动调用,这类函数称为魔术函数。 4 //__destruct():析构方法 当删除一个对象或一个对象操作结束时被自动调用.(当一个对象被销毁前自动调用) 5 class a{ 6 public $name; 7 public $age; 8 const WORK = 'php'; 9 public function __construct($user_name,$user_age){//构造方法 10 $this->name=$user_name; 11 $this->age=$user_age; 12 } 13 14 public function __destruct(){//析构方法 15 echo '<pre>'.'销毁前自动调用:'.$this->name; 16 } 17 18 public function user(){ 19 echo '使用构造方法: 名字:'.$this->name.'年龄:'.$this->age.'工作:'.self::WORK; 20 } 21 } 22 23 $userA= new a('admin_a',100);//对象的属性进行初始化 24 $userA->user(); 25 $userA= NULL; 26 27 $userB = new a('admin_b',200); 28 echo '<pre>'; 29 var_dump($userA,$userB);
运行结果如下图:
4.面向对象中的魔术方法,__clone() 示例demo
1 <?php 2 //__clone():当使用clone关键字,克隆一个对象时自动调用,作用是为新克隆的对象初始化赋值 3 class a{ 4 public $name; 5 public $age; 6 public function __construct($user_name,$user_age){ 7 $this->name=$user_name; 8 $this->age=$user_age; 9 } 10 11 public function __clone(){ 12 $this->name='admin_b'; 13 $this->age=200; 14 } 15 } 16 17 $userA= new a('admin_a',100); 18 $userB = clone $userA;//克隆新对象 19 echo '<pre>'; 20 var_dump($userA,$userB);
运行结果如下图:
5.静态成员(包含静态属性和静态方法) 示例demo
类中的所有成员:1.非静态属性 2.静态属性 3.非静态方法 4.静态方法 5.类常量
1 <?php 2 header("Content-Type: text/html;charset=utf-8"); 3 //静态成员的定义,名字前面加上关键字static. 静态成员包含1.静态属性 2.静态方法 4 //静态属性类内,类外是如何方法? 5 class a{ 6 public $name; 7 public static $age =100; 8 const WORK = 'php'; 9 public function __construct($user_name){ 10 $this->name=$user_name; 11 } 12 13 public function user(){ 14 //静态属性访问 //常量访问 15 echo '名字:'.$this->name.' (静态属性类内访问) 年龄:'.self::$age.' 工作:'.self::WORK; 16 } 17 } 18 19 $userA= new a('admin_a'); 20 $userA->user(); 21 echo '<pre>(静态属性类外访问) 年龄:'.a::$age; 22 23 24 //静态方法类内,类外如何访问? 25 class b{ 26 public function f1(){ 27 echo '非静态方法f1()'; 28 } 29 30 public static function f2(){ 31 echo '静态方法f2()'; 32 } 33 34 public static function f3(){ 35 self::f2(); 36 } 37 } 38 echo '<pre>'; 39 $newB=new b(); 40 $newB->f1(); 41 echo '<pre>(静态方法类外访问) '; 42 echo b::f2(); 43 echo '<pre>(静态方法类内访问)'; 44 echo b::f3();
运行结果如下图:
6. 类文件的自动 示例demo
1 <?php 2 header("Content-Type: text/html;charset=utf-8"); 3 //类文件的自动加载:自动调用__autoload()函数,该函数传递一个参数是当前类的类名 4 //简单实现自动加载 5 function __autoload($class_name){ 6 if(file_exists($class_name.'.class.php')){ 7 //加载类文件 8 include $class_name.'.class.php'; 9 }else{ 10 return false; 11 } 12 } 13 //实例化自动加载__autoload()函数 14 $newA= new a('admin_a',100); 15 $newA->user();
a.class.php文件
1 <?php 2 class a{ 3 public $name; 4 public $age; 5 const WORK = 'php'; 6 public function __construct($user_name,$user_age){ 7 $this->name=$user_name; 8 $this->age=$user_age; 9 } 10 public function user(){ 11 echo '自动加载类文件获取: 名字:'.$this->name.'年龄:'.$this->age.'工作:'.self::WORK; 12 } 13 }
运行结果如下图:
7.类的继承 示例demo
1 <?php 2 header("Content-Type: text/html;charset=utf-8"); 3 //类的继承: 一个类从另一个已有的类获得其成员的相关特性. 实现继承关键字:extends 4 //派生: 一个已有的类产生一个新的类,称为派生.(比如:B类继承自A类,反过来A类派生出B类) 5 //父类: 也叫作基类,就是指已有被继承的类 6 //子类: 也叫作派生类或扩展类 7 //扩展:在子类中增加一些自己特有的特性,就叫作扩展 8 //单继承: 一个类只能继承自一个其他的类,不能继承多个类.(重点) 9 //面向对象有三大特性:1.继承性 2.多态性 3.封装性 10 class goods{ 11 public $goods_id; 12 public $goods_name; 13 } 14 15 class book extends goods{ 16 public $area; 17 public $type; 18 } 19 20 class manga extends book{ 21 public $author; 22 public $title; 23 public function __construct($goods_id,$goods_name,$type,$area,$author,$title){ 24 $this->goods_id=$goods_id; 25 $this->goods_name=$goods_name; 26 $this->type=$type; 27 $this->area=$area; 28 $this->author=$author; 29 $this->title=$title; 30 } 31 } 32 echo '<pre>'; 33 $manga =new manga('1000','书籍类','中国地区','漫画','米二','一人之下'); 34 print_r($manga);
运行结果如下图:
8.重写 示例demo
1 <?php 2 header("Content-Type: text/html;charset=utf-8"); 3 //重写(覆盖):当子类成员与父类成员名字相同,从父类继承下来的成员会重新定义.(真正作用是子类中定义的成员!) 4 //语法: 父类名::父类的构造方法 关键字parent: 代表的是其父类 (常用写法) 5 class Goods{ 6 public $goods_name; 7 //构造方法 继承类都使用构造方法,如何解决重写(覆盖)问题? 8 public function __construct($g_name){ 9 $this->goods_name=$g_name; 10 } 11 public function getName(){ 12 echo $this->goods_name; 13 } 14 } 15 16 class Book extends Goods{ 17 public $type; 18 } 19 20 class Manga extends Book{ 21 public $title; 22 //先执行子类构造方法,后执行父类构造方法 23 public function __construct($g_name,$m_title){ 24 //调用父类的构造方法并传递变量 25 parent::__construct($g_name); 26 $this->title=$m_title; 27 } 28 public function getName(){ 29 echo 'Goods父类:'; 30 //调用父类getName()方法 31 Goods::getName(); 32 echo '<hr>'; 33 echo 'Manga子类:'; 34 echo $this->title; 35 } 36 } 37 38 $manga = new Manga('商品名称','一人之下'); 39 $manga->getName();
运行结果如下图:
9.最终类和抽象类 示例demo
1 <?php 2 header("Content-Type: text/html;charset=utf-8"); 3 //final类:最终类,不能被继承,只能实例化对象的类! 使用关键字:final 4 //abstract类:抽象类,只能被继承,不能实例化对象的类! 使用关键字:abstract 5 //final类 示例demo 6 class commodity{ 7 public $commodity_id; 8 public $commodity_name; 9 } 10 11 final class book extends commodity{//实际开发过程中的规范 12 public $area; 13 public $type; 14 } 15 $book = new book(); 16 echo '<pre>'; 17 print_r($book); 18 19 //abstract类 示例demo 20 abstract class goods{ 21 public $goods_id; 22 public $goods_name; 23 abstract function type($data); 24 abstract function area(); 25 } 26 27 class manga extends goods{ 28 public $author; 29 public $title; 30 function type($data){ 31 echo $data; 32 } 33 function area(){} 34 } 35 $manga= new manga(); 36 $manga->type('实现type()方法');
运行结果如下图:
10.interface接口 示例demo
1 <?php 2 header("Content-Type: text/html;charset=utf-8"); 3 //接口: 如果一个类中,所有的方法都是抽象方法,且成员属性必须是常量,这类被称为接口. 关键字:interface 4 //接口的作用:虽然PHP的类是单继承,但可以通过接口来实现多继承。 5 interface User{ 6 //接口的属性必须是常量 7 const VIP = 'vip用户'; 8 public function getDiscount(); 9 } 10 11 class VipUser implements User{ 12 //vip折扣系数 13 private $discount = 0.6; 14 public function getDiscount() { 15 return $this->discount; 16 } 17 } 18 19 class Goods{ 20 private $price = 200; 21 private $objectUser; 22 //获取User接口VipUser类实现 23 public function getUserData($User){ 24 $this->objectUser = $User; 25 $discount = $this->objectUser->getDiscount(); 26 $usertype = User::VIP; 27 echo $usertype."=>商品价格:".$this->price*$discount; 28 } 29 } 30 31 $display = new Goods(); 32 $display ->getUserData(new VipUser);
运行结果如下图:
11.魔术方法和魔术常量概念小结
1 语法较多就不一一举例,更多信息可以去查php手册用法. 2 3 魔术方法 4 PHP中把以两个下划线__开头的方法称为魔术方法包括: 5 __construct() :类的构造函数 (常用) 6 7 __destruct() :类的析构函数 8 9 __call() :在对象中调用一个不可访问方法时调用 10 11 __callStatic() :用静态方式中调用一个不可访问方法时调用 12 13 __get() :获得一个类的成员变量时调用 14 15 __set() :设置一个类的成员变量时调用 16 17 __isset() :当对不可访问属性调用isset()或empty()时调用 18 19 __unset() :当对不可访问属性调用unset()时被调用 20 21 __sleep() :执行serialize()时,先会调用这个函数 22 23 __wakeup() :执行unserialize()时,先会调用这个函数 24 25 __toString() :类被当成字符串时的回应方法 26 27 __invoke() :调用函数的方式调用一个对象时的回应方法 28 29 __set_state() :调用var_export()导出类时,此静态方法会被调用 30 31 __clone() :当对象复制完成时调用 32 33 34 魔术常量 35 魔术常量常被用于获得当前环境信息或者记录日志等.魔术常量包括: 36 37 __LINE__ :文件中的当前行号 38 39 __FILE__ :文件的完整路径和文件名 40 41 __DIR__ :文件所在的目录 42 43 __FUNCTION__ :函数名称 44 45 __CLASS__ :类的名称 46 47 __TRAIT__ :Trait的名字 48 49 __METHOD__ :类的方法名 50 51 __NAMESPACE__ :当前命名空间的名称
12.命名空间的概念和使用 示例demo:
1 <?php 2 //命名空间:一个脚本的开始需要定义命名空间,必须在脚本的最开始处定义. 关键字:namespace 3 //空间成员包含:1.常量 2.函数 3.类 4 //定义命名空间One 5 namespace One; 6 header("Content-Type: text/html;charset=utf-8"); 7 function getName(){//函数 8 echo '空间:'.__NAMESPACE__; 9 } 10 const AGE=100;//常量 11 class User{//类 12 public $name='admin_a'; 13 } 14 getName(); 15 echo '年龄:'.AGE; 16 var_dump(new User); 17 echo "<hr/>"; 18 19 //定义命名空间Two 20 namespace Two; 21 function getName(){ 22 echo '空间:'.__NAMESPACE__; 23 } 24 const AGE=200; 25 class User{ 26 public $name='admin_b'; 27 } 28 getName(); 29 echo '年龄:'.AGE; 30 var_dump(new \Two\User);//注意:完全限定名称访问
运行结果如下图:
空间成员的访问 示例demo:
1 <?php 2 //三种访问空间成员的方式:1.非限定名称访问 2.限定名称访问 3.完全限定名称访问 "\":代表根空间 3 //(1)非限定名称访问:在访问空间成员的时候,没有指定具体的空间的名字. 4 namespace A\B\C\D; 5 header("Content-Type: text/html;charset=utf-8"); 6 function getName(){ 7 echo '空间:'.__NAMESPACE__; 8 } 9 const AGE=100; 10 class User{ 11 public $name='admin_a'; 12 } 13 echo '空间A\B\C\D 非限定名称访问: '; 14 getName(); 15 echo '年龄:'.AGE; 16 var_dump(new User); 17 echo "<hr/>"; 18 19 //(2)限定名称访问:就是从当前空间开始访问其子空间的成员. 语法:子空间名\空间成员名 20 namespace A\B\C; 21 function getName(){ 22 echo '空间:'.__NAMESPACE__; 23 } 24 const AGE=200; 25 echo '空间A\B\C 非限定名称访问: '; 26 getName(); 27 echo '年龄:'.AGE.'<br>'; 28 29 echo '空间A\B\C 限定名称访问: '; 30 D\getName();//限定名称访问 31 echo '年龄:'.D\AGE;//限定名称访问 32 var_dump(new D\User);//限定名称访问 33 echo "<hr/>"; 34 35 //(3)完全限定名称访问:直接从根空间开始对绝对路径访问. 语法:\空间1\空间2\...\空间成员 36 //注意:完全限定名称访问的最大好处是可以在任意的空间访问其他任意空间的成员. 37 //空间类的引入语法: use 空间名\类名 38 namespace A; 39 function getName(){ 40 echo '空间:'.__NAMESPACE__; 41 } 42 const AGE=300; 43 echo '空间A 非限定名称访问: '; 44 getName(); 45 echo '年龄:'.AGE.'<br>'; 46 47 echo '空间A 完全限定名称访问: '; 48 \A\B\C\D\getName();//完全限定名称访问 49 echo '年龄:'.\A\B\C\D\AGE;//完全限定名称访问 50 use A\B\C\D\User;//空间类的引入 51 var_dump(new User);
运行结果如下图:
空间类的引入 示例demo:
文件One.php
1 <?php 2 namespace One; 3 header("Content-Type: text/html;charset=utf-8"); 4 function getName(){ 5 echo '空间:'.__NAMESPACE__; 6 } 7 class User{ 8 public $name='admin_a'; 9 } 10 class Book{ 11 public $manga='一人之下漫画'; 12 }
文件Two.php
1 <?php 2 //空间类的引入:就是把其他空间的类,引入到当前空间. 语法:use 空间名\类名 3 namespace Two; 4 header("Content-Type: text/html;charset=utf-8"); 5 function getName(){ 6 echo '空间:'.__NAMESPACE__; 7 } 8 class User{ 9 public $name='admin_b'; 10 } 11 //引入文件 12 include 'One.php'; 13 getName();//打印结果:空间:Two 14 echo '<pre>'; 15 16 //将One空间里面Book类引入到当前空间 17 use \One\Book; 18 //将One空间里面User类引入到当前空间(注意使用别名:oneUser) 19 use \One\User as oneUser; 20 $oneBook= new Book(); 21 $oneUser= new oneUser(); 22 //使用当前空间类 23 $twoUser= new User(); 24 var_dump($oneBook,$oneUser,$twoUser);
运行结果如下图: