oop類的繼承與類靜態成員學習

宋霸霸發表於2024-07-09
<?php
namespace controller;
// 1.變數 實現資料的複用 函式是實現程式碼塊的複用
// 2.類是具有相同屬性和方法的物件集合
// 3.物件是複合資料型別
// 4.oop 三大特性:封裝 繼承 多型
// 5.封裝:隱藏物件的屬性或方法(實現細節),目的是為了控制在程式中屬性的讀或者修改的訪問級別,使用者只需要透過外部介面以特定的許可權來使用類成員

class Player{
    // 成員屬性 前一定要有 訪問修飾符 public protected private
    public $name;//抽象屬性 null
    public $height;
    public $team;
    // protected只能被本類和子類訪問
    protected $playNump = 18;
    // 只能被本類訪問
    private $weight;

 // 如何給 protected private屬性賦值
 //  __construct()魔術方法建構函式  構造器 類例項化一次就被自動呼叫一次
//  __get __set __call __callStatic
 public function __construct($name,$height,$team,
 $playNump,$weight)
 {
    // 1.初始化類成員 讓類/例項化的狀態穩定下來
    // 2.給物件屬性進行初始化賦值
    // 3.可以給私有成員,受保護的成員初始化賦值
    $this->name = $name;
    $this->height = $height;
    $this->team = $team;
    $this->playNump = $playNump;
    $this->weight = $weight;
 }
 




    public function jog()
    { 
        // $this 本物件
        return "$this->name is jogging,whose playNum is $this->playNump<br>";
    }

    public function shoot()
    {
        return "$this->name is shooting,weighing
        $this->weight<br>";
    }
 
} 
 
 
//     //  類的例項化 new $j物件引用
//     $jordan = new Player;
//     $james = new Player;
//  //物件成員的訪問 物件引用->屬性名稱/方法名稱()
//     $jordan->name = 'xiaoqi';
//     $james->name = 'youyou';
//     echo $james->name.'<br>';
//     echo $james->jog(); 
//     echo $jordan->name.'<br>';
//     echo $jordan->jog(); 

//     // echo $j->playNump



    // $jordan = new Player('Jordan','205cm','Bulk',23,'80kg');
    // echo $jordan->name.'<br>';
    // echo $jordan->shoot();

?>

  

<?php
// 父類
class Product

{
   public $name;
   public $price;
   protected $discount = 5;

   public function __construct($name,$price)
   {
      $this->name = $name;
      $this->price = $price;
   }

   public function show()
   {
    return "{$this->name}的單價為{$this->price}元";
   }

   final public function display()
   {
    return "現在為您展示的商品是{$this->name},它目前的市場價為{$this->price}元。";
   }


}
// // 示例用法
// $product = new Product("蘋果",5.99);
// echo $product->show();//輸出:蘋果的單價為5.99元

?>

  

<?php
// 類的繼承(擴充套件)透過extends關鍵字實現
//php oop具有單繼承的詬病->帶來程式的高耦合性:如果程式透過深層次繼承繫結到某個具體的類,即使對父類做一些簡單的修改1,也會對子類帶來嚴重的破壞
// 
// trait trait是為類似php的單繼承語言而準備的一種程式碼複用機制 
class Son extends Product
{
    // 屬性擴充套件
    private $num;
    
    // 重寫父類構造器  
    public function __construct($name,$price,$num)
    {
        // parent關鍵字 呼叫父類中的成員方法
       parent::__construct($name,$price);
       $this->num = $num;
    }

    // 重寫父類中的普通方法
    public function show() :string
    {
        return parent::show() .", 數量{$this->num}個,雙十一期間打{$this->discount}折";

    } 

    // 方法擴充套件
    public function total()
    {
      return "商品{$this->name}的總價為".($this->price * $this->num) . '元';

    }
     
    // 子類不能重寫父類中帶有final關鍵字修飾的普通方法 可繼承
    // public function display()
    // {

    // }



}

?>

  

<?php
// 類的靜態成員 static關鍵字 標誌靜態屬性/方法  靜態成員能為本類呼叫 為所有例項共享

// 優點:
// 1.記憶體即使存在多個例項,靜態成員在記憶體中只佔一份, 為所有例項所共享,普通成員以例項的方法會建立多個記憶體
// 2.靜態成員的執行效率比例項化高,不用建立物件就可以直接呼叫

// 缺點:靜態成員不自動進行銷燬,而例項化的則可以銷燬




 class user{
   public static $name = '海綿寶寶';
   protected $_config = [
    'auth_on'=>'true',
    'auth_type'=>1//認證方式 1。實時認證 2.登陸認證
   ];
   public static $nation = 'China';
   private $salary;
   static $count = 0;//記錄已登入使用者的總數
   public function __construct($name,$salary)
   {
    // 靜態成員與類的例項無關 不能用$this訪問,用self::類的引用 訪問靜態成員
    self::$name =  $name;
    $this->salary = $salary;
    self::$count ++;

   }
   public static function getCount(){
     return sprintf('目前該網站的線上人數為%d<br>',
     self::$count);
   }

   //物件被銷燬時自動呼叫
   public function __destruct()
   {
    self::$count--;
   }    


    //靜態上下文中不能訪問普通屬性
    // public static functiom getConfig()
    // {
    //     return sprintf('認證開關:%s<br>,認證型別%d',
    //     $this->_config['auth_on'],
    //     $this->_config['auth_type']);
    // }
     

    public  functioN getConfig()
    {
        return sprintf('認證開關:%s<br>,認證型別%d',$this->_config['auth_on'],$this->_config['auth_type']);
    }
     

 }
 
    //1.靜態成員不能訪問類中的普通屬性(此時還不存在物件)
    // 2.普通成員是物件級別的存在,只能透過物件訪問 預設都提供了$this指標
    // 靜態成員是類級別的存在 隨著類的載入而載入 沒有提供$this指標,優先於物件存在 只能用類引用self::訪問 
 


?>

  

<?php
// 載入類檔案 類的自動載入器
require 'autoload.php';

$son1 = new Son('顯示器',1230,9);
$son2 = new Son('電腦',1230,9);

echo $son1->price.'<br>';
// echo $son1->discount.'<br>';//Fatal error: Uncaught Error: Cannot access protected property Son::$discount
echo $son1->show().'<br>';
echo $son1->display().'<br>';

echo '<bre>';
var_dump($son1);
var_dump($son2);

// object(Son)#4 (3)  #2物件id 每new一次得到不同的示例 就會產生一個新的物件id 
// 單例模式 類只能被例項化一次 只能產生唯一的物件id

$james = new Player('Jordan','205cm','Bulk',23,'80kg');
var_dump($james);

echo '<hr>';
var_dump($james instanceof player);
var_dump($son1 instanceof Son);

?>

  

<?php
// 載入類檔案 類的自動載入器
require 'autoload.php';
$user1 = new User('巧克力',35);
$user2 = new User('牛奶巧克力',38);
$user3 = new User('酒精巧克力',39);
unset($user3);//自動呼叫_destruct
echo User::getCount();
echo User::$name;
// 使用物件引用也可以訪問靜態成員  不推薦
// echo $user1->getCount();
echo User::$nation;
echo $user2->getConfig();
    
 


?>

  

<?php
require 'autoload.php';
// (new Product)->show();
$p1 = new Product('被子',56);
echo $p1->show();

// 類(物件例項化的結果)與物件(類例項化的結果)
// 物件成員之間的內部訪問$this
// oop封裝性 public private protected修飾物件成員
// private僅限本類中使用 protected本類和子類訪問
// 靜態成員 static 屬於類級別的存在 之間的內部訪問 self::
// 類的繼承 父類中的方法和屬性被繼承 ,被重寫 parent:: 呼叫父類成員

?>

  

<?php
 // 類的自動載入 前提 類名稱與類檔名稱保持一致 prs -4規劃

//  spl_autoload_register(function($className)
//  {
//    require $className .'.php';
//  });

 spl_autoload_register(function($className)
 {
  // 先檢視要載入的類
  printf('類名:%s<br>',$className);

  // 將名稱空間與類所在的路徑進行一一對映
  // linux /  window \
  // 解決在Linux系統中名稱空間失效的問題
  $file = __DIR__.'\\controller\\'.str_replace('\\',DIRECTORY_SEPARATOR,$className).'.php';
  // echo $file;
  if(!(is_file($file) && file_exists($file)))
  {
    throw new \Exception('檔名不合法或者不存在');
  }
  require $file;


 });


 // 2.new 類的例項化
// $j= new Player('Jordan','205cm','Bulk',23,'80kg');
// echo $j->shoot();
?>

  

<?php
// 抽象類不能被例項化
abstract  class aDb{
    //抽象方法
    public function show(){

    }
}
// 具體類
class work extends aDb{
    public function show(){
        // #根據自己的需求去實現抽象類
    }
}


?>

  

相關文章