Blogger Information
Blog 22
fans 0
comment 0
visits 14815
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
类声明与类的实例化,对象的三个重要特征:封装,继承和多态,类中静态成员的声明和访问。2018-9-4 18:05
朝闻道的博客
Original
912 people have browsed it

类的声明与实例化代码演示如下:

实例

<?php
/**
 * 类的声明与实例化
 * 1. 类声明: class;
 * 2. 类的实例化: new
 * 3. 对象成员的访问:->
 */

//用关键字class声明一个类
class Demo1
{

}
//用关键字 new 实例化一个类
$demo1 = new Demo1();

//给当前对象添加一些属性和方法
$demo1->name = '王老师';
$demo1->sex = '男';
$demo1->hello = function(){
    return '我是一个自定义的类方法';
};
//使用对象访问符:-> 来访问对象中的成员(属性和方法)
echo $demo1->name,': ',$demo1->sex,'<br>';

//错误的调用方式,因为当前对象方法不是一个普通函数,而是一个对象方法
//echo $demo1->hello();
//正确的调用方式,对象方法应该以回调的方式运行
echo call_user_func($demo1->hello);

运行实例 »

点击 "运行实例" 按钮查看在线实例

类常量与类属性的重载代码演示如下:

实例

<?php
/**
 * 对象的三大特征: 封装,继承,多态
 * 对象三要素之一: 封装
 *
 * 1.[封装]是指类中成员的访问进行限制,从而实现类的封装;
 * 2.类成员包括二类: 类属性, 类方法
 * 3.类成员的访问限制符(3p): public, protected, private
 * 4.类成员的访问应该通过公共接口(方法)进行,提高安全性
 * 5.类中成员可以使用 $this->成员 直接访问
 * 6.$this 是对象伪变量,代表着当前类的一个实例对象
 */

class Demo2
{
    //声明类属性,属性值必须是字面量,不能是变量或表达式
    public $name;   // 未初始化,默认值为null
    public $salary = 9800; // public 公共属性
    //将类属性进行封装,外部不能访问
    protected $sex = 0;   // protected 受保护的成员,仅限本类或本类的子类访问,0男1女
    private $age = 36;  // private 私有成员,仅限本类访问

    //声明类方法:创建公共接口,供外部访问类中访问受限成员
    public function getSex()
    {
        //返回语义化的性别名称
        return ($this->sex == 0) ? '男' : '女';
    }

    //创建$age属性的公共访问接口
    public function getAge()
    {
        // 男性直接输出年龄,女性拒绝查看
        return  ($this->sex == 0) ? $this->age : '保密';
    }
}

//类的实例化
$demo2 = new Demo2();

//测试属性默认值
var_dump(is_null($demo2->name));    // ($demo2->name === null) 返回同样结果: true

//查看公共属性 salary
echo $demo2->salary,'<br>';

//echo $demo2->sex,'<br>'; // protected 成员,类外部不可访问
//echo $demo2->age,'<br>'; // private 成员,类外部不可访问

echo '性别是: ', $demo2->getSex(),'<br>';  // 根据标志,返回语义化的中文
echo '年龄是: ', $demo2->getAge(),'<br>';  // 男性就显示年龄,女孩子的年龄是保密的

运行实例 »

点击 "运行实例" 按钮查看在线实例

实例

<?php
/**
 * 类常量,对象初始化,属性的重载
 * 1. 类常量可用来创建对象之间的共享数据
 * 2. 对象初始化: 用构造方法实现,创建对象之前会自动调用,完全对象的一些初始化工作
 *    例如:对象属性初始化,创建对象时自动调用的方法等,方法名称固定:__construct()
 * 3.属性重载:在类的外部访问不存在或者无权限访问的属性时,会自动触发此类方法调用
 *   属性重载涉及四个方法:__get(),__set(),__isset(),__unset()
 */

class Demo3
{
    //类常量:所有对象共享,用类名加范围解析符(::)访问,且默认为公共属性public
    //类常量可用来创建对象之间的共享数据
    const SITE_NAME = 'PHP中文网';

    //声明二个私有属性
    private $name;
    private $course;
    private $grade;

    //构造方法
    public function __construct($name,$course, $grade)
    {
        $this->name = $name;
        $this->course = $course;
        $this->grade = $grade;
        //构造方法中不仅可以初始化对象属性,还可以调用类方法
        echo $this->show();
    }

    //输出属性内容
    public function show()
    {
        return $this->name.'的《'.$this->course.'》课程的成绩是: '.$this->grade.'分!';
    }

    //获取属性的重载
    public function __get($name)
    {
        if ($name == 'grade') {
            return $name.'不允许查看';
        }
        return $this->$name;
    }

    //更新属性的重载
    public function __set($name, $value)
    {
        if ($name == 'grade') {
            echo $name.'不允许修改','<br>';
        }
        $this->$name = $value;
    }

    //属性检测的重载
    public function __isset($name)
    {
        if ($name == 'grade') {
            return false;
        }
        return isset($this->$name);
    }

    //销毁属性的重载
    public function __unset($name)
    {
        if ($name == 'grade' || $name == 'name') {
            return false;
        }
        unset($this->$name);
    }
}

//访问类常量:类常量可以被该类的所有对象所共享,所以不属于任何一个对象,应该使用类来访问
echo '站点名称: ', Demo3::SITE_NAME, '<br>';

//实例化Demo3,创建对象
$demo3 = new Demo3('小明','PHP', 86);
var_dump($demo3);
//访问属性,因为属性全部被封装,所以必须通过一个统一的外部接口访问
echo $demo3->show();
echo '<hr>';

//如果想简化以上操作,可以在实例化之前,在构造方法中调用属性访问接口方法
new Demo3('小明','PHP', 86);
echo '<hr>';

//属性操作: 获取,设置,检测,销毁
//获取
echo '姓名: ', $demo3->name, '<br>';   // 访问私有属性,如类中无__get()会出错,如有自动触发
echo '成绩: ', $demo3->grade, '<br>';  // 可以在__get()进行属性访问的权限控制

//设置
$demo3->course = 'Python';
echo '课程: ', $demo3->course,'<br>';
$demo3->grade = 65;

//检测,因为grade私有,所以外部检测不到,如类中有__isset()方法就可以检测到
echo isset($demo3->name) ? '存在<br>' : '<span style="color:red">不存在</span><br>';
echo isset($demo3->grade) ? '存在<br>' : '<span style="color:red">不存在</span><br>';

//销毁
unset($demo3->course);
echo $demo3->course,'<br>';

unset($demo3->name);    // 重载方法中__unset()不允许销毁grade和name属性
echo $demo3->name,'<br>';   // 所以这里仍可以访问到name属性

运行实例 »

点击 "运行实例" 按钮查看在线实例

类的继承与方法构造代码演示如下:

实例

<?php
/**
 * 对象三要素之: 继承与多态
 * 1. 继承是指类之间的继承,是代码复用的重要手段,之前我们是通过"函数"实现的代码复用
 * 2. 继承使用关键字: extends
 * 3. 引用父类成员: parent::
 * 4. 子类可以将父类中的公共和受保护成员全部继承
 */

class Demo4
{
    //父类属性
    public $name;
    protected $age;
    private $salary;
    const APP_NAME = '图书管理系统';

    //父类构造器
    public function __construct($name, $age)
    {
        $this->name = $name;
        $this->age = $age;
    }

    //属性访问重载
    public function __get($name)
    {
        if (isset($this->$name)) {
            return $this->$name;
        }
        return '非法属性';
    }
}

class Demo4_1 extends Demo4
{
    //子类自有属性
    private $sex;
    const APP_NAME = '影院后台管理系统';  //类常量可以在子类中重写

    //子类将父类同名方法进行重写,根据传入参数不同,实现不同的功能,这就是多态性
    public function __construct($name, $age, $sex='male')
    {

//        $this->name = $name;
//        $this->age = $age;
        //引用父类的构造方法来简化代码
        parent::__construct($name, $age);
        $this->sex = $sex;
    }

    //将父类属性重载方法重写后,顺利读取子类属性
    //所以属性重载方法__get()应该设置在最终工作类中(例如本类Demo4_1),而不是父类Demo4中
    //此时,将父类Demo4中的__get()删除,代码执行仍然正确
    public function __get($name)
    {
        if (isset($this->$name)) {
            return $this->$name;
        }
        return '非法属性';
    }

}

//当前类Demo4_1中即使没有任何成员,一样可以访问父类成员
$demo4_1 = new Demo4_1('bill', 88);
//访问父类中的属性
echo $demo4_1->name,'<br>';
echo $demo4_1->age,'<br>';
echo $demo4_1->salary,'<br>';   // 父类私有属性子类不可见,访问不到
echo Demo4_1::APP_NAME, '<br>';  // 访问类常量
echo $demo4_1->sex, '<br>'; //取不值,因为父类__get()不能识别子类属性

运行实例 »

点击 "运行实例" 按钮查看在线实例

类中静态成员的声明与访问代码演示如下:

实例

<?php
/**
 * 类中的静态成员与访问
 * 1.类中静态成员使用关键字:static 定义;
 * 2.静态成员包括: 静态属性和静态方法;
 * 3.静态成员是属于类的,我们应该终终使用类来访问;
 * 4.静态属性必须使用类来访问,而静态方法即可以用类,也可以用对象访问;
 * 5.静态成员是可以有访问限制的: public,protected,private;
 * 6.静态成员与对象无关,所以内部不允许使用伪变量: $this;
 * 7.访问时,类名后必须使用:范围解析符:双冒号[::]
 * 8.在类中引用自身使用关键字: self::
 *
 * 范围解析符的作用:
 * 1. 访问静态成员;
 * 2. 访问类常量;
 * 3. 继承上下文中引用被覆盖成员
 */

class Demo5
{
    public static $pdo = null;
    protected static $db = [
      'type' => 'mysql',
      'host' => '127.0.0.1',
      'name' => 'php',
      'user' => 'root',
      'pass' => 'root',
    ];

    public static function connect()
    {
        $dsn = self::$db['type'].':host='.self::$db['host'].';name='.self::$db['name'];
        self::$pdo = new PDO($dsn,self::$db['user'],self::$db['pass']);
    }

    public static function select($table,$fields='*', $num=5)
    {
        $stmt = self::$pdo->prepare("SELECT {$fields} FROM {$table} LIMIT {$num}");
        $stmt->execute();
        return $stmt->fetchAll(PDO::FETCH_ASSOC);

    }
}

//连接数据库
Demo5::connect();

//查询数据表
$result = Demo5::select('staff','name,age,salary',8);

//显示结果
echo '<pre>',var_export($result);

运行实例 »

点击 "运行实例" 按钮查看在线实例

课堂总结如下:

9月2日课堂总结:现在学习感觉有点力不从心了,学一点忘一点,心态有点爆炸。
刚开始学习HTML和CSS的时候感觉比较简单,现在学习PHP中的类和对象的属性,
命名空间一窍不通,视频往往要看两三遍才会懂一点点。我想了很久很久不知道为
什么会出现这样的问题,现在我终于想明白了以前上课时总是被动的去听课,听得
津津有味,课一上完就什么都忘了。造成这种情况的原因有很多其中最主要的就是
课前没有预习,课中没有带着问题听课,课后没有复习。为了解决这个问题,我一
定要提前预习,带着问题听课,课后复习,争取在第三期PHPpeixunban顺利毕业。



Correction status:qualified

Teacher's comments:
Statement of this Website
The copyright of this blog article belongs to the blogger. Please specify the address when reprinting! If there is any infringement or violation of the law, please contact admin@php.cn Report processing!
All comments Speak rationally on civilized internet, please comply with News Comment Service Agreement
0 comments