PHP-面向对象与面向对象编程

认识面向对象,学习面向对象的基础知识,了解面向对象的相关特性和使用规则,掌握把实际问题抽象成为类对象用以解决实际问题的方法。

面向对象(object-oriented)

项目代码都应该由单个能够起子程序作用的对象组成。

三个特性:
  • 重用性:模块在项目中可重复利用
  • 灵活性:模块替换成本低
  • 扩展性:对已有的模块添加功能
类与对象:

面向对象是说项目由一个个对象组合而成,而类是生成对象的代码模板,所以,我们要思考一下如何创建类呢。

创建类

PHP使用class声明一个类,使用new来实例化一个对象。

class Computer{
    
}
// 实例化类得到一个对象
$comp = new Computer();

类名以字母或下划线开头,首字母一般使用大写。

上面创建的Computer类是空的,类有属性与方法;类的属性和方法其实就是变量和函数,只不过是属于类的变量和函数。

访问控制权限:

  • public: 在类内部和类外部都能调用
  • protected: 子类、父类(继承)访问
  • private: 只能在本类访问

示例:

class Computer{
    // 定义类属性
    public $cpu = "amd 500";
    protected $name = "lenovo";
    private $prise = "6500";
    
    //定义类方法
    public function playGame(){
        echo $this->name;
    }
}
// 实例化类得到一个对象
$comp = new Computer();
// 调用类的属性
echo $comp->cpu; //amd 500
echo $comp->name; //会报错
// 调用类的方法
$comp->playGame(); // 

注:类中this可以理解为该类的一个实例。

构造方法与析构方法
  • __construct()构造方法:实例化一个对象时会自动执行的方法。
  • __destruct()析构方法:销毁一个对象时会自动执行的方法。
class Computer{
    ...
    
    public function __construct()
    {
        echo "cpu准备就绪";
    }
    
    ...
    
    public function __destruct()
    {
        echo "关闭电源";
    }
}
常量

1.一般定义常量:
define(): 在函数中定义常量(全局的不受命名空间的影响),定义后不允许改变

2.类常量:
const: 在类中定义常量(受命名空间的影响)

常量是属于类的,不是属于对象的。类中用 self::常量名 调用,外用"类名":: 常量名 调用即可。

class Computer{
    // 定义类常量
    const ONE = 1;
    const TWO = self::ONE + 1;
    
    ...
}
var_dump(Computer::TWO);
类的继承

类的继承使用extends关键字,继承一个类后就获得了该类的属性和方法。

子类可以覆盖继承的父类的同方法名的方法,子类中用 parent::方法名 调用父类方法。

// 父类  
class Dad{
    public function __construct(){
        echo "Dad init...";
    }
    public function say(){
        echo "I am dad";
    }
}
// 子类
class Son extends Dad{
    public function __construct(){
        parent::__construct();
        echo "Son init...";
    }
}
$boy = new Son();
$boy->say();
final关键字:

PHP 5 新增了一个 final 关键字。如果父类中的方法被声明为 final,则子类无法覆盖该方法。如果一个类被声明为 final,则不能被继承。

演示:

final class Dad{
    public function __construct(){
        echo "Dad init...";
    }
    final public function say(){
        echo "I am dad";
    }
}

注:final不能修饰属性

命名空间

受命名空间影响类型:

类(包括抽象类/traits),接口,函数和常量;

不同命名空间下的类调用:

  • use调用不同命名空间中的类 use 命名空间类;
  • use调用不同命名空间中的函数 use function 命名空间函数;
  • use调用不同命名空间中的常量 use consst 命名空间常量;
  • 当调用不同命名空间下的相同类时,可以在调用时给其中一个重命名 操作 "as 重命名";
  • 当有命名空间的地方想要调用全局类时 "类名";
类自动加载
<?php
function __autoload($className){
    require $className . ".php";
}
<?php

function autoload($className){
    require $className . ".php";
}
sql_autoload_register('autoload');

//或者
sql_autoload_register(function($className){
    require str_replace("\\","/",$className.".php");
});

spl_autoload_register('外部方法名');

spl_autoload_register([new 类名,'类名里的方法'])。

static关键字

如果在类属性名前加static关键字,外部访问不需要实例类。

class Person{  
    pubilc static $hand = "手";
    public static function work(){
        return "work..";
    }
}
echo Person::$hand;
echo Person::work();

魔术方法

  1. __construct() 实例化类时自动调用。
  2. __destruct() 类对象使用结束时自动调用。
  3. __set() 在给未定义的属性赋值的时候调用。
  4. __get() 调用未定义的属性时候调用。
  5. __isset() 使用isset()或empty()函数时候会调用。
  6. __unset() 使用unset()时候会调用。
  7. __sleep() 使用serialize序列化时候调用。
  8. __wakeup() 使用unserialize反序列化的时候调用。
  9. __call() 调用一个不存在的方法的时候调用。
  10. __callStatic()调用一个不存在的静态方法是调用。
  11. __toString() 把对象转换成字符串的时候会调用。比如 echo。
  12. __invoke() 当尝试把对象当方法调用时调用。
  13. __set_state() 当使用var_export()函数时候调用。接受一个数组参数。
  14. __clone() 当使用clone复制一个对象时候调用。
演示:
1. __set 与 __get
  • __set当给不可访问或不存在属性赋值时被调用
  • __get()在我们尝试访问一个不存在的属性时会被调用
class Test
{
    private $name = '';
    
    public function __set($var,$val){
        $this->$var = $val;
    }
    
    public function __get($var){
        return $this->$var;
    }
}

$test = new Test();
$test->name = 'giant123';
var_dump($test->name);
2. __isset 与 __unset
  • __isset对不可访问或不存在的属性调用isset()或empty()时被调用
  • __unset对不可访问或不存在的属性进行unset时被调用
class Test
{
    private $name = '';

    public function __isset($var){
        return isset($this->$var) ? true : false;
    }
    
    public function __unset($var){
        unset($this->$var);
    }
}

$test = new Test();
var_dump(isset($test->age));
unset($test->name);
3. __call

调用不可访问或不存在的方法时被调用

class Test
{
    public function __call($func,$arguments){
        ...
    }
}
$test = new Test();
$test->go(1,'ok');
4. __callStatic

__callStatic调用不可访问或不存在的静态方法时被调用

class Test
{
    public static function __callStatic($method,$arg){
        ...
    }
}
Test::go(1,'ok');
5. __invoke()

当把对象当做函数去调用的时候,会自动调用该方法。

6. __toString()

用于一个类被当成字符串时应怎样回应

trait关键字

php是单继承语言,但是当如果一个类要使用多个类的里的方法或者属性,这时可以使用trait关键字将原来需要继承的类改为用trait包含属性与方法,同时使用use调用,trait也支持trait嵌套。

trait A{
    public function a(){
        echo "a. ";
    }
}

trait B{
    public function b(){
        echo "b. ";
    }
}

trait C{
    use A,B;
}

class Test
{
    use C;
    
    public function c(){
        echo "c.";
    }
}
$test = new Test();
$test->a();
$test->b();
$test->c();
接口
<?php
interface Person {
    public function eat();
    public function sleep();
}

class Man implements Person {
    public function eat(){
        echo "吃大餐...";
    }
    public function sleep(){
        echo "半夜才睡觉...";
    }
}

class Woman implements Person {
    public function eat(){
        echo "减肥套餐...";
    }
    public function sleep(){
        echo "10点就睡...";
    }
}

class L {
    public static function factory(Person $user) {
        return $user;
    }
}

$user = L::factory(new Woman());
$user->eat();
interface Ia {
    const Giant = "jiatengfei";
    public function eat();
}
interface Ib {
    public function sleep();
}
interface AB extends Ia,Ib {

}
echo(Ia::Giant);
抽象类
abstract class AB {
    public function eat(){}
    public function sleep(){}
    
    public function play(){
        echo "playing...";
    }
}

class Test extends AB {
    public function eat(){
        echo "减肥套餐...";
    }
    public function sleep(){
        echo "先玩一会...";
        $this->play();
    }
}

$test = new Test();
$test->eat();
$test->sleep();
0 人推荐

声明:本文原创发布于加藤非博客,转载请注明出处:加藤非博客 jiatengfei.com 。如有侵权,请联系本站删除。

加藤非博客
请先登录再发表评论
  • 最新评论

  • 总共0条评论