熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> PHP編程 >> 正文

PHP中實現面向對象編程的研究

2022-06-13   來源: PHP編程 

  面向對象編程的概念對每一個作者來說都有不同的看法我提醒一下一個面向對象語言應有的東西
  
   數據抽象和信息隱藏
   繼承
   多態性
  
  在PHP中使用類進行封裝的辦法
  
  class Something {
  // In OOP classes are usually named starting with a cap letter
  var $x;
  
  function setX($v) {
  // Methods start in lowercase then use lowercase to seprate
  // words in the method name example getValueOfArea()
  $this>x=$v;
  }
  
  function getX() {
  return $this>x;
  }
  }
  
  ?>
  
  當然你可以用你自己的辦法但有一個標准總是好的
  
  PHP中類的數據成員使用 var 定義數據成員是沒有類型直到被賦值一個數據成員可能是一個 integer數組聯合數組(associative array)或甚至對象(object) 方法在類裡定義成函數在方法裡存取數據成員你必須使用$this>name 這樣的辦法否則對方法來說是一個函數的局部變量
  
  使用 new 來創建一個對象
  
  $obj = new Something;
  
  然後使用成員函數
  
  $obj>setX();
  $see = $obj>getX();
  
  setX 成員函數將 賦給對象(而不是類)obj 中成員變量 然後 getX 返回值
  
  你也可以用對象引用來存取成員變量例如$obj>x=; 然而這不一種好的面向對象編程的方法我堅持你應使用成員函數來設置成員變量的值和通過成員函數來讀取成員變量如果你認為成員變量是不可存取的除了使用成員函數的辦法你將成為一個好的面向對象程序員 但不幸的是PHP本身沒有辦法聲明一個變量是私有的所以允許糟糕的代碼存在
  
  在 PHP 中繼承使用 extend 來聲明
  
  class Another extends Something {
  var $y;
  function setY($v) {
  // Methods start in lowercase then use lowercase to seperate
  // words in the method name example getValueOfArea()
  $this>y=$v;
  }
  
  function getY() {
  return $this>y;
  }
  }
  
  ?>
  
  這樣類 Another 的對象擁有父類的所用成員變量及方法函數再加上自己的成員變量及成員函數
  
  $obj=new Another;
  $obj>setX();
  $obj>setY();
  
  多重繼承不被支持所以你不能讓一個類繼承多個類
  
  在繼承類中你可以重新定義來重定義方法如果我們在 Another 重新定義 getX那麼我們不再能存取 Something 中的成員函數 getX 同樣如果我們在繼承類中聲明一個和父類同名的成員變量那麼繼承類的變量將隱藏父類的同名變量
  
  你可以定義一個類的構造函數 構造函數是和類同名的成員函數在你創建類的對象時被調用
  
  class Something {
  var $x;
  
  function Something($y) {
  $this>x=$y;
  }
  
  function setX($v) {
  $this>x=$v;
  }
  
  function getX() {
  return $this>x;
  }
  }
  
  ?>
  
  所以可以用如下方法創建對象
  
  $obj=new Something();
  
  構造函數自動賦值 給成員變量 x 構造函數和成員函數都是普通的PHP函數所以你可以使用缺省參數
  
  function Something($x=$y=)
  
  然後:
  
  $obj=new Something(); // x= and y=
  $obj=new Something(); // x= and y=
  $obj=new Something(); // x= and y=
  
  缺省參數的定義方法和 C++ 一樣因此你不能傳一個值給 Y 但讓 X 取缺省值實參的傳遞是從左到右當沒有更多的實參時函數將使用缺省參數
  
  只有當繼承類的構造函數被調用後繼承類的對象才被創建父類的構造函數沒有被調用這是PHP不同其他面向對象語言的特點因為構造函數調用鏈是面向對象編程的特點如果你想調用基類的構造函數你不得不在繼承類的構造函數中顯式調用它這樣它能工作是因為在繼承類中父類的方法全部可用
  
  function Another() {
  $this>y=;
  $this>Something(); //explicit call to base class constructor
  }
  
  ?>
  
  在面向對象編程中一種好的機制是使用抽象類抽象類是一種不能實例化而是用來給繼承類定義界面的類設計師經常使用抽象類來強制程序員只能從特定的基類來繼承所以就能確定新類有所需的功能但在PHP中沒有標准的辦法做到這一點不過
  
  如果你在定義基類是需要這個特點可以通過在構造函數中調用 die這樣你就可以確保它不能實例化現在定義抽象類的函數並在每個函數中調用 die如果在繼承類中程序員不想重定義而直接調用基類的函數將會產生一個錯誤
  
  此外你需要確信因為PHP沒有類型有些對象是從基類繼承而來的繼承類創建的因此增加一個方法在基類來辨別類(返回 一些標識)並驗證這一點當你收到一個對象作為參數派上用場 但對於一個惡棍程序沒用辦法因為他可以在繼承類中重定義此函數通常這種辦法只對懶惰的程序員奏效當然最好的辦法是防止程序接觸到基類的代碼只提供界面
  
  重載在PHP中不被支持在面向對象編程中你可以通過定義不同參數種類和多少來重載一個同名成員函數PHP是一種松散的類型語言所以參數類型重載是沒有用的同樣參數個數不同的辦法重載也不能工作
  
  有時候在面向對象編程中重載構造函數很有用所以你能以不同的方式創建不同的對象(通過傳遞不同的參數個數)一個小巧門可以做到這一點
  
  class Myclass {
  function Myclass() {
  $name=Myclassfunc_num_args();
  $this>$name();
  //Note that $this>$name() is usually wrong but here
  //$name is a string with the name of the method to call
  }
  
  function Myclass($x) {
  code;
  }
  function Myclass($x$y) {
  code;
  }
  }
  
  ?>
  
  通過這種辦法可以部分達到重載的目的
  
  $obj=new Myclass(); //Will call Myclass
  $obj=new Myclass(); //Will call Myclass
  
  多態性
  多態性被定義為當在運行時刻一個對象作為參數傳遞時對象能決定調用那個方法的能力例如用一個類定義了方法 draw繼承類重定義 draw 的行為來畫圓或正方形這樣你就有一個參數為 x 的函數在函數裡可以調用$x>draw() 如果支持多態性那麼 draw 方法的調用就取決於對象 x 的類型多態性在PHP中很自然被支持(想一想這種情況在C++編譯器中如果編譯那一個方法被調用?然而你不知道對象的類型是什麼當然現在不是這種情況)
  
  幸好PHP支持多態性
  
  function niceDrawing($x) {
  //Supose this is a method of the class Board
  $x>draw();
  }
  
  $obj=new Circle();
  $obj=new Rectangle();
  
  $board>niceDrawing($obj); //will call the draw method of Circle
  $board>niceDrawing($obj); //will call the draw method of Rectangle
  
  ?>
  
  PHP的面向對象編程
  純對象論者認為PHP不是真正的面向對象語言這是對的PHP是一種混合語言你可以用面向對象或傳統結構編程的方法來使用它對於大型工程然而你可能或需要使用純面向對象方法來定義類並在你的工程中只使用對象和類越來越大的工程通過使用面向對象的方法會獲得益處面向對象工程非常容易維持容易理解並且重用這是軟件工程的基本使用這些概念在網站設計中是未來成功的關鍵
  
  PHP中的高級面向對象技術
  在回顧面向對象的基本概念之後我將介紹一些更高級的技術
  
  串行化
  PHP並不支持持久性對象在面向對象語言中持久性對象是一些經過應用程序多次調用仍然保持其狀態和功能的對象這意味著有一種能保存對象到文件或數據庫中然後重新裝載對象這種機制稱之為串行化PHP 有一個串行化函數可以在對象中調用串行化函數返回一個字符串代表這個對象然後串行化函數保存的是成員數據而不是成員函數
  
  在PHP如果你串行化一個對象到字符串 $s 然後刪除此對象再反串行化對象到 $obj 你仍然可以調用對象的方法函數但我不推薦這種方法這因為(a)這種功能在將來不一定支持(b)這導致一種幻象如果你保存串行化對象到磁盤並退出程序將來重新運行此腳本時你不能反串行化此對象並希望對象的方法函數仍有效因為串行化出來的字符串並沒有表示任何成員函數最後串行化保存對象的成員變量在PHP中非常有用僅僅如此 (你可以串行化聯合數組和數組到磁盤裡)
  
  例子:
  
  $obj=new Classfoo();
  $str=serialize($obj);
  // Save $str to disk
  
  //some months later
  
  //Load str from disk
  $obj=unserialize($str)
  
  ?>
  
  上例中你可以恢復成員變量而沒有成員函數(根據文檔)這導致 $obj>x 是
From:http://tw.wingwit.com/Article/program/PHP/201311/20815.html
    推薦文章
    Copyright © 2005-2022 電腦知識網 Computer Knowledge   All rights reserved.