PHP自学之路-----面向对象的编程方法

面向对象的三大特征:
²  封装
抽象:简单理解,我们在定义一个类的时候,实际上就是把一类事物的共有属性和行为提取出来,形成一个物理模型,这种研究问题的方法叫做抽象。
封装:就是把抽象的数据和对数据的操作封装在一起,数据被保护在内部,程序的其他部分只有通过被授权的操作(成员方法),才能对数据进行操作。
那么在PHP中如何实现这种类型的控制呢!请看下面的小程序,不能随便查看人的年龄,工资等隐私。
  访问控制修饰符
PHP提供三种访问控制修饰符皓来控制方法和变量(属性)的访问权限。

Public

表示全局,类内部,外部和子类都可以访问

protected

表示受保护的,只有本类和子类可以访问

Private

表示私有的,只有本类的内部可以使用

下面是总结的使用范围

 

Public

Protected

private

全局

 

 

继承

 

本类

Ø  如果一个方法没有设置访问修饰符,默认是public
Ø  属性必须制定访问修饰符
Ø  成员内方法之间也可以相互调用,但是使用this

 

[php] view plain copy
 
 print?
  1. function test1(){  
  2.  $this->test2();  
  3. }  
  4. private function test2(){  
  5.  echo "我是一名程序猿,转行学习,求大家多多指教";  
  6. }  

 


  如何访问protectedprivae修饰变量?

 

 

[php] view plain copy
 
 print?
  1. //通过下面的方法来访问protected private变量  
  2.          //查看薪水:  
  3.          public function getSalary($name,$passwd){  
  4.              if($name=="jsh" && $passwd=="1234567a"){  
  5.                  echo $this->salary;  
  6.              }else{  
  7.                  echo "输入用户名或密码错误,无法访问";  
  8.              }  
  9.          }  
  10.          //修改年龄  
  11.          public function setAge($age){  
  12.              if($age>0&&$age<120){  
  13.                  $this->age=$age;  
  14.              }else{  
  15.                  echo "设置年龄不符合要求";  
  16.              }  
  17.          }  
  18.          //查看年龄  
  19.          public function getAge($name,$passwd){  
  20.              if($name=="jsh" && $passwd=="1234567a"){  
  21.                  echo $this->age;  
  22.              }else{  
  23.                  echo "输入用户名或密码错误,无法访问";  
  24.              }  
  25.          }  

 

 

 

Ø  从上面可以很容易看出,对访问protected private修饰的变量提供了上述的访问方法,并且增加了验证!

 

PHP设计者提供下面的方法:

[php] view plain copy
 
 print?
  1. <?php  
  2.     class A{  
  3.         private $n1;  
  4.         private $n2;  
  5.         private $n3;  
  6.         private $n4;  
  7.           
  8.         //使用__set方法来设置所有的属性  
  9.         function __set($pro_name,$pro_val){  
  10.             $this->pro_name=$pro_val;  
  11.         }  
  12.         //使用__get方法来获得所有的属性  
  13.         function __get($pro_name){  
  14.             if(isset($pro_name)){  
  15.                 return $this->pro_name;  
  16.             }else{  
  17.                 return null;  
  18.             }  
  19.         }  
  20.   
  21.     }  
  22.     $a1=new A();  
  23.     $a1->n1="hello  ||  ";  
  24.     echo $a1->n1;  
  25.     $a1->n2=222;  
  26.     echo $a1->n2;  
  27.     //结果:hello || 222  
  28.   
  29. ?>  

上面的方法和public 使用时一样的,所以基本来对我们编程来说这种写法没有什么用途的。
代码一:

 

[php] view plain copy
 
 print?
  1. <?php  
  2.      //封装实例:  
  3.   
  4.      class Person{  
  5.          public $name;  
  6.          protected $age;  
  7.          private $salary;  
  8.   
  9.          public function __construct($name,$age,$salary){  
  10.              $this->name=$name;  
  11.              $this->age=$age;  
  12.              $this->salary=$salary;  
  13.          }  
  14.          //成员方法  
  15.          public function showInfo(){  
  16.              //三种访问控制修饰符号在本类中都可以访问  
  17.              echo $this->name."||".$this->age."||".$this->salary;  
  18.          }  
  19.          //通过下面的方法来访问protected private变量  
  20.          //查看薪水:  
  21.          public function getSalary($name,$passwd){  
  22.              if($name=="jsh" && $passwd=="1234567a"){  
  23.                  echo $this->salary;  
  24.              }else{  
  25.                  echo "输入用户名或密码错误,无法访问";  
  26.              }  
  27.          }  
  28.          //修改年龄  
  29.          public function setAge($age){  
  30.              if($age>0&&$age<120){  
  31.                  $this->age=$age;  
  32.              }else{  
  33.                  echo "设置年龄不符合要求";  
  34.              }  
  35.          }  
  36.          //查看年龄  
  37.          public function getAge($name,$passwd){  
  38.              if($name=="jsh" && $passwd=="1234567a"){  
  39.                  echo $this->age;  
  40.              }else{  
  41.                  echo "输入用户名或密码错误,无法访问";  
  42.              }  
  43.          }  
  44.   
  45.          function test1(){  
  46.              $this->test2();  
  47.          }  
  48.          private function test2(){  
  49.              echo "我是一名程序猿,转行学习,求大家多多指教";  
  50.          }  
  51.   
  52.      }  
  53.   
  54.      $p1=new Person("阿辉",29,1000);  
  55.      //访问阿辉的年龄及薪水,有如下错误!private 是不能被外部访问的  
  56.     // echo $p1->age.$p1->salary;  
  57.      //Fatal error: Cannot access private property Person::$age in /var/myphp/class/fengzhuang.php on line 18  
  58.   
  59.   
  60.      //查看薪水  
  61.     echo $p1->name."薪水是:";  
  62.     $p1->getSalary("jsh","1234567a");  
  63.     echo "<br/>";  
  64.   
  65.     //设置年龄,查看年龄  
  66.     $p1->setAge(28);  
  67.     echo $p1->name."年龄是:";  
  68.     $p1->getAge("jsh","1234567a");  
  69.     echo "<br/>";  
  70.   
  71.     $p1->test1();  
  72.     /*********************输出结果********************* 
  73.      *阿辉薪水是:1000 
  74.      *阿辉年龄是:28 
  75.      *我是一名程序猿,转行学习,求大家多多指教 
  76.     **************************************************/  
  77. ?>  

 

 

继承:

[php] view plain copy
 
 print?
  1. <?php  
  2.     //应用场景,开发一套学生管理系统(Pupil Graduate,...)  
  3.     /*************************************************** 
  4.     class Pupil{ 
  5.         public $name; 
  6.         private $age; 
  7.         private $grade; 
  8.      
  9.         //构造方法 
  10.         public function __construct($name,$age,$grade){ 
  11.             $this->name=$name; 
  12.             $this->age=$age; 
  13.             $this->grade=$grade; 
  14.         } 
  15.         //输入学生信息的方法 
  16.         public function showInfo(){ 
  17.            echo $this->name."||".$this->age."||".$this->grade."<br/>"; 
  18.         } 
  19.         //考试方法 
  20.         public function testing(){ 
  21.             echo "小学生考试<br/>"; 
  22.         } 
  23.     } 
  24.     class Graduate{ 
  25.         public $name; 
  26.         private $age; 
  27.         private $grade; 
  28.      
  29.         //构造方法 
  30.         public function __construct($name,$age,$grade){ 
  31.             $this->name=$name; 
  32.             $this->age=$age; 
  33.             $this->grade=$grade; 
  34.         } 
  35.         //输入学生信息的方法 
  36.         public function showInfo(){ 
  37.            echo $this->name."||".$this->age."||".$this->grade."<br/>"; 
  38.         } 
  39.         //考试方法 
  40.         public function testing(){ 
  41.             echo "研究生考试<br/>"; 
  42.         } 
  43.     } 
  44.     //考虑上述有很多共同点,不如年龄,名字,分数等等,这样就造成 
  45.     //代码的复用性不高,代码的可维护性比较低, 
  46.     ********************************************************/  
  47.     //解决方案,引入继承方法。  
  48.     //父类  
  49.     class Stu{  
  50.         public $name;  
  51.         private $age;  
  52.         private $grade;  
  53.       
  54.         //构造方法  
  55.         public function __construct($name,$age,$grade){  
  56.             $this->name=$name;  
  57.             $this->age=$age;  
  58.             $this->grade=$grade;  
  59.         }  
  60.         //输入学生信息的方法  
  61.         public function showInfo(){  
  62.            echo $this->name."||".$this->age."||".$this->grade."<br/>";  
  63.         }  
  64.   
  65.     }  
  66.   
  67.     //子类 小学生  
  68.   
  69.     class Pupil extends Stu{  
  70.         //考试方法  
  71.         public function testing(){  
  72.             echo "小学生考试<br/>";  
  73.         }  
  74.     }  
  75.   
  76.     //子类,研究生  
  77.     class Graduate extends Stu{  
  78.         //考试方法  
  79.         public function testing(){  
  80.             echo "研究生考试<br/>";  
  81.         }  
  82.     }  
  83.   
  84.     $pupil1=new Pupil("阿辉",28,99);  
  85.     $pupil1->showInfo();  
  86.     $pupil1->testing();  
  87.   
  88.     $gra1=new Graduate("佩佩",29,89);  
  89.     $gra1->showInfo();  
  90.     $gra1->testing();  
  91.     /************输出结果****** 
  92.      *阿辉||28||99 
  93.          *小学生考试 
  94.          *佩佩||29||89 
  95.          *研究生考试 
  96.      **************************/  
  97. ?>  

上面的代码,我们简单了解到继承方法的使用,引入继承方法的好处,可以解决代码复用,让我们的变成更加靠近人类的思维,当多个了存在相同的属性和方法是,可以从这些类中抽象出父类,在父类中定义这些相同的类或者方法,所有的子类不需要重新定义这些属性和方法,只需要通过

class 子类名 extends 父类名{

}  这样,子类就会自动永远父类定义的属性和方法。 

细节讨论:

1)父类的那些属性(变量)、方法被子类继承了?

    父类的public修饰符的属性和方法,protected修饰符的属性和方法被子类继承了。父类的private修饰符的属性和方法不能被子类继承。

2) 子类最多只能继承一个父类(直接继承)

3) 子类可以继承去父类的public protected修饰的属性和函数方法  

4)在创建某个子类对象时,默认情况下不会自动调用其父类的构造方法,这点和JAVA不同。

[php] view plain copy
 
 print?
  1. <?php  
  2.     //继承方法测试  
  3.     class A{  
  4.         public $name=90;  
  5.         public function __construct(){  
  6.             echo "A __construct<br/>";  
  7.         }  
  8.     }  
  9.     class B extends A{  
  10.         public function ___construct(){  
  11.             echo "B __construct<br/>";  
  12.         }  
  13.     }  
  14.   
  15.     $b=new B();  
  16. ?>  

上面的PHP会输出什么? 居然输出的是B __construct   

5) 如果子类需要访问父类的方法(构造、成员方法,方法修饰符是public,protected)可以使用父类::方法名 或者parent::方法名)来完成。

[php] view plain copy
 
 print?
  1. <?php  
  2.     //继承方法测试  
  3.     class A{  
  4.         public $name=90;  
  5.         public function __construct(){  
  6.             echo "A __construct<br/>";  
  7.         }  
  8.     }  
  9.     class B extends A{  
  10.         public function __construct(){  
  11.             //A::__construct();  
  12.             parent::__construct();  
  13.         }  
  14.     }  
  15.   
  16.     $b=new B();  
  17. ?>  

重载

基本概念: 函数名一样,可以通过函数的参数个数或者参数类型的不同,达到嗲用同意函数名,但可以区分不同的函数。

1)PHP中 默认是不知道方法重载的

2)PHP可以 通过__call魔术方法,模拟一个方向的效果。

[php] view plain copy
 
 print?
  1. <?php  
  2. class A{  
  3.   
  4.     public function test1($p){  
  5.         echo "输入一个参数<br/>";  
  6.         var_dump($p);  
  7.         echo "<br/>";  
  8.     }  
  9.     public function test2($p){  
  10.         echo "输入二个参数<br/>";  
  11.         var_dump($p);  
  12.     }  
  13.   
  14.     function __call($method,$p){  
  15.         if($method == "test"){  
  16.             if(count($p)==1){  
  17.                 $this->test1($p);  
  18.             }else if (count($p)==2){  
  19.                 $this->test2($p);  
  20.             }  
  21.         }  
  22.     }  
  23.     }  
  24.   
  25.     $a=new A();  
  26.     $a->test(1);  
  27.     $a->test(1,2);  
  28.     /* 
  29.     输入一个参数 
  30. array(1) { [0]=> int(1) }  
  31. 输入二个参数 
  32. array(2) { [0]=> int(1) [1]=> int(2)  
  33. */  
  34.   
  35.   
  36. ?>  

方法覆盖:

 

[php] view plain copy
 
 print?
  1. <?php  
  2.   
  3.     //抽象一个动物类  
  4.     class Animal{  
  5.         public $name;  
  6.         protected $price;  
  7.   
  8.         function cry(){  
  9.             echo "不知道怎么叫";  
  10.         }  
  11.     }  
  12.          
  13.     class Dog extends Animal{  
  14.         //覆盖(逻辑上的覆盖)  
  15.         function cry(){  
  16.             echo "小狗叫。。。。";  
  17.         }  
  18.     }  
  19.     class Pig extends Animal{  
  20.         function cry(){  
  21.             echo "小猪叫。。。。";  
  22.         }  
  23.     }  
  24.   
  25.         //创建一只狗  
  26.         $dog1=new Dog();  
  27.         $dog1->cry();  
  28.   
  29.         $pig1=new Pig();  
  30.         $pig1->cry();  
  31. ?>  
 

 方法重写细节讨论

1、 要实现重写,要求子类的那个方法的名字和参数列表一模一样

2、如果子类要去调用父类的某个方法,前提是父类方法必须要public或者protected。在子类中可以使用 

父类::方法名 或者parent::方法名)来完成。

3、在是先方法覆盖的时候,访问修饰符可以不一样。但是必须满足,子类的范围一定要大于等于父类的范围

²  抽象类

为什么设计抽象类这个技术

1、在实际开饭中,我们可能有这样一种类,是其他类的父类,但是它本身并不需要实例化。主要用于子类来继承。这样可以达到代码复用作用,同时利于项目设计者设计类

2、如果一个类使用abstract修饰了,这个类就是抽象类

如果一个方法被abstract修饰了,这个抽象方法就不能有方法体;

1、  抽象类可以没有抽象方法,同时还有有实现了的方法,可以被子类继承。

2、  一个类中,只有有抽象方法,则该类必须声明为抽象类,否则会报错!

3、  如果一个类继承了某个抽象类,则要求子类必须实现从父类继承的所有抽象类,或者子类也是抽象类。

[php] view plain copy
 
 print?
  1. <?php  
  2.   
  3.     //抽象一个动物类  
  4.    abstract class Animal{  
  5.         public $name;  
  6.         protected $price;  
  7.         //这个方法没有方法体,主要为了给子类来覆盖  
  8.         abstract public function cry();  
  9.     }  
  10.          
  11.     class Dog extends Animal{  
  12.         //覆盖(逻辑上的覆盖)  
  13.         function cry(){  
  14.             echo "小狗叫12。。。。";  
  15.         }  
  16.     }  
  17.     class Pig extends Animal{  
  18.         function cry(){  
  19.             echo "小猪叫1234。。。。";  
  20.         }  
  21.     }  
  22.   
  23.         //创建一只狗  
  24.         $dog1=new Dog();  
  25.         $dog1->cry();  
  26.   
  27.         $pig1=new Pig();  
  28.         $pig1->cry();  
  29. ?>  
posted @ 2017-01-10 11:11  天涯海角路  阅读(152)  评论(0)    收藏  举报