PHP OOP小結(jié)

PHP面向?qū)ο?/h3>
面向過程編程:
其基本特征是:
將要完成的任務(wù),分割為若干個步驟:
第1步:做什么喻粹。。厂抽。
第2步:做什么。暗甥。坎怪。
.......
最后岖沛,做完了暑始,任務(wù)完成!



面向?qū)ο缶幊蹋篛OP: Object Oriented  Program(面向?qū)ο缶幊蹋?其基本特征是:
將要完成的任務(wù)婴削,“分派”給不同的“對象”去做;
某對象1:會做什么牙肝。唉俗。。
某對象2:會做什么配椭。虫溜。。
........
程序一旦啟動股缸,則各個對象“各司其職”衡楞,相互配合就完成了任務(wù)。

面向?qū)ο笾械幕靖拍?類和對象
對象:  萬物皆對象敦姻;

類:  任何對象瘾境,都可以人為“規(guī)定”為某種類型(類別);

class  Person{
var  $name ;
var  $age;
var  $edu;
}
我:
姓名:羅XX镰惦, 
年齡40迷守, 
學(xué)歷:大學(xué);
王亮: 
姓名:王亮
年齡:20旺入;
學(xué)歷:大學(xué)兑凿;

class  Teacher{
var  $name ;
var  $age;
var  $edu;
var  $major;        //專業(yè)
}


可見:
?   類是描述一類事物的一個總稱,是具有相同特征特性的該類事物的一個通用名字(稱呼)茵瘾;
?   對象是一個明確的具體的“物體”礼华,是某個類中的一個“實物”(相對來說,類就是一種抽象的泛稱)拗秘。對象離不開類圣絮,或者說,對象一定隸屬于某個類——有類才有對象聘殖,先有類再有對象晨雳。


屬性和方法
屬性:就是原來的“變量”,只是現(xiàn)在它“隸屬于”一個類了奸腺,即寫在一個類中餐禁,就稱為屬性;
方法:就是原來的“函數(shù)”突照,只是現(xiàn)在它“隸屬于”一個類了帮非,即寫在一個類中,就稱為方法;
注意:屬性和方法末盔,已經(jīng)不能“自由使用”了筑舅,而是都要通過這個類或這個類的對象去使用。
使用屬性陨舱,就把它當(dāng)做一個“變量”去使用就好了翠拣,只是需要該形式:對象->屬性名;
使用方法游盲,就把它當(dāng)做一個“函數(shù)”去使用就好了误墓,只是需要該形式:對象->函數(shù)名(實參列表...)


創(chuàng)建對象的幾種形式
class  C1{
var  $p1 = 1;   //定義一個屬性;
}
形式1:
$o1 = new C1(); //通過一個類益缎,去new出一個對象
形式2:
$o2 = new $o1();    //通過一個對象谜慌,去new出一個對象——其實是new出來的是舊對象所述類的一個新對象套腹。
形式3:
$s1 = “C1”; //只是一個字符串變量而已藕溅;
$o3 = new $s1();    //這就是所謂的“可變類”——無非就是類的名字是一個變量而已。

形式4:
$o4 = new  self();  //self表示“當(dāng)前類本身”拍柒,它只能出現(xiàn)在一個類的方法中令哟。


對象的傳值方式:
為什么對于對象恼琼,值傳遞和引用傳遞,這個情況下励饵,他們似乎沒有區(qū)別驳癌??役听?
這要從對象的數(shù)據(jù)的存儲方式來理解:
$o1 = new C1(); //這里創(chuàng)建一個對象o1颓鲜,其存儲結(jié)果


這里,實際上典予,變量$o1中甜滨,存儲的數(shù)據(jù)只是一個“對象編號#1”,這個對象編號瘤袖,才會去指向?qū)ο髷?shù)據(jù)new  C1();  該編號數(shù)據(jù)衣摩,我們不能控制,只是系統(tǒng)內(nèi)部的分配捂敌。

在語法上艾扮,對對象變量進行的屬性進行操作,其實就是通過該編號來指向?qū)ο蠖僮鞯摹?$o1->p1  =  2;  //此時占婉,就是通過對象編號#1去修改了對象(new  C1() )本身的內(nèi)部數(shù)據(jù).
echo  $o2->p1;  //此時相當(dāng)于取得變量$o2所包含的編號#1中所指向的對象(new  C1() )的內(nèi)部數(shù)據(jù)p1



類中成員
類中成員概述
面向?qū)ο缶幊膛葑欤切枰ㄟ^“對象”去做什么事情(以完成某種任務(wù));
而:
對象總是來源于類逆济;
所以:
面向?qū)ο蟮木幊套糜瑁磺卸际菑亩x類開始磺箕;

類中成員分為3大類:
屬性:
方法:
常量:
形式上,大致如下:
class  類名 {
常量定義1抛虫;
常量定義2松靡;
.......
屬性定義1;
屬性定義2建椰;
........
方法定義1雕欺;
方法定義2;
.......
}
說明:
以上各項广凸,沒有順序問題阅茶;習(xí)慣上,其實常量放前面谅海,然后是屬性,然后是方法蹦浦;

詳細(xì)一點扭吁,就又分為:
屬性:
普通屬性;//一般屬性盲镶,實例屬性
靜態(tài)屬性侥袜;
方法:
普通方法;//一般方法溉贿,實例方法
靜態(tài)方法枫吧;
構(gòu)造方法;
析構(gòu)方法宇色;
常量:
類常量
當(dāng)在一個類中定義一個常量時九杂,該常量就稱為“類常量”——本質(zhì)其實還是常量;
定義形式:
class  類名{
const  常量名 = 常量值宣蠕;
//不可以使用define()來定義例隆!
}
使用形式:
常量的使用,是通過類名抢蚀,并使用范圍解析符(::)來取用的镀层;
類名::常量名;


普通屬性(實例屬性):
實例的單詞為:instance
實例皿曲,其實也叫做“對象”唱逢;

普通(實例)屬性,就是一個可以在該類實例化出的對象上使用的屬性屋休!
定義形式:
class  類名{
var  $屬性名  =  初始值坞古;
var  $屬性名;      //這個屬性沒有初始值博投;
//上述的var 還可以使用public來代替绸贡,比如:
public  $屬性名  =  初始值;
public  $屬性名;       //這個屬性沒有初始值听怕;
}
使用形式:
是通過該類的對象捧挺,來使用普通屬性(實例屬性):
$對象->屬性名;   
因為尿瞭,屬性的本質(zhì)就是變量闽烙,則其就可以當(dāng)做一個變量來看待和使用,比如:
$v1 = $對象->屬性名声搁;
echo  $對象->屬性名黑竞;
$v2 = $對象->屬性名 * 3 + 5; //進行計算

靜態(tài)屬性:
靜態(tài)屬性,本質(zhì)上也是“變量”疏旨,但其有一個特點就是:該變量只隸屬于“類”很魂,即:
一個類中的一個靜態(tài)屬性,就只有“一份數(shù)據(jù)”檐涝;
但:
一個類中的一個實例屬性遏匆,就可以有“多份數(shù)據(jù)”——每創(chuàng)建一個對象出來,就會有一份數(shù)據(jù)谁榜;
定義形式:
class  類名{
static   $屬性名  =  初始值幅聘;
static   $屬性名;      //這個屬性沒有初始值窃植;
}
使用形式:
使用類名和范圍解析符(::)來對靜態(tài)屬性進行操作:
類名::$靜態(tài)屬性名帝蒿;     //注意:屬性名帶$符號
對比1:
常量的使用:類名::常量名;
對比2:
實例屬性的使用:對象名->實例屬性名巷怜; //注意:屬性名不帶$符號


1葛超,實例屬性,是每個對象都可以不一樣的數(shù)據(jù)丛版,也是每個對象都“獨自擁有”的數(shù)據(jù)巩掺;
2,靜態(tài)屬性页畦,他不屬于任何一個對象胖替,而只屬于該類本身,也可以理解為為所有對象所共有的數(shù)據(jù)豫缨;

普通方法(實例方法)
一個類中定義的方法独令,可以為這個類的所有對象調(diào)用的方法。也可以理解為好芭,這個類的所有對象燃箭,都各自有自己的一個該方法;

定義形式:
class  類名{
function  方法名(形參1舍败,形參2招狸,.... ){
//方法體敬拓。。裙戏。
}
}
調(diào)用形式:
$對象名->方法名(實參1乘凸,實參2,....)累榜;

靜態(tài)方法
一個類中定義的方法营勤,只隸屬于這個類本身,而不是隸屬于這個類的對象壹罚。

定義形式:
class  類名{
static  function  方法名(形參1葛作,形參2,.... ){
//方法體猖凛。赂蠢。。
}
}
調(diào)用形式:
類名::方法名(實參1辨泳,實參2客年,....);

構(gòu)造方法(__construct):
構(gòu)造方法漠吻,是一個特殊的方法:
1,名字是固定的:_ _construct司恳;
2途乃,該方法通常都不要我們自己調(diào)用,而是在new一個對象的時候會自動調(diào)用扔傅。
3耍共,該方法主要的目的是為了在new一個對象的時候,給該對象設(shè)置一些“初始值”(初始化工作)猎塞;
4试读,構(gòu)造方法的參數(shù)沒有規(guī)定,通常是根據(jù)實際的需要來定義荠耽,目的是為了對象屬性數(shù)據(jù)的初始化钩骇;


析構(gòu)方法(__destruct):
說明:
1,析構(gòu)方法是一個特殊的方法铝量,名字為固定的詞:_ _desctruct
2倘屹,析構(gòu)方法是在一個對象被“銷毀”的時候會自動被調(diào)用的方法——我們無法調(diào)用它;
3慢叨,析構(gòu)方法不能帶參數(shù)(形參)纽匙,但方法中也可以使用$this這個詞,代表“當(dāng)前對象”拍谐;

對象在哪些情況下會被銷毀烛缔?
1馏段,如果程序結(jié)束,所有變量都會被銷毀践瓷,自然院喜,變量所代表的對象也會被銷毀;

對象銷毀的順序当窗,默認(rèn)情況下够坐,跟其創(chuàng)建的順序相反;

2崖面,當(dāng)一個對象沒有任何變量“指向”它的時候元咙,即使程序還沒有結(jié)束,也會被銷毀巫员;

  • 繼承
基本概念
將一個類A中的特性信息庶香,傳遞到另一個類B中,此時就稱為:
B繼承A
A派生出B


class A{

}

class B extends A{
    
}


幾個基本概念
?   繼承:一個類從另一個已有的類獲得其特性简识,稱為繼承赶掖。
?   派生:從一個已有的類產(chǎn)生一個新的類,稱為派生七扰。
?   父類/子類:已有類為父類奢赂,新建類為子類。父類又可以稱為“基類”颈走,上級類膳灶,子類又稱為派生類,下級類立由,
?   單繼承:一個類只能從一個上級類繼承其特性信息轧钓。PHP和大多數(shù)面向?qū)ο蟮恼Z言都是單繼承模式。C++是多繼承锐膜。
?   擴展:在子類中再來定義自己的一些新的特有的特性信息(屬性毕箍,方法和常量)。沒有擴展道盏,繼承也就沒有意義了而柑。
訪問控制修飾符
形式:
class  類名{
訪問控制修飾符  屬性或方法定義;
}

有3個訪問修飾符:
?   public公共的:在所有位置都可訪問(使用)捞奕。
?   protected受保護的:只能再該類內(nèi)部和該類的子類或父類中訪問(使用)牺堰。
?   private私有的:只能在該類內(nèi)部訪問(使用)。

他們的作用是:用來“限制”其所修飾的成員的“可訪問性”颅围;
可訪問性:
就是在代碼中使用這樣兩種語法形式的“有效性”(合法性):
對象->實例屬性或方法伟葫;
類::靜態(tài)屬性或方法;

訪問控制修飾符院促,需要結(jié)合使用該語法形式的所在位置筏养,才能確定是否可訪問斧抱。

有3個訪問位置(范圍):
某個類的內(nèi)部:
某個類的繼承類的內(nèi)部:
某個類的外部:



1,public修飾的成員渐溶,哪里都能訪問辉浦;
2,類的內(nèi)部茎辐,可以訪問任何級別的成員宪郊;
3,public具有最寬泛的可訪問性拖陆;private具有最狹小的可訪問性弛槐;protecte則居中;



parent關(guān)鍵詞
parent表示“父母”的意思依啰,在面向?qū)ο笳Z法中乎串,代表“父類”
——本質(zhì)上就是代表父類這個“類”,而不是父類的“對象”速警;

其使用方式為:
parent::屬性或方法叹誉;  //通常是靜態(tài)屬性或靜態(tài)方法,但有時候可能是實例屬性或?qū)嵗椒ǎ?




構(gòu)造方法和析構(gòu)方法調(diào)用上級同類方法的問題
1闷旧,如果一個類 有 構(gòu)造方法长豁,則實例化這個類的時候,就 不會 調(diào)用父類的構(gòu)造方法(如果有)忙灼;
2蕉斜,如果一個類沒有構(gòu)造方法,則實例化這個類的時候缀棍,就會自動調(diào)用父類的構(gòu)造方法(如果有);



3机错,如果一個類 有 析構(gòu)方法爬范,則銷毀這個類的時候,就 不會 調(diào)用父類的析構(gòu)方法(如果有)弱匪;
4青瀑,如果一個類沒有析構(gòu)方法,則銷毀這個類的時候萧诫,就會自動調(diào)用父類的析構(gòu)方法(如果有)斥难;
5,如果一個類中有構(gòu)造方法或析構(gòu)方法帘饶,則就可以去“手動”調(diào)用父類的同類方法(如果有)哑诊;
手動調(diào)用的語法形式總是這樣:
parent::構(gòu)造方法或析構(gòu)方法()

則,第5種情況及刻,parent在構(gòu)造方法中的一個典型代碼(寫法):
(在子類的構(gòu)造方法中镀裤,常常需要去調(diào)用父類的構(gòu)造方法竞阐,以簡化對象的初始化工作。)



覆蓋(override):
基本概念
覆蓋暑劝,又叫“重寫”:
含義:
將一個類從父類中繼承過來的屬性和方法“重新定義”——此時相當(dāng)于子類不想用父類的該屬性或方法骆莹,而是想要定義。

覆蓋的現(xiàn)實需要:
對于一個父類担猛,或許其屬性的現(xiàn)有數(shù)據(jù)(值)幕垦,子類覺得不合適,而需要有自己的新的描述傅联;
或許其方法先改,子類覺得也不合適,需要自己來重新定義該方法中要做到事纺且。
此時就可以使用覆蓋盏道。



重寫的基本要求:
訪問控制權(quán)限:
子類覆蓋的屬性或方法的訪問控制權(quán)限,不能“低于”父類的被覆蓋的屬性或方法的訪問控制權(quán)限:
具體來說:
父類: public      子類:只能是public
父類: protected   子類:可以說protected和public
父類: private 子類:不能覆蓋载碌!——既父類的私有成員猜嘱,不存在被子類覆蓋的可能。

方法的參數(shù)形式:
子類覆蓋父類的同名方法的時候嫁艇,參數(shù)要求跟父類保持一致朗伶;
特例:
構(gòu)造方法重寫的時候參數(shù)可以不一致

小注意:
雖然父類的私有屬性不能被覆蓋,但子類卻可以定義自己的跟父類同名的屬性步咪;
雖然父類的私有方法不能被覆蓋论皆,但子類也不能定義自己的同名方法;



最終類
最終類猾漫,其實就是一種特殊要求的類:要求該類不允許往下繼承下去点晴。

形式:
final  class  類名{
//類的成員定義。悯周。粒督。跟一般類的定義一樣!
}

最終方法
最終方法禽翼,就是一個不允許下級類去覆蓋的方法M篱稀!

形式:
class  類名{
final  function  方法名(形參列表...){ 闰挡。锐墙。。长酗。溪北。 }
}

設(shè)計模式
什么叫設(shè)計模式?
簡單來說,設(shè)計模式就是解決某個問題的一般性代碼的經(jīng)驗性總結(jié)刻盐。
類比來說:
它類似之前所學(xué)的“算法”:針對某種問題掏膏,使用某種特定的語法邏輯就可以完成該任務(wù)。

工廠模式
所謂工廠模式敦锌,就是這樣一個類(就是所謂的工廠類):
它可以根據(jù)“傳遞”給他的類名馒疹,而去生產(chǎn)出對應(yīng)的類的對象。

class A{}
class B{}

class FactoryClass{
    static function GetObject($className){
        $obj = new $className();
        return $obj;
    }
}

$obj1 = FactoryClass::GetObject("A");
$obj2 = FactoryClass::GetObject("B");
$obj3 = FactoryClass::GetObject("A");



單例模式:
例乙墙,就是實例(Instance)颖变,其實就是對象(object)
單例:就是一個對象;
單例模式:就是設(shè)計這樣一個類听想,這個類只能“創(chuàng)造”出它的一個對象(實例)腥刹;


class Singleton{
    private function __construct(){
    
    }
    
    static private $instance = null;
    static function ShareInstance(){
        if(!isset(self::$instance)){
            $obj = new self();
            self::$instance = $obj;
            return $obj;
        }
        
        return self::$instance;
    }
}

  • 設(shè)計一個MySQL數(shù)據(jù)庫操作類
設(shè)計目標(biāo):
1,該類一實例化汉买,就可以自動連接上mysql數(shù)據(jù)庫衔峰;
2,該類可以單獨去設(shè)定要使用的連接編碼(set  names  XXX)
3蛙粘,該類可以單獨去設(shè)定要使用的數(shù)據(jù)庫(use  XXX)垫卤;
4,可以主動關(guān)閉連接出牧;
上述設(shè)計目錄穴肘,大致上相當(dāng)于如下幾行代碼:
$link  =  mysql_connect(“l(fā)ocalhost”, “root”, “123”);
mysql_query(“set names XXX”);
mysql_query(“use  XXX”);
然后,后面就可以執(zhí)行各種sql語句來:
$r1 = mysql_query(“insert into ....”);
$r2 = mysql_query(“delete from .....”)
$r3 = mysql_query(“select * from ....”);





class MySQLDB{
    publick $link = null;
    function __construct($host,$port,$username,$password,$charset,$dbname){
        $this->link = @mysql_connect("$host:$port","$username","$password") or die("connect failure!");
        
        mysql_query("set names $charset");
        mysql_query("use $dbname");
    }
    
    function setCharset($charset){
        mysql_query("set names $charset")
    }
    
    function selectDB($dbname){
        mysql_query("use $dbname");
    }
    
    function closeDB(){
        mysql_close($this->link)
    }
    
}

//使用

$host = "localhost";
$port = 3306;
$username = "root";
$password = "aaa"
$charset = "utf8";
$dbname = "info";

$db = new MySQLDB($host,$port,$username,$password,$charset,$dbname);

$result = mysql_query("select * from tab_int");

$db->setCharset("gbk");


$db->closeDB();

  • 抽象類舔痕,抽象方法
抽象類:
是一個不能實例化的類评抚;

定義形式:
abstract  class  類名{}

為什么需要抽象類:
它是為了技術(shù)管理而設(shè)計!


抽象方法:
是一個只有方法頭伯复,沒有方法體的方法定義形式慨代;

定義形式:
abstract  function  方法名( 形參1,形參2啸如,.... )鱼响;    //注意,這里必須有分號组底;

為什么需要抽象方法:
它也是為了技術(shù)管理而設(shè)計:要求下級類需要去實現(xiàn)這個方法的“具體做法”;



抽象類和抽象方法的細(xì)節(jié)
1筐骇,一個抽象方法债鸡,必須在抽象類中;
2铛纬,反過來厌均,抽象類中可以沒有抽象方法——雖然不常見;
3告唆,可見:抽象方法是為了規(guī)定下級類中“必須”要具體去完整某個工作(任務(wù))棺弊;
4晶密,下級類中繼承了上級類的抽象方法,則要么去“實現(xiàn)該方法的具體內(nèi)容”模她,要么自己也作為抽象類(即其繼承的抽象方法仍然是抽象的)稻艰;
5,子類實現(xiàn)父類的抽象方法的時候侈净,其形參也應(yīng)該跟父類保持一致尊勿,其訪問權(quán)限也不能更小畜侦;
——其原因其實這是“重寫現(xiàn)象”元扔,自然應(yīng)該遵循重寫的要求;


重載技術(shù)overloading
重載的基本概念
重載在“通常面向?qū)ο笳Z言”中的含義:
是指旋膳,在一個類(對象)中澎语,有多個名字相同但形參不同的方法的現(xiàn)象;
類似這樣:
class   C{
function  f1(){验懊。擅羞。。}
function  f1($p1){鲁森。祟滴。。}
function  f1($p1,  $p2  ){歌溉。垄懂。。}
}
$c1 = new C();
$c1->f1();
$c1->f1(2);
$c1->f1(3,4);


重載在“php語言”中的含義:
是指痛垛,當(dāng)對一個對象或類使用其未定義的屬性或方法的時候草慧,其中的一些“處理機制”;
比如:
class  A{
public  $p1 = 1;
}
$a1 = new A();
echo   $a1->p1;     //1匙头;
echo   $a1->p2;     //出錯漫谷,未定義的屬性!
則:php中的重載技術(shù)蹂析,就是來應(yīng)對上述“出錯”的情況舔示,使代碼不出錯,而且還能“優(yōu)雅處理”电抚;

class A{
    public $p = 1;
}

$a = new A();

echo $a->p; //1
echo $a->p2; //報錯


//處理

class A{
    public $p = 1;
    
    function __get($pro_name){
        echo "調(diào)用了未定義字段"
    }
}

$a = new A();

echo $a->p; //1
echo $a->p2; //不報錯,直接調(diào)用方法->調(diào)用了未定義字段


屬性重載
就是對一個對象的不存在的屬性進行使用的時候惕稻,這個類中預(yù)先設(shè)定好的應(yīng)對辦法(處理機制);

屬性蝙叛,本質(zhì)俺祠,就是變量,其只有4個操作:
取值:
當(dāng)對一個對象的不存在的屬性進行“取值”的時候,就會自動調(diào)用內(nèi)部方法:__GET()
賦值:
當(dāng)對一個對象的不存在的屬性進行“賦值”的時候蜘渣,就會自動調(diào)用內(nèi)部方法:__SET()
判斷(isset):
當(dāng)對一個對象的不存在的屬性進行isset()判斷的時候淌铐,就會自動調(diào)用內(nèi)部方法:__isset()
銷毀(unset):
當(dāng)對一個對象的不存在的屬性進行unset()銷毀的時候,就會自動調(diào)用內(nèi)部方法:__unset()

以上蔫缸,4個方法腿准,被稱為“魔術(shù)方法”;

__GET($屬性名):
在對一個對象的不存儲的屬性進行“取值”的時候捂龄,會自動調(diào)用的方法释涛;
我們其實是可以使用該方法來對這種“意外”情況進行某種特別的處理。
其中倦沧,該方法可以帶一個形參唇撬,表示這個要對之取值的不存在的屬性名(字符串);



__SET($屬性名展融,值):
當(dāng)對一個對象的不存在的屬性進行“賦值”的時候窖认,就會自動調(diào)用這個內(nèi)部的魔術(shù)方法;
它有2個形參告希,分別代表要對不存在的屬性進行賦值的時候的“屬性名”和“屬性值”扑浸;

這個方法,結(jié)合__GET方法燕偶,往往可以使我們定義的類喝噪,就有一種“可方便擴展屬性”的特性加缘。
即:類(或?qū)ο螅┑膶傩栽镒玻梢愿鼮榉奖阕杂桑?


class A{
    protected $prop_list = array();
    
    function __set($p,$v){
        $this->prop_list[$p] = $v;
    }
    
    function __get($p){
        return $this->prop_list[$p];
    }
}



__ISSET($屬性名):
當(dāng)對一個對象的不存在的屬性進行isset()判斷的時候,就會自動調(diào)用內(nèi)部方法:__isset()值漫;
用法:
$v1 = isset($對象 -> 不存在的屬性); //  此時就會調(diào)用這個對象的所屬類中的魔術(shù)方法:__isset()

function __isset($prop){
    $v = isset($this->prop_list[$prop]);
    return $v;
}


__UNSET($屬性名):

當(dāng)對一個對象的不存在的屬性進行unset()銷毀操作的時候伯诬,就會自動調(diào)用內(nèi)部方法:__unset()

function __unset($prop){
    unset($this->prop_list[$prop]);
}



方法重載
當(dāng)對一個對象的不存在的實例方法進行“調(diào)用”的時候晚唇,會自動調(diào)用類中的__call()這個魔術(shù)方法;

當(dāng)對一個類的不存在的靜態(tài)方法進行“調(diào)用”的時候盗似,會自動調(diào)用類中的__callstatic()這個靜態(tài)魔術(shù)方法哩陕;


class A{
    function __call($method,$args){
        echo "__call被調(diào)用了!"
    }
}


利用php的重載技術(shù),實現(xiàn)通常的“方法重載”


  • 接口 interface
什么是接口赫舒?
先看抽象類:
abstract  class  類名  {
屬性1悍及;
屬性2;
.....
非抽象方法1接癌;
非抽象方法2心赶;
......
抽象方法1;
抽象方法2扔涧;
......
}  
設(shè)想,將上述抽象類中“實在的成員”,刪除枯夜,即刪除那些非抽象的成員弯汰。則,自然該抽象類中湖雹,就只有抽象方法咏闪;
abstract  class  類名  {
抽象方法1;
抽象方法2摔吏;
......
}  
由此鸽嫂,可以理解為:這個抽象類,“太抽象了”征讲,幾乎自己什么都沒做据某,就光讓別人做什么。

那么:

接口就是這樣一個“天然不實在”的家伙:
接口诗箍,就是規(guī)定癣籽,里面只能放“抽象方法”和“常量”的一種類似類的語法結(jié)構(gòu);
——可見滤祖,接口就是“比抽象類更抽象的”一種語法結(jié)構(gòu)筷狼。

接口(interface)定義形式:
interface  接口名{
常量1;
常量2匠童;
.....
抽象方法1埂材;
抽象方法2;
.....
}
說明:
1汤求,可見俏险,接口中,只有常量(接口常量)和抽象方法兩種成員首昔;
2寡喝,接口常量的使用形式為: 接口名稱::常量名稱;
3勒奇,接口中的抽象方法预鬓,不要使用abstract修飾,也不需要使用訪問控制修飾符赊颠,因為其天然就是public



為什么需要接口格二?
面向?qū)ο缶幊趟枷胧菍Α艾F(xiàn)實世界”的描述(模擬)!
現(xiàn)實世界往往都都是多繼承的竣蹦;
但:
出于降低類跟類之間關(guān)系的復(fù)雜度的考慮顶猜,就將語言設(shè)計為單繼承的;
但這樣痘括,就無法表達出現(xiàn)實世界的多繼承特性长窄;
則:
接口就是對沒有多繼承的類之間關(guān)系的一個補充滔吠;

因為:接口可以實現(xiàn)“多繼承”——但此時不稱為繼承而已,而是稱為“實現(xiàn)”挠日;
即:
接口1  -->> 類1疮绷;
就稱為:類1實現(xiàn)了接口1;
其本質(zhì)嚣潜,其實就是類1中冬骚,有了接口1中“特征信息”;



使用形式:
形式為:
class  類名  implements  接口名1懂算, 接口名2只冻, ....{    
//類的定義。
}
這里计技,叫做喜德,類實現(xiàn)了接口。



其中酸役,接口跟接口之間住诸,也可以繼承,跟類之間的繼承:
interface  接口1  extends  接口2{
//接口的成員定義涣澡;贱呐。。入桂。奄薇。
}



進一步完善mysqldb工具類:
完善分2個方面:
1,現(xiàn)有已經(jīng)完成的功能抗愁,做優(yōu)化處理馁蒂;
2,添加更多的功能蜘腌,要求繼續(xù)實現(xiàn)如下功能:
2.1:用該類的對象可以執(zhí)行任意的增刪改語句沫屡,并返回布爾值;
2.2:用該類的對象可以執(zhí)行返回一行數(shù)據(jù)的“查詢語句”:結(jié)果是一個一維數(shù)組撮珠,類似這樣:
array( ‘id’=>3,  ‘name’=>’張三’,  ‘a(chǎn)ge’ => 18,  ‘edu’=>’大學(xué)’ );
2.3:用該類的對象可以執(zhí)行返回多行數(shù)據(jù)的“查詢語句”:結(jié)果是一個二維數(shù)組沮脖,類似這樣:
array(
0=>array( ‘id’=>3,  ‘name’=>’張三’,  ‘a(chǎn)ge’ => 18,  ‘edu’=>’大學(xué)’ ),
1=>array( ‘id’=>4,  ‘name’=>’張四’,  ‘a(chǎn)ge’ => 14,  ‘edu’=>’中學(xué)’ )芯急,
2=>array( ‘id’=>7,  ‘name’=>’張七’,  ‘a(chǎn)ge’ => 17,  ‘edu’=>’小學(xué)’ )
)
2.4:用該類的對象可以執(zhí)行返回一個數(shù)據(jù)的“查詢語句”:結(jié)果是一個數(shù)據(jù)值勺届,其sql語句常常類似這樣:  select  name  from  Users  where id = 1;  或: select  count(*) as c  from  表名;

  • 類的自動加載
含義:
當(dāng)某行代碼需要一個類的時候娶耍,php的內(nèi)部機制可以做到“自動加載該類文件”免姿,以滿足該行需要一個類的這種需求。

什么時候需要一個類榕酒?
1胚膊,new一個對象的時候故俐;
2,使用一個類的靜態(tài)方法的時候紊婉;
3购披,定義一個類(B)并以另一個類(A)作為父類的時候;



function __autoload($name){
    require_once './'.$name.'.class.php'
}

$config = array(
    "host"=>"localhost",
    "port"=>3306,
    "username"=>"root",
    "password"=>"aaa",
    "charset"=>"utf8",
    "dbname"=>"db123"
    );
    
    $db = MySQLDB::ShareInstance($config);

    條件和要求
1肩榕, 當(dāng)需要一個類的時候,就會自動調(diào)用某個函數(shù)(默認(rèn)是__autoload)惩妇,并傳入所需要的類的名字
2株汉, 一個類應(yīng)該保存到一個獨立的“類文件中”:即其中只有該類的定義,沒有別的代碼歌殃;
3,習(xí)慣上氓皱,類文件的命名要有一定的“規(guī)則”路召,通常是:類名.class.php
4波材,通常股淡,我們需要將各種類,存儲在一些特定的目錄中廷区,以方便確定其位置唯灵!
5,在該自動加載的函數(shù)中隙轻,“充分”使用傳過來的類名埠帕,以構(gòu)建一個合適的文件路徑并載入;



自定義自動加載函數(shù):
剛才玖绿,__autoload()函數(shù)敛瓷,是系統(tǒng)內(nèi)部的自動加載函數(shù),我們只是定義其函數(shù)體斑匪。

但:

我們可以使用更多函數(shù)(自定義的)呐籽,來實現(xiàn)更靈活的自動加載!

基本模式為:

spl_autoload_register(“函數(shù)1”);       //聲明“函數(shù)1”作為自動加載函數(shù)秤标;
spl_autoload_register(“函數(shù)2”);       //聲明“函數(shù)2”也作為自動加載函數(shù)绝淡;
.........
然后,就去定義這些函數(shù)苍姜,跟定義__autoload()函數(shù)一樣:
function  函數(shù)1( $class_name ){
//.......
}
function  函數(shù)2( $class_name ){
//.......
}
.............

這樣牢酵,系統(tǒng)就會一次調(diào)用這些自動加載函數(shù)去加載所需要的類,直到加載成功衙猪!



spl_autoload_register("autoload1");
spl_autoload_register("autoload2");

function autoload1($class_name){
    $file = './class/'.$class_name.".class.php";
    if(file_exists($file)){
        include_once $file;
    }
}

function autoload2($class_name){
        $file = './lib/'.$class_name.".class.php";
    if(file_exists($file)){
        include_once $file;
    }
}



對象的復(fù)制(克骡梢摇)
$obj1  =  new  A();
$obj1->p1 = 11;
$obj2  = $obj1; //值傳遞
//則布近,現(xiàn)在有幾個對象?——1個對象丝格!
當(dāng)然:
$obj3  =  & $obj1;
結(jié)果撑瞧,還是一個對象!
 
對象的克隆語法显蝌,就是用于將一個對象“制作”雙份的語法预伺,類似之前普通數(shù)據(jù)的“值傳遞”;

語法:
$obj2  =  clone  $obj1;     //這樣曼尊,就有一個跟$obj1完全一樣的新的對象酬诀。



對象的遍歷
對象的遍歷,跟數(shù)組的遍歷骆撇,一樣瞒御!
其實,只能遍歷出對象的“實例屬性數(shù)據(jù)”

foreach( $對象名  as   $key => $value){
//這里就可以處理$key和$value
//但注意:
1,  $key表示的是對象 的 “屬性”神郊,$value是其對應(yīng)值肴裙;
2,  這里能夠遍歷出來的屬性,只能是在該范圍中的“可訪問屬性”(就是要考慮訪問控制權(quán)限)
}



將一個對象的所有屬性都遍歷出來

class A{
    public $p1 = 1;
    protected $p2 = 2;
    private $p3 = 3;
    static $p4 = 4;
    
    function showAllProperties(){
        foreach($this as $key=>$vlue){
            ...
        }
    }
}




PHP內(nèi)置標(biāo)準(zhǔn)類
php語言內(nèi)部涌乳,有“很多現(xiàn)成的類”蜻懦,其中有一個,被稱為“內(nèi)置標(biāo)準(zhǔn)類”夕晓。
這個類“內(nèi)部”可以認(rèn)為什么都沒有阻肩,類似這樣:
class  stdclass{ }


其作用,可以用于存儲一些臨時的簡單的數(shù)據(jù):
$obj1->pp1 = 1;
$obj1->port = ‘3306’;

也可以用于類型轉(zhuǎn)換時用于存儲數(shù)據(jù)运授,如下節(jié)所示

其他數(shù)據(jù)類型轉(zhuǎn)換為對象類型
其他數(shù)據(jù)類型轉(zhuǎn)換為對象類型烤惊,得到的結(jié)果是:內(nèi)置標(biāo)準(zhǔn)類(stdclass)的一個對象!
語法形式為:
$obj1  =  (object) 其他類型數(shù)據(jù)吁朦;
?   數(shù)組轉(zhuǎn)換為對象:數(shù)組的鍵名當(dāng)作屬性名柒室,值為對應(yīng)值;
注意:數(shù)字下標(biāo)的數(shù)據(jù)元素逗宜,轉(zhuǎn)換為對象后的屬性雄右,無法通過對象語法獲取,因此不推薦轉(zhuǎn)換纺讲。

?   null轉(zhuǎn)換為對象:空對象擂仍;
$obj1 = (object)null;
?   其他標(biāo)量數(shù)據(jù)轉(zhuǎn)換為對象:屬性名為固定的“scalar”,值為該變量的值:


類型約束
什么叫類型約束熬甚?
就是要求某個變量只能使用(接收逢渔,存儲)某種指定的數(shù)據(jù)類型;
php屬于“弱類型語言”乡括,通常不支持類型約束肃廓;
相應(yīng)的智厌,強類型語言,類型約束卻是其“基本特征”盲赊。

php中铣鹏,只支持局部的部分類型約束
php中,只支持在函數(shù)(或方法)的形參上哀蘑,設(shè)定類型的約束目標(biāo)诚卸,形式如下:
function 方法名(【要求使用的類型】$p1 ,  【要求使用的類型】$p2,  ..... ){
//..........
}
說明:
1,定義一個函數(shù)(方法)時绘迁, 一個形參惨险,可以使用類型約束,也可以不使用脊髓;
2,如果使用了類型約束栅受,則對應(yīng)的該實參數(shù)據(jù)将硝,就必須是要求的那種類型。
3屏镊,能夠使用的類型約束依疼,其實非常少,只有以下幾種可用:
數(shù)組: array而芥,
對象:使用類的名稱律罢,表示,傳遞過來的實參棍丐,必須是該類的實例误辑;
接口: 使用接口的名稱,表示歌逢,傳遞過來的實參巾钉,必須是實現(xiàn)了該接口的類的實例


單例類的加強:禁止克隆
對于一個類的對象,如果使用“clone運算符”秘案,就會克隆出一個跟當(dāng)前對象完全一樣的新對象出來砰苍,
并且:
此時還會自動調(diào)用該類中的魔術(shù)方法:_ _c l o n e ();只要其中有該方法阱高;

則赚导,要想實現(xiàn)單例類,就應(yīng)該對這個單例類的對象“禁止克隆”赤惊,做法是:
私有化這個魔術(shù)方法:_ _c l o n e ()吼旧;


與類有關(guān)的其他魔術(shù)方法
序列化與反序列化技術(shù)
含義:
序列化:
就是將一個變量所代表的“內(nèi)存”數(shù)據(jù),轉(zhuǎn)換為“字符串”形式并持久保存在硬盤上的一種做法未舟。
反序列化:
就是將序列化之后保存在硬盤上的“字符串?dāng)?shù)據(jù)”黍少,恢復(fù)為其原來的內(nèi)存形式的變量數(shù)據(jù)的一種做法寡夹。

序列化的做法:
$v1 =  123;     //這是一個變量,代表任意的內(nèi)存數(shù)據(jù)
$s1 =  serialize( $v1 );    //將任何類型的變量數(shù)據(jù)厂置,轉(zhuǎn)換為“字符串”
file_put_contents( ‘要保存的目標(biāo)文本文件’, $s1);  //將該字符串菩掏,保存到一個文件里(就是硬盤數(shù)據(jù))

反序列化的做法:
$s1 = file_get_contents( ‘保存序列化數(shù)據(jù)的目標(biāo)文本文件’); //從一個文件里讀出其中的所有字符
$v1 =  unserialize( $s1 );  //將該字符串?dāng)?shù)據(jù),反序列化轉(zhuǎn)換為變量(數(shù)據(jù))


__sleep():用于對象的序列化:
1昵济,對一個對象進行序列化智绸,只能將其屬性數(shù)據(jù)“保存起來”,而方法被忽略(方法不是數(shù)據(jù))
2访忿,對象的序列化的時候瞧栗,會自動調(diào)用該對象所屬類的這個魔術(shù)方法:__sleep()(前提是有該方法)。
且海铆,此時迹恐,該方法必須返回一個數(shù)組,數(shù)組中是“計劃”要進行序列化的屬性名卧斟;


__wakeup:用于對象的反序列化:
1殴边,對一個對象進行反序列化,其實是恢復(fù)其原來保存起來的屬性數(shù)據(jù)珍语,而且锤岸,此時必然需要依賴該對象原本的所屬類;
2板乙,對象在反序列化的時候是偷,會自動調(diào)用該對象所屬類的這個魔術(shù)方法:__wakeup()

__tostring()魔術(shù)方法——比較常用!
含義:
將一個對象“當(dāng)做”一個字符串來使用的時候募逞,會自動調(diào)用該方法蛋铆,并且在該方法中,可以返回一定的字符串放接,以表明該對象轉(zhuǎn)換為字符串之后的結(jié)果戒职。

注意:
如果沒有定義該方法,則對象無法當(dāng)做字符串來使用透乾!

__invoke()魔術(shù)方法:
將對象當(dāng)作函數(shù)來使用的時候洪燥,會自動調(diào)用該方法。通常不推薦這么做乳乌。
class  A{
function  __invoke(){
echo “<br />我是一個對象呀捧韵,你別當(dāng)我是一個函數(shù)來隨便調(diào)用!”;
}
}
$obj1 = new A();
$obj1();    //此時就會調(diào)用類中的方法:__invoke()


其他零碎:
與類有關(guān)的魔術(shù)常量:
以前學(xué)過的魔術(shù)常量:
__FILE__
__DIR__
__LINE__
現(xiàn)在:
__CLASS__:  代表當(dāng)前其所在的類的類名汉操;
__METHOD__:代表其當(dāng)前所在的方法名再来;


與類有關(guān)的系統(tǒng)函數(shù):
class_exists(“類名”), 判斷一個類是否存在(是否定義過)
interface_exists(“接口名”), 判斷一個接口是否存在(是否定義過)
get_class( $obj ),      獲得某個對象$obj 的所屬類
get_parent_class($obj ),        獲得某個對象$obj 的所屬類的父類
get_class_methods(),        獲得一個類的所有方法名,結(jié)果是一個數(shù)組,里面存儲的是這些方法的名稱
get_class_vars(),           獲得一個類的所有屬性名芒篷。結(jié)果是一個數(shù)組搜变,里面存儲的是這些屬性的名稱get_declared_classes()     獲得“整個系統(tǒng)”所定義的所有類名;


與對象有關(guān)的系統(tǒng)函數(shù):

is_object( $obj ): 判斷某個變量是否是一個對象针炉;
get_object_vars( $obj ):獲得一個對象的所有屬性挠他;結(jié)果是一個數(shù)組,里面存儲的是這些屬性的名稱

與類有關(guān)的運算符:
new篡帕,
instanceof:  判斷一個“變量”(對象殖侵,數(shù)據(jù)),是否是某個類的“實例”镰烧;
示意如下:
class  A {}
class  B {}
class  C extends  A{}
$a1 = new A();
$b1 = new B();
$c1 = new C();
$v1 =  $a1  instanceof  A  ;    //結(jié)果是true
$v2 =  $b1  instanceof  A  ;    //結(jié)果是false
$v3 =  $c1  instanceof  C  ;    //結(jié)果是true
$v4 =  $c1  instanceof  A  ;    //結(jié)果是true
——推論:一個類的對象拢军,必然也屬于這個類的上級類的對象;

static關(guān)鍵字的新用法和總結(jié):
static這個關(guān)鍵字怔鳖,也可以像“self”一樣茉唉,代表“當(dāng)前類”,用于訪問一個類的“靜態(tài)屬性或靜態(tài)方法”结执;
但度陆,
static,在應(yīng)用中昌犹,更靈活,因此更常見览芳!
因為static斜姥,它代表的是“調(diào)用”當(dāng)前方法的類,而不是“其代碼所在的類”:
self它就比較死板沧竟,只代表這個單詞本身所在位置的所在類铸敏。


面向?qū)ο缶幊趟枷氲?個特征:
封裝:
無非是一個大的指向思想,目的是為了將一個類設(shè)計得更為健壯悟泵!
其基本做法是:
盡可能地將一個類的成員私有化杈笔,只開放那些必不可少的對外的屬性或方法,能private的就不要protected糕非。能protected就不要public
繼承:
是面向?qū)ο蟮幕舅枷牒突咀龇ā?繼承是代碼重用的一種重要機制蒙具。
多態(tài):
多態(tài),就是“多種形態(tài)”朽肥,其實指的是禁筏,現(xiàn)實世界的“豐富多彩的表現(xiàn)形式”,比如:
人在吃飯衡招;
豬在吃食篱昔;
魚在進食;
小雞啄米;
州刽。空执。。穗椅。
他們都是“吃”這個行為辨绊!
在實際代碼(應(yīng)用)中,多態(tài)常常有兩種表現(xiàn)形式:
1房待, 不同對象邢羔,使用相同的方法,會表現(xiàn)為不同的結(jié)果桑孩!
2拜鹤, 同一個對象,使用相同的方法流椒,也可能會表現(xiàn)為不同的結(jié)果——這其實是“方法重載現(xiàn)象”

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末敏簿,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子宣虾,更是在濱河造成了極大的恐慌惯裕,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,265評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件绣硝,死亡現(xiàn)場離奇詭異蜻势,居然都是意外死亡,警方通過查閱死者的電腦和手機鹉胖,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,078評論 2 385
  • 文/潘曉璐 我一進店門握玛,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人甫菠,你說我怎么就攤上這事挠铲。” “怎么了寂诱?”我有些...
    開封第一講書人閱讀 156,852評論 0 347
  • 文/不壞的土叔 我叫張陵拂苹,是天一觀的道長。 經(jīng)常有香客問我痰洒,道長瓢棒,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,408評論 1 283
  • 正文 為了忘掉前任丘喻,我火速辦了婚禮音羞,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘仓犬。我一直安慰自己嗅绰,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 65,445評論 5 384
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著窘面,像睡著了一般翠语。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上财边,一...
    開封第一講書人閱讀 49,772評論 1 290
  • 那天肌括,我揣著相機與錄音,去河邊找鬼酣难。 笑死谍夭,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的憨募。 我是一名探鬼主播紧索,決...
    沈念sama閱讀 38,921評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼菜谣!你這毒婦竟也來了珠漂?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,688評論 0 266
  • 序言:老撾萬榮一對情侶失蹤尾膊,失蹤者是張志新(化名)和其女友劉穎媳危,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體冈敛,經(jīng)...
    沈念sama閱讀 44,130評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡待笑,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,467評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了抓谴。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片暮蹂。...
    茶點故事閱讀 38,617評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖库倘,靈堂內(nèi)的尸體忽然破棺而出茂缚,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 34,276評論 4 329
  • 正文 年R本政府宣布擎值,位于F島的核電站,受9級特大地震影響狡汉,放射性物質(zhì)發(fā)生泄漏甸赃。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,882評論 3 312
  • 文/蒙蒙 一趟据、第九天 我趴在偏房一處隱蔽的房頂上張望券犁。 院中可真熱鬧,春花似錦汹碱、人聲如沸粘衬。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,740評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽稚新。三九已至勘伺,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間褂删,已是汗流浹背飞醉。 一陣腳步聲響...
    開封第一講書人閱讀 31,967評論 1 265
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留屯阀,地道東北人缅帘。 一個月前我還...
    沈念sama閱讀 46,315評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像难衰,于是被迫代替她去往敵國和親钦无。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,486評論 2 348

推薦閱讀更多精彩內(nèi)容

  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法召衔,類相關(guān)的語法铃诬,內(nèi)部類的語法,繼承相關(guān)的語法苍凛,異常的語法趣席,線程的語...
    子非魚_t_閱讀 31,598評論 18 399
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn)醇蝴,斷路器宣肚,智...
    卡卡羅2017閱讀 134,629評論 18 139
  • Php:腳本語言,網(wǎng)站建設(shè)悠栓,服務(wù)器端運行 PHP定義:一種服務(wù)器端的HTML腳本/編程語言,是一種簡單的霉涨、面向?qū)ο?..
    廖馬兒閱讀 2,120評論 2 38
  • 第十三章 樓 頂 文:青河 雙龍街校區(qū)的勵志樓總共十一層,大一大二在那里上課惭适,樓頂陽臺上有個三層樓高的小閣樓笙瑟,那是...
    QH青河閱讀 363評論 1 5
  • 你可能覺得這是夢往枷。然而在卡夫卡筆下,這是現(xiàn)實凄杯。 一天清晨错洁,Gregor Samsa從噩夢中醒來,發(fā)現(xiàn)自己躺在床上戒突,...
    MissYihan閱讀 3,992評論 2 20