【php】基础学习4

  这部分主要包括php面向对象的程序设计,具体如下:

  1 <html xmlns=http://www.w3.org/1999/xhtml>
  2     <head>
  3     <meta http-equiv=Content-Type content="text/html;charset=utf-8">
  4     </head>
  5     <body>
  6     <?php
  7         /*
  8         * 面向对象程序设计
  9         */
 10         
 11         /*
 12         * 类的定义格式:
 13           class 类名{
 14             var $temp;//属性
 15             function 方法名(参数1,参数2...){
 16                 方法的具体操作
 17             }
 18           }
 19         */
 20         
 21         /*
 22         * 对象
 23         * ① 对象的实例化用new关键字:
 24              $对象名称=new 类型名();
 25           ② 当类被实例化后,可使用操作符"->"来调用该对象中的成员属性和方法
 26              $对象名称->属性;
 27         */
 28     
 29         /*
 30         * 类成员的访问控制
 31         * 通过对类的成员添加关键字public、protected、private来实现对类中成员的访问控制。
 32           如果没有设置这些关键字,php将自动解析为public
 33           ① public:被public定义的类成员可以再任何地方被访问。
 34           ② protected:被protected定义的类成员可以再其所在的类的子类和父类中访问。
 35           ③ private:被private定义的类成员只能在类的内部被访问。
 36         * 当成员变量使用private关键字修饰时,由于只能在类的内部访问,
 37           所以只能通过调用成员方法来实现对私有成员变量的访问。
 38         */
 39         class blog{
 40             private $blogName;
 41             public function setName($blogName){
 42                 $this->blogName=$blogName;
 43             }
 44             public function getName(){
 45                 return $this->blogName;
 46             }
 47         }
 48         $blog=new blog();
 49         $blog->setName('Knife');
 50         echo $blog->getName()."<br/>";
 51     
 52         /*
 53         * 在类里面定义常量用const关键字,而不是通常的define()函数。
 54         * const constant="value";
 55         */
 56         Class Person{
 57             const country = "中国"; // 定义常量
 58             public function myCountry() {
 59                 echo "我是".self::country."人<br />";//内部访问常量
 60             }
 61         }
 62         echo Person::country."<br />";//中国
 63         $p1 = new Person();
 64         $p1 -> myCountry();//我是中国人
 65     
 66         /*
 67         * 范围解析操作符(::)
 68         * 可以用于访问静态成员static,类常量constant,还可以用于覆盖类中的属性和方法。
 69         * ① 当在类定义之外引用到这些项目时,要使用类名。
 70           ② 自PHP 5.3.0起,可以通过变量来引用类,该变量的值不能是关键字(如 self,parent 和 static)。
 71           ③ self,parent 和 static 这三个特殊的关键字是用于在类定义的内部对其属性或方法进行访问的。
 72         */
 73         //1 在类的外部使用 :: 操作符
 74         class MyClass {
 75             const CONST_VALUE = 'A constant value';
 76         }
 77         $classname = 'MyClass';
 78         echo $classname::CONST_VALUE."<br/>"; // 自 PHP 5.3.0 起
 79         echo MyClass::CONST_VALUE."<br/>";
 80         //2  在类定义内部使用 ::
 81         class OtherClass extends MyClass{
 82             public static $my_static = 'static var';
 83             public static function doubleColon() {
 84                 echo parent::CONST_VALUE . "<br/>
";
 85                 echo self::$my_static . "<br/>
";
 86             }
 87         }
 88         $classname = 'OtherClass';
 89         echo $classname::doubleColon(); // 自 PHP 5.3.0 起
 90         OtherClass::doubleColon();
 91         //3 调用父类的方法
 92         class MyClass1{
 93             protected function myFunc() {
 94             echo "MyClass::myFunc()<br/>";
 95             }
 96         }
 97         class OtherClass1 extends MyClass1{
 98             public function myFunc(){
 99                 parent::myFunc();// 但还是可以调用父类中被覆盖的方法
100                 echo "OtherClass::myFunc()<br/>";
101             }
102         }
103         $class = new OtherClass1();
104         $class->myFunc();
105         
106         /*
107         * 构造方法
108         * ① 构造函数可以接受参数,能够在创建对象时将参数赋值给特定的对象字段。
109           ② 构造函数可以调用类方法或其他函数。
110           ③ 类的构造函数可以调用其他构造函数,包括父类的构造函数
111           ④ 也可以调用与实例化对象没有任何关系的类构造函数,只须在__construct前加上类名即可
112              className::__construct();
113         * 构造方法的命名方式,可统一规定为__construct(注意:是两个下划线)
114           如果一个类中没有名称为__construct()的方法时,php5将搜索与类名相同的构造方法
115         */
116         class human{
117             private $name;
118             private $work;
119             function __construct($name,$work){
120                 $this->name=$name;
121                 $this->work=$work;
122             }
123             function introduce(){
124                 echo "我叫".$this->name.",我的工作是一名".$this->work."<br/>";
125             }
126         }
127         $man_1=new human('Jim','ITer');
128         $man_1->introduce();
129         
130         /*
131         * 析构方法
132         * 析构方法和构造方法的作用是相对的,它在某个对象中的所有引用都被删除或对象被显示销毁时执行,
133           析构方法是php5中新添加的内容,之前的版本中没有析构方法
134         * 与构造方法的命名规则一样,一个类的析构方法被规定为__destruct(注意:两个下划线)。
135           析构方法不能带有任何参数。创建格式如下:
136           function __destruct(){
137             具体方法内容;
138           }
139         */
140         class human1{
141             private $name;
142             private $work;
143             function __construct($name,$work){
144                 $this->name=$name;
145                 $this->work=$work;
146             }
147             function introduce(){
148                 echo "我叫".$this->name.",我的工作是一名".$this->work."<br/>";
149             }
150             function __destruct(){
151                 echo "销毁对象".$this->name.'<br/>';
152             }
153         }
154         $man_1=new human1('Knife','ITer');
155         $man_1->introduce();    
156         $man_1=new human1('Fork','Manager');
157         $man_1->introduce();    
158         
159         /*
160         * 静态属性
161         * 如果想在同一类的成员方法中访问静态属性,可以通过在改静态属性的名称前加上操作符"self::"来实现
162         */
163         class sta_num{
164             static $num=0;
165             function add(){
166                 self::$num++;              //直接写$num++报错
167                 echo self::$num++."<br/>"; //直接写$num++报错
168             }
169         }
170         $sta=new sta_num();
171         $sta->add();
172         
173         /*
174         * 静态方法
175         * 由于静态方法不受任何具体对象的限制,所以不需要建立类实例
176         * 它与静态属性的调用方式相同,使用self::来表示调用同一类中的静态方法
177         */
178         class sta_num2{
179             static function show($num){
180                 echo "$num:".$num;
181                 echo "<br/>
";
182                 self::add($num);
183             }
184             static function add($num){
185                 echo "$num+100=".($num+100)."<br/>";
186             }
187         }
188         $num=50;
189         sta_num2::show($num);
190         
191         /*
192         * 对象克隆
193         * clone一个对象
194         * 通过clone后得到的对象与原对象没有任何关系,它把原来对象的所有信息从内存的位置中复制了一份,
195           然后再内存中又开辟一个空间来存储克隆后的对象
196         */
197         $man_1=new human('Jim','ITer');
198         $man_1->introduce();
199         $man_2=clone $man_1;
200         $man_2->introduce();
201         
202         /*
203         * _clone方法
204         * 可以再对象类中定义一个__clone()(注意:两个下划线)方法来调整对象的克隆行为。
205           此方法的代码将在克隆的操作期间来执行。
206         * 除了将所有的现有对象成员复制到目标对象之外,还会执行_clone()方法制定的操作。
207         */
208         class cloneExample{
209             public function __clone(){
210                 echo "cloneExample对象已被克隆<br/>";
211             }
212         }
213         $ce1=new cloneExample();
214         $ce2=$ce1;    //不调用_clone方法,没有任何输出
215         $ce3=clone $ce1;//调用_clone()方法
216         
217         /*
218         * 继承
219         * extends
220         * 关键字parent::用来表示父类和要调用的父类中的成员方法,语法格式如下:
221           parent::父类成员方法(参数1,参数2...)
222         * ① 在父类和子类中都定义了构造函数时,子类的对象实例化后将调用子类的构造函数,
223              而不会调用父类的构造函数。
224         */
225         class human3{
226             var $name;
227             var $height;
228             function __construct(){
229                 echo "这里是父类的构造方法<br/>";
230             }
231             function introduce(){
232                 echo "我叫".$this->name."&nbsp;&nbsp;我的身高是:".$this->height."<br/>";
233             }
234         }
235         class worker3 extends human3{
236             var $company;
237             function __construct(){
238                 echo "这里是子类的构造方法<br/>";
239                 parent::__construct();//如果隐掉这句话,就是注释①的情况
240             }
241         }
242         $man=new worker3();
243         
244         /*
245         * instanceof关键字
246         * php5中instanceof运算符可以检测当前对象是否属于同一类
247         */
248         class tree{
249             function __construct($name){
250                 echo $name;
251             }
252         }
253         class dog{
254             function __construct($name){
255                 echo $name;
256             }
257         }
258         class car{
259             function __construct($name){
260                 echo $name;
261             }
262         }
263         //检测函数,检测对象是否属于某个类
264         class is_class{
265             static function check($obj){
266                 if($obj instanceof tree){
267                     echo "属于tree类<br/>";
268                 }else if($obj instanceof dog){
269                     echo "属于dog类<br/>";
270                 }else{
271                     echo "属于其他类<br/>";
272                 }
273             }
274         }
275         $obj_1=new tree("松树");
276         is_class::check($obj_1);
277         $obj_2=new dog("京巴");
278         is_class::check($obj_2);
279         $obj_3=new car("丰田");
280         is_class::check($obj_3);
281         
282         /*
283         * 多态
284         * 多态的重点是父类和接口,而不是他们所衍生出来的子类。
285         * 实现多态的方法有两种:
286           ① 通过继承实现多态
287           ② 通过接口实现多态
288         */
289         
290         /*
291         * 抽象类与接口
292         * php中存在一些不能被实例化的特殊类,他们就是抽象类与接口
293         * ① 抽象类里至少包含一个由关键字abstract修饰的抽象方法
294              抽象类的定义格式语法如下:
295              abstract class 抽象类名称{
296                 声明数据成员; 
297                 abstract function 成员方法1(参数1,参数2,...)
298                 abstract function 成员方法1(参数1,参数2,...)
299                 ...
300             }
301             当子类要继承方法时,必须包含该类中所有方法,否则在运行时就会出现错误。
302         * ② 接口是一组成员方法声明的集合,它只包含一些空的成员方法和常量,
303              这些空的成员方法将由实现改接口的类去实现。定义一个几口需要使用interface声明
304              定义接口的方式如下:
305              interface 接口名称{
306                 类常量;
307                 function 成员方法1(参数1,参数2,...);
308                 function 成员方法2(参数1,参数2,...);
309                 ...
310              }
311            ③ 抽象类与接口的区别:
312               1.接口没有数据成员;抽象类有数据成员,且可以实现数据封装;
313               2.接口没有构造函数和析构函数;而抽象类可以有
314               3.接口中的方法都是public类型的;而抽象类中的方法则可以使用private、protected或public来修饰
315               4.接口中不能有实现的方法;而抽象类中可以有自定义的方法
316         */
317         
318         /*
319         * 命名空间
320         * ① 定义命名空间可使用关键字namespace
321              namespace MyProject;                //file1.php
322              const F00=1;
323              function foo(){
324                 echo "MyProjectfunction foo()<br/>";
325              }
326         * ② 注意:命名空间的名称不能使用php关键字,而且namespance语句前不能有任何输出语句。
327         * ③ 自定义的命名空间也可以向目录那样出现多级层形式(使用反斜杠""进行间隔)
328              namespance MyProjectSubLevel;    //file2.php
329              const FOO=1;
330              function foo(){
331                 echo "MyProjectfunction foo()<br/>";
332              }
333         * ④ 同一文件中php还支持定义多个不同的命名空间
334              namespance MyProject;
335              const FOO=1;
336              function foo(){
337                 echo "MyProjectfunction foo()<br/>";
338             }
339             namespace AnotherProject;
340             const FOO=1;
341             function foo(){
342                 echo "MyProjectfunction foo()<br/>";
343             }
344         * ⑤ 定义命名空间后,使用变量、方法或类时,前面要加上空间名称
345              include 'file1.php';
346              MyProjectfoo();
347              echo MyProjectFOO;
348         * ⑥ 当定义命名空间后,在一个文件中可以出现相同的方法、变量或类,
349              主要属于不同的命名空间即可。
350              namespace Current;
351              include 'file1.php';
352              const FOO=2;
353              function foo(){
354                 echo "MyProjectfunction foo()<br/>";
355              }
356              foo();   //调用current命名空间中的foo()函数
357              echo FOO;//调用current命名空间中的常量FOO
358              MyProjectfoo();
359              //开头的反斜线表示'根'全局空间,没有该反斜杠会默认为'CurrentMyProjectfoo()'
360              echo MyPorjectFOO;
361         * ⑥ 除了以上方法,还可以使用use关键字导入命名空间
362              include 'file2.php';
363              use MyProjectSubLevel; // 导入命名空间
364              Levelfoo();
365              echo LevelFOO;
366         * ⑦ 还可以为命名空间定义一个别名并使用别名作为调用的前缀
367              include 'file2.php';
368              use MyProjectSubLevel as ns; // 导入命名空间并定义别名为ns
369              nsfoo();
370              echo nsFOO;
371         * ⑧ __NAMESPACE__常量(注意:是两对双下划线)
372              它总是返回当前命名空间的名称
373         * ⑨ namespace关键字
374              可以用于明确引用一个当前命名空间或自命名空间中的项目,它等价于类中的self命名空间
375              namespace MyProject;
376              class foo{
377                 public function fun(){
378                     echo "namespance test!<br/>";
379                 }
380              }
381              $obj=new namespacefoo;
382              echo $obj->fun();
383         */
384         
385         /*
386         * PHP5中的特殊方法
387         */
388         /*
389         * 方法1:__toString()
390         * 类内没有声明__toString()方法时,echo类的对象就会报错。
391         */
392         class product{
393             function __toString(){
394                 return "this is __toString()方法<br/>";
395             }
396         }
397         $obj=new product();
398         echo $obj;
399     
400         /*
401         * 方法2:__autoload()方法会在第一次引用一个类时调用该方法,
402         * 该方法在得到该类的名称后,可以利用这个方法去引入外部的类文件
403         * 下面代码运行的前提是,先建一个demo2.php,示例代码如下:
404            <?php
405                 class demo2{
406                     function __construct(){
407                         echo "this is demo2's construct!";
408                     }
409                 }
410             ?>
411            然后在和demo2.php同级别的目录下新建一个demo1.php,示例代码如下:
412         * 注意:使用__autoload()方法时,自动载入的类名应该和该类所在的文件名保持一致,否在会报错。
413         */
414         function __autoload($class_name){
415             include($class_name.".php");
416         }
417         $obj=new demo2();
418         
419         /*
420         * 方法3:__get()方法和__set()方法
421         * 他们在程序打算获取或设置对象未定义的属性时调用。
422         * __set()需要传入两个参数,一个是指定要获取的属性的名称,一个是该属性要设定的值
423         */
424         class product2{
425             var $company="Knife";
426             var $array_product=array();
427             function __set($key,$value){
428                 echo "$key=$key,$value=$value<br/>";
429                 $this->array_product[$key]=$value;
430             }
431             function __get($key){
432                 echo "$key=$key,value=".$this->array_product[$key]."<br/>";
433             }
434         }
435         $obj=new product2();
436         $obj->company='cannon'; //company存在,所以无输出
437         $obj->product_name='fork'; //product_name不存在,调用__set()方法
438         $obj->company; //company存在,所以无输出
439         $obj->product_name; //product_name不存在,调用_get()方法
440     
441         /*
442         * 方法4:__call
443         * __call方法可以处理类内未定义的方法,让浏览器对用户友好输出
444         * __call方法需要传入两个参数,
445           第一个参数是方法名称,第二个参数是包含传递给该方法的参数的所有值
446         */
447         class product3{
448             function __call($method,$parameters){
449                 echo $method."()方法被调用,该方法所包含信息为:<br/>";
450                 print_r($parameters);
451             }
452         }
453         $obj=new product3();
454         $obj->undefinedMethod(1,2,3);
455     ?>
456     </body>
457 </html>
原文地址:https://www.cnblogs.com/ningvsban/p/3621091.html