### 面向對象的三大特征:
**2? 封裝
抽象:簡單理解,我們在定義一個類的時候,實際上就是把一類事物的共有屬性和行為提取出來,形成一個物理模型,這種研究問題的方法叫做抽象。
封裝:就是把抽象的數據和對數據的操作封裝在一起,數據被保護在內部,程序的其他部分只有通過被授權的操作(成員方法),才能對數據進行操作。
那么在PHP中如何實現這種類型的控制呢!請看下面的小程序,不能隨便查看人的年齡,工資等隱私。
訪問控制修飾符
PHP提供三種訪問控制修飾符皓來控制方法和變量(屬性)的訪問權限。
<table border="1" cellspacing="0" cellpadding="0"><tbody><tr><td valign="top"><p align="left">Public</p></td><td valign="top"><p align="left">表示全局,類內部,外部和子類都可以訪問</p></td></tr><tr><td valign="top"><p align="left">protected</p></td><td valign="top"><p align="left">表示受保護的,只有本類和子類可以訪問</p></td></tr><tr><td valign="top"><p align="left">Private</p></td><td valign="top"><p align="left">表示私有的,只有本類的內部可以使用</p></td></tr></tbody></table>
下面是總結的使用范圍
<table border="1" cellspacing="0" cellpadding="0"><tbody><tr><td valign="top"><p align="left">?</p></td><td valign="top"><p align="left">Public</p></td><td valign="top"><p align="left">Protected</p></td><td valign="top"><p align="left">private</p></td></tr><tr><td valign="top"><p align="left">全局</p></td><td valign="top"><p align="left"><span style="background:red">※</span></p></td><td valign="top"><p align="left">?</p></td><td valign="top"><p align="left">?</p></td></tr><tr><td valign="top"><p align="left">繼承</p></td><td valign="top"><p align="left"><span style="background:red">※</span></p></td><td valign="top"><p align="left"><span style="background:red">※</span></p></td><td valign="top"><p align="left"><span style="background:red">?</span></p></td></tr><tr><td valign="top"><p align="left">本類</p></td><td valign="top"><p align="left"><span style="background:red">※</span></p></td><td valign="top"><p align="left"><span style="background:red">※</span></p></td><td valign="top"><p align="left"><span style="background:red">※</span></p></td></tr></tbody></table>
?? 如果一個方法沒有設置訪問修飾符,默認是public
?? 屬性必須制定訪問修飾符
?? 成員內方法之間也可以相互調用,但是使用this
~~~
function test1(){
$this->test2();
}
private function test2(){
echo "我是一名程序猿,轉行學習,求大家多多指教";
}
~~~
###如何訪問protectedprivae修飾變量?
~~~
//通過下面的方法來訪問protected private變量
//查看薪水:
public function getSalary($name,$passwd){
if($name=="jsh" && $passwd=="1234567a"){
echo $this->salary;
}else{
echo "輸入用戶名或密碼錯誤,無法訪問";
}
}
//修改年齡
public function setAge($age){
if($age>0&&$age<120){
$this->age=$age;
}else{
echo "設置年齡不符合要求";
}
}
//查看年齡
public function getAge($name,$passwd){
if($name=="jsh" && $passwd=="1234567a"){
echo $this->age;
}else{
echo "輸入用戶名或密碼錯誤,無法訪問";
}
}
~~~
?? 從上面可以很容易看出,對訪問protected private修飾的變量提供了上述的訪問方法,并且增加了驗證!
PHP設計者提供下面的方法:
~~~
<?php
class A{
private $n1;
private $n2;
private $n3;
private $n4;
//使用__set方法來設置所有的屬性
function __set($pro_name,$pro_val){
$this->pro_name=$pro_val;
}
//使用__get方法來獲得所有的屬性
function __get($pro_name){
if(isset($pro_name)){
return $this->pro_name;
}else{
return null;
}
}
}
$a1=new A();
$a1->n1="hello || ";
echo $a1->n1;
$a1->n2=222;
echo $a1->n2;
//結果:hello || 222
?>
~~~
上面的方法和public 使用時一樣的,所以基本來對我們編程來說這種寫法沒有什么用途的。
代碼一:
~~~
<?php
//封裝實例:
class Person{
public $name;
protected $age;
private $salary;
public function __construct($name,$age,$salary){
$this->name=$name;
$this->age=$age;
$this->salary=$salary;
}
//成員方法
public function showInfo(){
//三種訪問控制修飾符號在本類中都可以訪問
echo $this->name."||".$this->age."||".$this->salary;
}
//通過下面的方法來訪問protected private變量
//查看薪水:
public function getSalary($name,$passwd){
if($name=="jsh" && $passwd=="1234567a"){
echo $this->salary;
}else{
echo "輸入用戶名或密碼錯誤,無法訪問";
}
}
//修改年齡
public function setAge($age){
if($age>0&&$age<120){
$this->age=$age;
}else{
echo "設置年齡不符合要求";
}
}
//查看年齡
public function getAge($name,$passwd){
if($name=="jsh" && $passwd=="1234567a"){
echo $this->age;
}else{
echo "輸入用戶名或密碼錯誤,無法訪問";
}
}
function test1(){
$this->test2();
}
private function test2(){
echo "我是一名程序猿,轉行學習,求大家多多指教";
}
}
$p1=new Person("阿輝",29,1000);
//訪問阿輝的年齡及薪水,有如下錯誤!private 是不能被外部訪問的
// echo $p1->age.$p1->salary;
//Fatal error: Cannot access private property Person::$age in /var/myphp/class/fengzhuang.php on line 18
//查看薪水
echo $p1->name."薪水是:";
$p1->getSalary("jsh","1234567a");
echo "<br/>";
//設置年齡,查看年齡
$p1->setAge(28);
echo $p1->name."年齡是:";
$p1->getAge("jsh","1234567a");
echo "<br/>";
$p1->test1();
/***********輸出結果***********
*阿輝薪水是:1000
*阿輝年齡是:28
*我是一名程序猿,轉行學習,求大家多多指教
**************************/
?>
~~~
### 繼承:
~~~
<?php
//應用場景,開發一套學生管理系統(Pupil Graduate,...)
/***************************
class Pupil{
public $name;
private $age;
private $grade;
//構造方法
public function __construct($name,$age,$grade){
$this->name=$name;
$this->age=$age;
$this->grade=$grade;
}
//輸入學生信息的方法
public function showInfo(){
echo $this->name."||".$this->age."||".$this->grade."<br/>";
}
//考試方法
public function testing(){
echo "小學生考試<br/>";
}
}
class Graduate{
public $name;
private $age;
private $grade;
//構造方法
public function __construct($name,$age,$grade){
$this->name=$name;
$this->age=$age;
$this->grade=$grade;
}
//輸入學生信息的方法
public function showInfo(){
echo $this->name."||".$this->age."||".$this->grade."<br/>";
}
//考試方法
public function testing(){
echo "研究生考試<br/>";
}
}
//考慮上述有很多共同點,不如年齡,名字,分數等等,這樣就造成
//代碼的復用性不高,代碼的可維護性比較低,
****************************/
//解決方案,引入繼承方法。
//父類
class Stu{
public $name;
private $age;
private $grade;
//構造方法
public function __construct($name,$age,$grade){
$this->name=$name;
$this->age=$age;
$this->grade=$grade;
}
//輸入學生信息的方法
public function showInfo(){
echo $this->name."||".$this->age."||".$this->grade."<br/>";
}
}
//子類 小學生
class Pupil extends Stu{
//考試方法
public function testing(){
echo "小學生考試<br/>";
}
}
//子類,研究生
class Graduate extends Stu{
//考試方法
public function testing(){
echo "研究生考試<br/>";
}
}
$pupil1=new Pupil("阿輝",28,99);
$pupil1->showInfo();
$pupil1->testing();
$gra1=new Graduate("佩佩",29,89);
$gra1->showInfo();
$gra1->testing();
/******輸出結果****
*阿輝||28||99
*小學生考試
*佩佩||29||89
*研究生考試
**************/
?>
~~~
上面的代碼,我們簡單了解到繼承方法的使用,引入繼承方法的好處,可以解決代碼復用,讓我們的變成更加靠近人類的思維,當多個了存在相同的屬性和方法是,可以從這些類中抽象出父類,在父類中定義這些相同的類或者方法,所有的子類不需要重新定義這些屬性和方法,只需要通過
class 子類名 extends 父類名{
} ?這樣,子類就會自動永遠父類定義的屬性和方法。?
細節討論:
1)父類的那些屬性(變量)、方法被子類繼承了?
父類的public修飾符的屬性和方法,protected修飾符的屬性和方法被子類繼承了。父類的private修飾符的屬性和方法不能被子類繼承。
2) 子類最多只能繼承一個父類(直接繼承)
3) 子類可以繼承去父類的public protected修飾的屬性和函數方法 ?
4)在創建某個子類對象時,默認情況下不會自動調用其父類的構造方法,這點和JAVA不同。
~~~
<?php
//繼承方法測試
class A{
public $name=90;
public function __construct(){
echo "A __construct<br/>";
}
}
class B extends A{
public function ___construct(){
echo "B __construct<br/>";
}
}
$b=new B();
?>
~~~
上面的PHP會輸出什么? 居然輸出的是B?__construct ??
5) 如果子類需要訪問父類的方法(構造、成員方法,方法修飾符是public,protected)可以使用父類::方法名 或者parent::方法名)來完成。
~~~
<?php
//繼承方法測試
class A{
public $name=90;
public function __construct(){
echo "A __construct<br/>";
}
}
class B extends A{
public function __construct(){
//A::__construct();
parent::__construct();
}
}
$b=new B();
?>
~~~
### 重載
基本概念: 函數名一樣,可以通過函數的參數個數或者參數類型的不同,達到嗲用同意函數名,但可以區分不同的函數。
1)PHP中 默認是不知道方法重載的
2)PHP可以 通過__call魔術方法,模擬一個方向的效果。
~~~
<?php
class A{
public function test1($p){
echo "輸入一個參數<br/>";
var_dump($p);
echo "<br/>";
}
public function test2($p){
echo "輸入二個參數<br/>";
var_dump($p);
}
function __call($method,$p){
if($method == "test"){
if(count($p)==1){
$this->test1($p);
}else if (count($p)==2){
$this->test2($p);
}
}
}
}
$a=new A();
$a->test(1);
$a->test(1,2);
/*
輸入一個參數
array(1) { [0]=> int(1) }
輸入二個參數
array(2) { [0]=> int(1) [1]=> int(2)
*/
?>
~~~
### 方法覆蓋:
~~~
<?php
//抽象一個動物類
class Animal{
public $name;
protected $price;
function cry(){
echo "不知道怎么叫";
}
}
class Dog extends Animal{
//覆蓋(邏輯上的覆蓋)
function cry(){
echo "小狗叫。。。。";
}
}
class Pig extends Animal{
function cry(){
echo "小豬叫。。。。";
}
}
//創建一只狗
$dog1=new Dog();
$dog1->cry();
$pig1=new Pig();
$pig1->cry();
?>
~~~
### ?方法重寫細節討論
1、 要實現重寫,要求子類的那個方法的名字和參數列表一模一樣
2、如果子類要去調用父類的某個方法,前提是父類方法必須要public或者protected。在子類中可以使用?
父類::方法名 或者parent::方法名)來完成。
3、在是先方法覆蓋的時候,訪問修飾符可以不一樣。但是必須滿足,子類的范圍一定要大于等于父類的范圍
2? 抽象類
為什么設計抽象類這個技術
1、在實際開飯中,我們可能有這樣一種類,是其他類的父類,但是它本身并不需要實例化。主要用于子類來繼承。這樣可以達到代碼復用作用,同時利于項目設計者設計類
2、如果一個類使用abstract修飾了,這個類就是抽象類
如果一個方法被abstract修飾了,這個抽象方法就不能有方法體;
1、? 抽象類可以沒有抽象方法,同時還有有實現了的方法,可以被子類繼承。
2、? 一個類中,只有有抽象方法,則該類必須聲明為抽象類,否則會報錯!
3、? 如果一個類繼承了某個抽象類,則要求子類必須實現從父類繼承的所有抽象類,或者子類也是抽象類。
~~~
<?php
//抽象一個動物類
abstract class Animal{
public $name;
protected $price;
//這個方法沒有方法體,主要為了給子類來覆蓋
abstract public function cry();
}
class Dog extends Animal{
//覆蓋(邏輯上的覆蓋)
function cry(){
echo "小狗叫12。。。。";
}
}
class Pig extends Animal{
function cry(){
echo "小豬叫1234。。。。";
}
}
//創建一只狗
$dog1=new Dog();
$dog1->cry();
$pig1=new Pig();
$pig1->cry();
?>
~~~
- 前言
- HTML(第一天)
- HTML(第二天)
- DIV+CSS(第一天)
- DIV+CSS(第二天)
- DIV+CSS(第三天)
- DIV+CSS(第四天)
- PHP開發環境配置說明
- PHP基礎數據類型及運算符介紹
- 走進PHP函數
- 走進位運算
- 走進數組及相關數組函數
- 面向對象的編程(類與對象)
- 面向對象的編程(類成員方法用法)
- 構造方法,析構方法
- static,global用法
- 靜態方法
- 面向對象的編程方法
- 接口方法
- 接口VS繼承、final、const
- 錯誤及異常處理機制、錯誤日志
- HTTP協議深度剖析
- 文件下載
- PHP數據庫編程
- 數據庫編程(2)
- 超全局變量
- Zend studio 開發環境入門
- 雇員管理系統(1)
- 雇員管理系統(2)
- 會話技術(cookie session)
- 會話技術 session場景使用介紹!
- PHP.in中session和cookie的配置說明
- PHP文件編程
- 報表及繪圖技術
- 報表及繪圖技術(jpgraph庫使用,Linux安裝及配置說明)
- XML基本語法及DTD介紹
- XML編程(Dom技術)
- XML編程(Xpath技術,simpleXml技術)基礎入門
- 網上支付平臺PHP版本
- javascript基礎入門