搜尋
首頁後端開發php教程PHP什麼是物件導向? PHP物件導向小結

本篇文章帶給大家的內容是PHP什麼是物件導向? PHP物件導向小結。有一定的參考價值,有需要的朋友可以參考一下,希望對你們有幫助。

 物件導向特性:

*重複使用(每個模組都可以在專案中重複使用)

*彈性(每個模組都很輕鬆被替換更改的)

*拓展性(在模組上添加新功能是很方便的)

類別和對象的關係(類生成對象)

物以類聚:相同特性的物件歸為一個類,例如nba球員,都有想到的屬性姓名,身高體重,球隊號碼,方法有跑步,跳躍,運球,投籃。將他們當做一個類,而喬丹,詹姆斯這些就是nba球員的實例,也叫對象;

對象內部高內聚(特定的職能,所有相關的內容都封裝在對象內部),對外低耦合(物件的一些可見屬性和一些可見方法)

用class 宣告一個類,在類別裡面只能有 成員屬性 和 成員方法! ! ! !不能有其他,在一個腳本中不能有兩個同名類別,實例化類別可以有多個物件

class Computer{
    public $text = "用关键字new实例化一个类";
    public function output(){
    echo $this->text;
    }
}
$computer = new Computer();

$computer->output();//外部访问方法
$computer->text();//外部访问属性
$computer2 = new Computer();//可以实例化多个

 類別的屬性和方法

存取控制:
public 公有都可以存取
private 私有  只有類別本身內部可以存取
protected  受保護繼承的子類別和類別本身內部可以訪問,外部存取不了,如: $computer->output() ;如果output()方法設了protected,則報錯。

類別裡面的方法:

方法裡面呼叫一個屬性,需要實例化類別才能存取屬性,而$this可以理解為是這個類別的一個實例

class Computer{    
    public $text = "用$this调用我";   
    public function output(){    
         echo $this->text;
    }
}

建構方法(實例化時執行)

 建構方法可以傳遞參數,在實例化時傳入

 透過建構函數的參數傳遞,改變裡面的屬性使得每個實例物件不同

class Computer{
   function __construct($arg){
       echo "我是构造方法,自动执行";    
       echo $arg;
   } 
} 
$conputer = new Computer("我是构方法的参数");

 析構方法:銷毀時執行,不能有參數

程式結束後自動執行,手動釋放(當物件的參考全部銷毀時)會使析構函數提前執行,不用等到程式結束後才呼叫

當你unset 一個引用,只是斷開了變數名稱和變數內容之間的綁定。這並不意味著變數內容被銷毀了 

//对象引用  在PHP 中引用的意思是:不同的名字访问同一个变量内容.
class A
{
    
    function __destruct()
    {
        echo '====我是析构函数====';
    }
}


$a = new A();
//提前执行析构函数的两个方法 unset($a);$a=null;
echo "====正常执行我是先输出的=====";
//两种对象引种的区别
$a = $b;//这时$a和$b是两个独立的引用,unset($aa)只是删除了$a的引用,还有$b的引用,所以不会执行析构函数。改变其中一个为null,不会影响另外一个变量,也不会执行析构函数;
$c = &$a;//两个的变量使用同个引用,c是a的影子,改变其中一个变量为null,两个都为null,会执行析构函数。但是只是unset($a),$c还在使用引用,只要有引用在不会执行析构函数;
//对象的引用用于访问对象的属性和方法,所以$a $b $c都可以访问对象的属性方法; 
//当一个对象的所有引用被删除后,才会触发析构函数

//总结:如果程序大,对象引用尽量使用&,节省内存,清除也方便。设其中一个为Null,其他都为Null;

//变量引用 (默认变量赋值会独立开辟一个内存存放内容)
 //PHP 的引用允许你用两个变量来指向同一个内容
$a="AB"; 
$b =&$a;
echo $a;//这里输出:AB
echo $b;//这里输出:AB 
$b="EF"; 
echo $a;//这里$a的值变为EF 所以输出EF 
echo $b;//这里输出EF  <?php $a = 1;
$b = $a;
echo $a;
//在此之前,b都是和a共用内存空间的。
xdebug_debug_zval(&#39;b&#39;);
$a = 2;//a作出了改变,此时b才会有自己的空间
xdebug_debug_zval(&#39;b&#39;);
?>


//函数引用
<?php function test(&$a){ 
$a=$a+100; 
} 
$b=1; 
echo $b;//输出1 test($b); //这里$b传递给函数的其实是$b的变量内容所处的内存地址,通过在函数里改变$a的值 就可以改变$b的值了 echo "<br>"; echo $b;//输出101
?>//函数的引用返回
<?phpfunction  &test(){     static $b=0;//申明一个静态变量     $b=$b+1;     echo $b;     return $b; }$a=test();//这条语句会输出 $b的值 为1 相当于$a=$b$a=5; $a=test();//这条语句会输出 $b的值 为2 也是$a=$b$a=&test();//这条语句会输出 $b的值 为3 $a=&$b,所以b会随a变了$a=5; $a=test();//这条语句会输出 $b的值 为6?>

賦值和複製的區別

$a=$b(獨立引用)和$a=&$ b(同一引用)這種賦值方式,指向的是同一個對象,同一塊記憶體空間;

$a=clone $b這種賦值方式,則是指向另一個新的對象,另一個塊新的記憶體空間。

<?phpclass  mm {

    public $name = &#39;Peter&#39;;

}
$a = new mm();
$b = $a; 
$c = &$a;
$d = clone $a; 
$b->name = "Anne";
echo $a->name,"\n",$b->name,"\n",$c->name,"\n",$d->name;//输出为:Anne Anne Anne Peter
?>

類別常數 

內部存取self::常數名稱

外部存取不需要實例化:類別名稱::常數名稱

class Computer{    
    const yh = 12;    
    const yh2 = self::yh+1;
} 
var_dump (Computer::yh2);

$this 和self 的區別

一個是物件$this 相當於實例化後,可以說除了靜態和const常數,基本上其他都可以使用this聯絡;

self則是類別本身self可以存取本類別中的靜態屬性和靜態方法,可以存取父類別中的靜態屬性和靜態方法。用self時,可以不用實例化的

類別的繼承

#存在意義:把相同的屬性方法抽出來,讓子類別繼承

extends 後面只能一個逗號,就是說只能繼承一個父類,當單繼承

class dad{     
     function eat(){         
          echo "我是父类的方法,子类可以继承我的方法";
     }
}
class boy extends dad{
} 
$boy = new boy();$boy->eat();

子類別也可以覆寫父類別的方法

子類別沒有建構方法時,就會調用父類別的建構方法,有則呼叫自己的,
用關鍵字parent:: __construct();可以呼叫父類別的建構方法
用final關鍵字加在類別前面就不會被繼承;加到方法面前,此方法就不會被重寫

命名空間(解決命名衝突問題)
利用檔案系統不用目錄的原理
被引入的php文件中加入 namespace 目錄\子目錄;
使用時呼叫:new 目錄\子目錄\類別名稱();如new com\session\computer();
受命名空間影響的有,類別(包括抽象類,traits),接口,函數,常數(const和define都是用來聲明常數的(它們的區別不詳述),但是在命名空間裡,define的作用是全局的,而const則作用於當前空間。)

要注意的是,目前腳本檔案的第一個命名空間前面不能有任何程式碼,下面的寫法都是錯誤的:

//例一
//在脚本前面写了一些逻辑代码
 

<?php $path = "/";

class Comment { }

namespace Article;

?>

 

//例二
//在脚本前面输出了一些字符


<?php namespace Article;

?>为什么要说第一个命名空间呢?因为同一脚本文件中可以创建多个命名空间。<?php //创建一个名为&#39;Article&#39;的命名空间namespace Article;
//此Comment属于Article空间的元素class Comment { }
//创建一个名为&#39;MessageBoard&#39;的命名空间namespace MessageBoard;
//此Comment属于MessageBoard空间的元素class Comment { }?>

由於每次呼叫都要寫上路徑,很麻煩,所以出現use的用法(use引入必須帶類名或函數名)
在呼叫時先用use引入,use 目錄\子目錄\類;還可以起個別名區別as

use venter\session\computer;
use venter\computer as computer2;
new computer();
new computer2();

函数的话记得带上function
use function venter\session\computer;
computer();

常量记得带上const 
use const venter\session\computer;
var_dump(computer);

重點:在命名空間裡面呼叫全域的類,函數,常數的區別,
頁面a定義了命名空間namespace venter;引入b頁面(全域空間)後,此時想呼叫b頁面的類,必須:
New \venter() 加個\代表全域空間下的
但是當呼叫函數和常數時,就不需要加,因為他會自動尋找,向全域尋找。

类自动加载:
当你实例化一个类时,这个类不存在,就会自动执行我们写的 function __autoload($className){},在这个自动函数的内部去执行我们想要操作的代码,参数就是我们实例化的类名,因此可以根据参数去引入php文件。
__autoload将被淘汰,使用新的函数 spl_autoload_register();参数可以传函数名或者匿名函数


spl_autoload_register(function($a){
echo $a;
}
);
new Computer();
或者
function aaa($a){
echo $a;
}

spl_autoload_register('aaa');
new Computer();
或者类的调用方法
class momo
{
function aaa($a){
echo $a;
}
}
spl_autoload_register([new momo],'aaa');
new Computer();

利用命名空间和自动加载实现项目自动引用
1,文件目录就和命名空间名一样,文件名和类名一样 new models\imooc() 就是在models文件下的imooc.php文件,
2,然后利用spl_autoload_register(function($classname){
include str_replace("\\","/",$classname.".php");
});
这里的作用是models\imooc替换掉models/imooc.php 引入
而imooc.php文件中必须命名 namespace models;

static 静态

存在的价值,为了让对象公用一些数据,做到统一性

当属性和方法被定义为 static 时就变成类的属性和方法,不属于对象的,不需要实例化

外部访问  类名::$aa  内部访问 self::$aa 或者static::$aa; 子类访问父类 parent::$aa;

静态方法不能调用非静态属性
因为 $this代表实例化对象,而这里是类,不知道 $this 代表哪个对象


class person{
public static $aa ="a";
public static function eat(){
        echo self::$aa;
        echo static::$aa;
    }
}
class boy extends person{
    public function eat2(){
        echo parent::$aa;
    }
}
echo(boy::eat2());

后期静态绑定:

class A{
public static function who(){
echo "A类的who方法";
}
public static function test(){
self::who(); 
// static::who();
}

}
class B extends A{
public static function who(){
echo "B类的who方法";
}
}
B::test();

如果是self::who(); 输出的是A类的who方法,说明调用的是A自身,static::who();会根据上下文作处理,类B调用就使用B里面的who()

魔术方法
__set($var,$val) 设置私有属性,当外部调用设置一个私有属性时会自动执行这个方法,
__get($var)获取私有属性,原理是外部调用一个私有属性时会自动执行这个方法
例子:


class test{
private $abc = "";
private $ccc = "";
public function __set($var,$val){
$this->$var = $val;
}
public function __get($var){
return $this->$var;
}
}
$test = new test();
$test->abc = 'abc';
var_dump($test->abc);

__isset($var)方法,当外部调用isset($test-abc)访问一个不能访问的属性时,就会自动执行   isset()或者empty() 都会触发__isset()方法

__unset($var),当外部想删除一个私用属性时,会自动执行

以上是属性的重载

__call,__callStatic是属于方法的重载,不是重写

__call($func方法名,$arguments参数)当外部调用一个没有定义的方法时,就会调用

__callStatic($meethod,$arg)当调用一个不存在的静态方法时,会自动执行 注意在function 前也要加入 static 因为是静态方法

__invoke($rag)当实例化一个类后,把这个对象变量当成函数调用时,会自动执行
例如:$test = new test();
$test("go....");

__toString() 当对象被当成string使用时,会执行,比如 echo($test);

__clone方法的一些应用
当一个对象被克隆时,会调用__clone,此时可以在里面执行一些逻辑,比如不想让某些值被克隆,或者初始化一些属性的值

对象拷贝:
浅拷贝:是地址传递(对象是浅拷贝)
深拷贝:复制一份,新开辟一块内存(普通变量是深拷贝)

加clone 使对象成为深拷贝,互不影响;
$a = new A();
$b = clone $a;

__clone()当使用clone时,会自动执行
$a = new A();
$b = clone $a; 在A类中会执行__clone()
例子:

class A{
public $obj = null;
public function __clone(){
$this->obj = clone $this->obj;//开辟了新空间给克隆的对象
}
}
Class B{
public $sex = 0;
}

$a = new A();
$a->obj= new B();
$b = clone $a;
$b->obj->sex = 1;
var_dump($a->obj->sex);

类型约束

class A{
public $obj = null;
public function go(){
echo "googogogogo";
}
}
class B{
public function go(){
echo "bbbbbb";
}
}
Function test(A $a){
$a->go();
}
test(new A());//必须是A的实例

trait 关键字

解决单继承问题 配合use 使用

trait A{
public function a(){
echo "aaaaa";
}
}
trait B{
public function b(){
echo "bbbb";
}
}

Class test{
use A,B;
public function c(){
echo "cccc";
}
}

$test = new test();
$test->a();
$test->b();
$test->c();

接口

可以理解为类的模板 不能直接被实例化

用instanceof 判断某个对象是否实现了某个接口
接口可以继承接口,但是类必须实现接口所有的方法

interface person {
public function eat();
public function sleep();
}
class man implements person{
public function eat(){
echo "chichi吃吃";
}
public function sleep(){
echo "shuishushi";
}
}
$aaa = new man();
$aaa->eat();
//接口继承 两种方法 
interface aa {
public function eat();
}
interface bb {
public function sleep();
}
interface person extends aa,bb{
//person就直接继承了两种方法
}
class man implements person{
public function eat(){
echo "chichi";
}
public function sleep(){
echo "shuishuishui";
}
}
//或者 直接实现两种接口
class man implements aa,bb{
public function eat(){
echo "chichi";
}
public function sleep(){
echo "shuishuishui";
}
}
//接口里面可以利用 const 定义一个常量 
interface person {
const aa = "bbb";
public function eat();
public function sleep();
}
echo person::aa;

抽象类

(比如人和动物都会呼吸方法都一样,此时就不需要每个类去实现不同的呼吸方法,吃东西的方法不同,所以在类中各自实现逻辑)抽象类的子类只需要实现抽象方法;

内部有自己的执行方法

abstract class person {
public function holiday(){
echo '我是抽象类自己实现的方法';
}
//抽象方法,以分号结束,无方法体;抽象类中至少要有一个抽象方法
abstract public function eat();
}
class man extends person{
    public function eat(){
    $this->holiday();//直接调用即可
    }
}
$aaa = new man();
$aaa->eat();

单例模式:

让一个类只会被实例化一次,节省内存空间
先把构造函数和克隆函数变成私用属性

class test{
private static $_instance = null;//依靠属性存储实例对象判断是否已经实例过
private function __construct(){
// 私有后将不会被外部实例
}
private function __clone(){
// 私有后将不会被外部克隆
}
public static function getInstance(){
if(!(self::$_instance instanceof self)){
// instanceof判断是否是当前的实例,不是的话就实例化赋值,否则就返回
self::$_instance = new self();
}
return self::$_instance;
}
}
$test1 = test::getInstance();
$test2 = test::getInstance();
$test3 = test::getInstance();
var_dump($test1);
var_dump($test2);
var_dump($test3);
// 输出结果object(test)#1 (0) { } object(test)#1 (0) { } object(test)#1 (0) { }

工厂模式:

就是在多处实例化一个类,当这个类名需要改变时,就会导致大量地方需要更改,使用工厂模式避免这种情况发生

class A{
public function a(){
echo 'aaa';
}
public function c(){
echo 'ccc';
}
public function b(){
echo 'bbb';
}
}
class cashe{
public static function factory(){
return new A();//当业务逻辑变化时,只需要改此处
}
}
$cashe = cashe::factory();
$cashe->a();

面向对象功能汇总

有继承功能,必须有访问的控制,(私有公有属性),static静态关键字来保存一些公用的数据,重写对父类的方法属性重定义,final关键字不允许重写或者继承,访问静态属性的几个方法,接口中的方法是不用具体实现的,在类中才实现,而且必须实现接口中所有的方法,因为有了不同的实现方法逻辑,不同的对象产生不同的表现,这叫多态,存在与接口与类之间的叫抽象类,可以有一部分可以实现,一部分不用实现

/*--------------多态的一个应用实例 模拟USB设备的使用------------------*/

//一个USB的接口

interface USB{

function mount();//装载USB的方法

function work();//USB工作的方法

function unmount();//卸载USB的方法

}

//定义一个USB设备 U盘

class Upan implements USB{//实现USB接口

function mount(){

echo " U盘 装载成功<br>";

}

function work(){

echo "U盘 开始工作<br>";

}

function unmount(){

echo "U盘 卸载成功<br>";

}

}

//定义一个USB设备 USB鼠标

class Umouse implements USB{//实现USB接口

function mount(){

echo " USB键盘 装载成功<br>";

}

function work(){

echo "USB键盘 开始工作<br>";

}

function unmount(){

echo "USB键盘 卸载成功<br>";

}

}

//定义一个电脑类

class Computer{

//使用USB设备的方法

function useUSB ($usb){//$usb参数表示 使用哪种USB设备

$usb->mount();//调用设备的 装载方法

$usb->work();//调用设备的 工作方法

$usb->unmount();//调用设备的卸载方法

}

}

//定义一个电脑的使用者的类

class PcUser{

//

安装

USB的方法

function install(){

//首先拿来一台电脑

$pc=new Computer;

//拿来一些USB设备

$up=new Upan;//拿来一个U盘

$um=new Umouse;//拿来一个USB鼠标

//把USB设备插入电脑, 使用电脑中使用USB设备的方法 来调用 要插入的设备

$pc->useUSB($up);//插入U盘

$pc->useUSB($um);//插入USB鼠标

}

}

//实例化一个电脑用户

$user=new PcUser;

$user->install();//安装设备

/*-------------输出内容--------------

U盘 装载成功

U盘 开始工作

U盘 卸载成功

USB键盘 装载成功

USB键盘 开始工作

USB键盘 卸载成功

-----------------------------------*/

?>

以上就是本篇的全部内容,更多相关教程请访问php编程从入门到精通全套视频教程php实战视频教程bootstrap视频教程


以上是PHP什麼是物件導向? PHP物件導向小結的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述
本文轉載於:博客园。如有侵權,請聯絡admin@php.cn刪除
php怎么把负数转为正整数php怎么把负数转为正整数Apr 19, 2022 pm 08:59 PM

php把负数转为正整数的方法:1、使用abs()函数将负数转为正数,使用intval()函数对正数取整,转为正整数,语法“intval(abs($number))”;2、利用“~”位运算符将负数取反加一,语法“~$number + 1”。

php怎么实现几秒后执行一个函数php怎么实现几秒后执行一个函数Apr 24, 2022 pm 01:12 PM

实现方法:1、使用“sleep(延迟秒数)”语句,可延迟执行函数若干秒;2、使用“time_nanosleep(延迟秒数,延迟纳秒数)”语句,可延迟执行函数若干秒和纳秒;3、使用“time_sleep_until(time()+7)”语句。

php字符串有没有下标php字符串有没有下标Apr 24, 2022 am 11:49 AM

php字符串有下标。在PHP中,下标不仅可以应用于数组和对象,还可应用于字符串,利用字符串的下标和中括号“[]”可以访问指定索引位置的字符,并对该字符进行读写,语法“字符串名[下标值]”;字符串的下标值(索引值)只能是整数类型,起始值为0。

php怎么除以100保留两位小数php怎么除以100保留两位小数Apr 22, 2022 pm 06:23 PM

php除以100保留两位小数的方法:1、利用“/”运算符进行除法运算,语法“数值 / 100”;2、使用“number_format(除法结果, 2)”或“sprintf("%.2f",除法结果)”语句进行四舍五入的处理值,并保留两位小数。

php怎么读取字符串后几个字符php怎么读取字符串后几个字符Apr 22, 2022 pm 08:31 PM

在php中,可以使用substr()函数来读取字符串后几个字符,只需要将该函数的第二个参数设置为负值,第三个参数省略即可;语法为“substr(字符串,-n)”,表示读取从字符串结尾处向前数第n个字符开始,直到字符串结尾的全部字符。

php怎么根据年月日判断是一年的第几天php怎么根据年月日判断是一年的第几天Apr 22, 2022 pm 05:02 PM

判断方法:1、使用“strtotime("年-月-日")”语句将给定的年月日转换为时间戳格式;2、用“date("z",时间戳)+1”语句计算指定时间戳是一年的第几天。date()返回的天数是从0开始计算的,因此真实天数需要在此基础上加1。

php怎么查找字符串是第几位php怎么查找字符串是第几位Apr 22, 2022 pm 06:48 PM

查找方法:1、用strpos(),语法“strpos("字符串值","查找子串")+1”;2、用stripos(),语法“strpos("字符串值","查找子串")+1”。因为字符串是从0开始计数的,因此两个函数获取的位置需要进行加1处理。

php怎么替换nbsp空格符php怎么替换nbsp空格符Apr 24, 2022 pm 02:55 PM

方法:1、用“str_replace("&nbsp;","其他字符",$str)”语句,可将nbsp符替换为其他字符;2、用“preg_replace("/(\s|\&nbsp\;||\xc2\xa0)/","其他字符",$str)”语句。

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
3 週前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳圖形設置
3 週前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您聽不到任何人,如何修復音頻
3 週前By尊渡假赌尊渡假赌尊渡假赌
WWE 2K25:如何解鎖Myrise中的所有內容
3 週前By尊渡假赌尊渡假赌尊渡假赌

熱工具

SublimeText3 英文版

SublimeText3 英文版

推薦:為Win版本,支援程式碼提示!

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

WebStorm Mac版

WebStorm Mac版

好用的JavaScript開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

SublimeText3 Linux新版

SublimeText3 Linux新版

SublimeText3 Linux最新版