php 面向对象 学习笔记

类,成员方法,类的实例化,成员变量,类常量

class SportObject{ //定义类
    function beatBasketball($name,$height,$age){  //声明成员方法
        echo "姓名:".$name;
        echo "身高:".$height;
        echo "年龄:".$age;

        if($height>180 and $age>15){
            return $name."符合";
        }else{
            return $name."不符合";
        }
    }

    // 定义变量的关键字:public private protected static final
    public $name; //定义成员变量
    public $height;
    public $age;
    
    public function bootFootBall($name,$height,$age){ //声明成员方法
        $this->name=$name;
        $this->height=$height;
        $this->age=$age;

        if($this->height<185 and $this->age>20){ 
            return $this->name."符合<br>"; //方法实现的功能
        }else{
            return $this->name."不符合<br>";
        }
    }

    const BOOK_TYPE='计算机图书'; //声明常量
    public $object_name; //声明变量

    function setObjectName($name){ //声明方法
        $this->object_name=$name; //设置成员变量值

    }

    function getObjectName(){ //声明方法
        return $this->object_name;
    }
}
$sport=new SportObject(); //类的实例化
echo $sport->beatBasketball('空空','40','20'); //调用方法
echo $sport->bootFootball('空空','180','30'); //执行类中的方法
//输出计算机图书->php类

//定义常量的关键字:const
$c_book=new SportObject(); //实例化
$c_book->setObjectName('php类'); //调用方法
echo SportObject::BOOK_TYPE."->"; //输出常量
echo $c_book->getObjectName();

1.类要在一个<?php...?>中,不可被分割
2.成员方法即类中函数,实现类的行为
3.类的实例化:对象名=new 类名
4.调用方法:对象名->成员方法
5.$this->xxx作用是调用本类中的成员变量或成员方法
6.类中的变量:成员变量
7.无论是使用$this->xxx还是对象名->xxx的格式,后面的变量都是没有$符号的
8.输出常量不需要实例化对象,直接由类名::常量名调用即可(域操作符


构造方法和析构方法

class SportObject2{
    public $name;
    public $height;
    public $age;

    public function __construct($name,$height,$age){ //定义构造方法
        $this->name=$name;
        $this->height=$height;
        $this->age=$age;
    }

    public function bootFoot(){
        if($this->height<185 and $this->age>20){ 
            return $this->name."都符合<br>"; //方法实现的功能
        }else{
            return $this->name."都不符合<br>";
        }
    }

    function showMe(){
        echo "这句话不会显示"; //用于验证下面多态的覆盖
    }

   function __destruct(){
        echo "<p>对象被销毁,调用析构函数</p>"; 
    } 
    //当对象结束其生命周期,如对象所在的函数已调用完毕时,系统自动执行析构函数。

}

$sport=new SportObject2('xixi','185','29'); //实例化类并传递参数
// 与上面不同的是:实例化时只需一条语句即可赋值执行
echo $sport->bootFoot(); //执行类中的方法

1.构造方法是生成对象时自动执行的方法,作用是初始化对象
2.析构函数往往用来做“清理善后” 的工作(例如在建立对象时用new开辟了一片内存空间,delete会自动调用析构函数后释放内存)
3.如果类中有构造方法,则在实例化时只需一条语句即可对成员变量进行赋值$sport=new SportObject2('xixi','185','29');


继承,多态

//子类 beatBall
class BeatBall extends SportObject2{ //定义子类,继承父类
    public $height;
    function __construct($name,$height){ //定义构造方法
        $this->height=$height;
        $this->name=$name;
    }

    function showMe(){ //再次定义方法showMe()->验证多态的覆盖
        if($this->height>170){
            return $this->name."体重符合<br>";
        }else{
            return $this->name."体重不符合<br>";
        }
    }
}

//子类 WeightLift
class WeightLift extends SportObject2{
    function showMe(){ //再次定义方法showMe()->验证多态的覆盖
        if($this->age>15){
            return $this->name."年龄符合<br>";
        }else{
            return $this->name."年龄不符合<br>";
        }
    }
}

$beatball=new BeatBall('heihei','190');
$weightlift=new WeightLift('xixi','190','25');
echo $beatball->showMe()."<br>";
//输出:heihei体重符合 调用的是第二个showMe()方法
echo $weightlift->showMe()."<br>";
//输出:xixi年龄符合 调用的是第三个showMe()方法

class C{ 
    function __call($name,$num){ //调用不存在的方法时会执行的方法
        // $name 为调用的不存在的函数名
        // $num 为调用不存在函数时传递的参数,类型为数组
        // count($array) 返回数组的总个数
      
        
        echo "方法名:".$name; //输出方法名
        echo "参数存在个数:".count($num); //输出参数个数
        if(count($num)==1){  //根据参数不同调用不同的方法
            echo $this->list1($num[0]);
        }
        if(count($num)==2){
            echo $this->list2($num[0],$num[1]);
        }

    }

    public function list1($a){
        return "list1:$a";
    }
    public function list2($a,$b){
        return "list2:a->$a,b->$b";
    }
    
}

$a=new C;
echo $a->firstshow('kongkong','18'); //两个参数
//输出:方法名:firstshow 参数存在个数:2
echo $a->secondshow('kongkong'); //一个参数
//输出:方法名:secondshow 参数存在个数:1

1.继承通过关键字 extends 来声明 格式 class subClass extends superClass{...}
2.如果继承的父类中无构造函数,而子类调用方法时直接实例化传递参数是传递不了的
3.多态两种形式:覆盖和重载
4.覆盖:在子类中重写父类方法,调用时会先调用子类的(如上文中关于showMe()的调用
5.重载:一个标识符被用作多个函数名,且能通过函数的参数个数或参数类型将这些同名的函数区分开来,做到调用时不发生混淆


数据隐藏

限定类成员(包括变量和方法)访问权限的关键字:public private , protected , static , final

private

class book{
    private $name='computer'; //声明私有变量
    public function setname($name){ //设置私有变量方法
        $this->name=$name;
    }
    public function getname(){ //读取私有变量
        return $this->name;
    }
}

class lbook extends book{

}

$lbook=new lbook();

//只能用调用成员方法的方式来访问私有变量
echo 'true pratice:';
$lbook->setname('jiuzhe');
echo $lbook->getname();
//输出:true pratice:jiuzhe
echo '<br>false result:'; 
echo book::$name; //错误操作,会报错

private修饰的变量和方法只能在所属类内部被调用,不可以在类外部被访问,子类也不行

protected

//被protected修饰可以在本类和子类中被调用
class book2{
    protected $name='computer';
}
class lbook2 extends book2{
    public function showme(){
        echo '$name:'.$this->name;
    }
}
$lbook2=new lbook2();
$lbook2->showme();
//输出:$name:computer

protected修饰可以在本类和子类中被调用,其他地方不行

static

class book3{
    static $num=0; //声明静态变量$num
    public function showme(){
        echo '第'.self::$num.'位访客';
        self::$num++; //调用静态变量的方式
    }

}
$book1=new book3();
$book1->showme();
//输出:第0位访客

$book2=new book3();
$book2->showme();
//输出:第1位访客
echo '第'.book3::$num.'位访客'; //直接使用类名调用静态变量
//输出:第2位访客

1.关键字static,使用静态变量可以不需要实例化而直接调用,如关键字::静态成员
2.静态方法只能调用静态变量,普通方法可以调用静态变量

final

final class finaltest{ //final类
    function __construct(){
        echo 'initialize object';
    }
}
class heihei extends finaltest{ //创建子类
     static function exam(){
         echo '1';
     }
 }
heihei::exam(); 
//调用子类方法 - 报错Class heihei may not inherit from final class

关键字final ,final方法不可以被继承、不能再有子类


抽象类

abstract class commodity{ //定义抽象类,关键字abstract
    abstract function service($getname,$price,$num); //定义抽象方法
}
class mybook extends commodity{  //定义抽象类的子类
    function service($getname,$price,$num){ //实现抽象类中的方法
        echo '商品:'.$getname.',价格是:'.$price.'数量为:'.$num;
    }
}
class mycomputer extends commodity{ //定义抽象类的子类
    function service($getname,$price,$num){ //实现抽象类中的方法
        echo '商品:'.$getname.',价格是:'.$price.'数量为:'.$num;
    }
}
$book=new mybook();
$computer=new mycomputer();
$book->service('php','123','10');
//输出: 商品:php,价格是:123数量为:10

1.抽象类不能被实例化,只能作为其他类的父类使用 使用 abstract 来声明
2.抽象类至少要包含一个抽象方法
3.子类必须实现抽象父类的方法,除此之外可以实现其他的方法


接口

//声明接口MPopedom
interface MPopedom{
    function popedom();
}
//声明接口MPuview
interface MPuview{
    function purview();
}
//创建子类Member 实现一个接口MPuview
class Member implements MPuview{
    function purview(){
        echo '会员拥有的权限';
    }
}
//创建子类Manager 实现多个接口MPuview和MPopedom
class Manager implements MPuview,MPopedom{
    function purview(){
        echo '管理员拥有会员拥有的权限';
    }
    function popedom(){
        echo '管理员还有会员没的';
    }
    function heihei(){ //除了接口的方法还可以实现新的方法
        echo 'haha !';
    }
}
$member=new Member();
$manager=new Manager();
$member->purview();
//输出:会员拥有的权限
$manager->purview();
//输出:管理员拥有会员拥有的权限
$manager->popedom();
//输出:管理员还有会员没的
$manager->heihei();
//输出:haha !

1.接口使用interface来声明,子类通过implements`来实现接口
2.要实现多个接口就应在每个接口间用逗号分割,且接口中的方法需要在子类中全部实现
3.除了接口方法,可以使用新方法


克隆

class bookbook{
    private $obtype='book';
    public function settype($obtype){
        $this->obtype=$obtype;
    }
    public function gettype(){
        return $this->obtype;
    }
}
$book1=new bookbook();
$book2=$book1; //使用普通数据类型的方法赋值
$book2->settype('computer'); //改变$boo2的值
echo $book1->gettype().'<br>'; //输出对象$book1的值
//输出:computer
echo $book2->gettype(); //输出对象$book2的值
//输出:computer

可见连$book1的值也被改变

class cloneobject{
    private $obtype='book';
    public function settype($type){
        $this->obtype=$type;

    }
    public function gettype(){
        return $this->obtype;
    }
    public function __clone(){ //声明clone方法
        $this->obtype='game';
    }
}
$book1=new cloneobject();
$book2=clone $book1;  //使用克隆对象的方法给对象book2赋值
echo 'book1:'.$book1->gettype();
//输出:book1:book
echo 'book2:'.$book2->gettype();
//输出:book2:game

使用克隆对象,$boo1的值未被改变


对象比较

class compareobject{
    private $name;
    function __construct($name){
        $this->name=$name;
    }
}
$book=new compareobject('book');
$clonebook=clone $book; //克隆对象
$rebook=$book; //引用对象
if($clonebook==$book){
    echo '两个对象的内容相等<br>';
}
if($rebook===$book){
    echo '两个对象的引用地址相等';
}

输出:
两个对象的内容相等
两个对象的引用地址相等

==比较两个对象的内容 ===比较对象的引用地址


对象类型检测

class objecttype{} //父类
class myitem extends objecttype{ //子类
    private $type;
}
$citem=new myitem();
if($citem instanceof myitem)
    echo '对象citem属于myitem类<br>';
if($citem instanceof objecttype)
    echo '对象citem属于objecttype类';

输出:
对象citem属于myitem类
对象citem属于objecttype类

instanceof检测当前对象属于哪个类


魔术方法 __set() __get()

class magicobject{
    private $type='';
    public function __get($name){
        if(isset($this->$name)){ //判断变量是否被声明
            echo '已声明,变量值为:'.$this->$name.'<br>';
        }else{
            echo '未声明,初始化为0'.'<br>';
            $this->$name=0; //未声明则对变量初始化
        }
    }
    public function __set($name,$value){
        if(isset($this->$name)){
            $this->$name=$value;
            echo '存在的变量,赋值为:'.$value.'<br>';
        }else{
            $this->$name=$value;
            echo '不存在的变量,初始化为'.$value.'<br>';
        }
    }
}
$mycomputer=new magicobject();
$mycomputer->type='diy'; //给变量赋值
$mycomputer->type; //调用变量$type
//输出:存在的变量,赋值为:diy<br>已声明,变量值为:diy
$mycomputer->name; //调用变量$name
//输出:未声明,初始化为0<br>不存在的变量,初始化为0

1.写入不存在或者不可见的成员变量时,__set()方法,两个参数,变量名和变量值(不可省略)
2.调用未定义或不可见的成员变量时,__get()方法,一个参数,变量名


魔术方法 __call()

class callobject{
    public function mydream(){
        echo '方法存在<br>';
    }
    public function __call($method,$parameter){
        echo '不存在,执行__call方法<br>';
        var_dump($parameter);
    }
}
$exam=new callobject();
$exam->mydream();
//输出:方法存在
$exam->hisdream('how','what','why');
//输出:不存在,执行__call方法 array(3) { [0]=> string(3) "how" [1]=> string(4) "what" [2]=> string(3) "why" }

__call()方法存储方法名及参数(调用不存在或者不可见的成员方法时),两个参数:方法名和方法参数(方法参数是以数组形式存在的)


魔术方法 __sleep() __wakeup()

1.__sleep() 方法常用于提交未提交的数据,或类似的清理操作。同时,如果有一些很大的对象,但不需要全部保存,这个功能就很好用。
2.__wakeup() 经常用在反序列化操作中,例如重新建立数据库连接,或执行其它初始化操作。
3.实现序列化接口的类将不再支持__sleep()__wakeup()


魔术方法 __toString()

class stringobject{
    private $type='diy';
    public function __toString(){ 
        return $this->type;
    }
}
$mycom=new stringobject();
echo '对象值为:'.$mycom; 
//输出:对象值为:diy

1.__toString()echo print输出时将对象转化成字符串
2.如果没有__toString直接输出对象将发生致命错误

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 221,695评论 6 515
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 94,569评论 3 399
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 168,130评论 0 360
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,648评论 1 297
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,655评论 6 397
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 52,268评论 1 309
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,835评论 3 421
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,740评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 46,286评论 1 318
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,375评论 3 340
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,505评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 36,185评论 5 350
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,873评论 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,357评论 0 24
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,466评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,921评论 3 376
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,515评论 2 359

推荐阅读更多精彩内容