PHP面向对象

2020-03-08
内存
    栈:空间较小,存储变量名
    堆:存储变量值
    代码段:存储方法体
    数据段:存储静态变量以及常量

构造方法(__construct()):
析构方法(__destruct()):类调用完后,销毁资源
instancof:用于确定一个PHP变量是否属于某一个类class的示例(与父类判断也会返回true),返回bool
    示例:
    $bus = new Bus();
    var_dump($bus instancof Bus);
对象的常用关键字:
    1、final:最后的最终的,一般用来不允许被继承的类或重写的方法
        1、修饰的类不能被继承 
            示例:
                final class A 
                {
                    public function a()
                    {
                        echo 1;
                    }
                }
        2、修饰的方法不能被覆盖
            示例:
                class A 
                {
                    public final function a()
                    {
                        echo 1;
                    }
                }
    2、static 声明类中的静态变量和方法,在类中调用静态当前类的静态变量和方法
        示例:
            class A 
            {
                public static $a = 2;
                public static function a()
                {
                    echo 1;
                }
                public function rum()
                {
                    static::a(); //调用当前类中的静态方法
                    echo static::$a; //调用当前类中的静态变量
                }
            }
            
            A::$a = 5; //给类的属性赋值
            echo A::$a; //访问类的属性
            A::a(); //访问类的方法
            $a = new A;
            $a->run();
    3、self 访问本类中的静态属性,常量和方法;
        示例:
            class A 
            {
                public static $a = 2;
                public static function a()
                {
                    echo 1;
                }
                public function rum()
                {
                    self::a(); //调用当前类中的静态方法
                    echo self::$a; //调用当前类中的静态变量
                }
            }
            $a = new A;
            $a->run();
        self和static的区别:
            如果子类重写了父类的方法,而父类中的其他方法调用了父类中被重写的方法,那么实例化子类,调用父类的方法
            self:会执行父类的本身的被重写前的方法体,
            static:会执行子类重写后的方法体
            示例:
                class A 
                {
                    public static function test()
                    {
                        echo 'this is A test';
                    }
                    public function rum()
                    {
                        self::test();
                        static::test();
                    }
                }
                class B extends A
                {
                    public static function test()
                    {
                        echo 'this is B test';    
                    }
                }
                $b = new B;
                $b->run();
    4、const 类内部定义常量 define一般是类外部定义常量
        示例:
            class A
            {
                const NAME = 'tom';
                public static function test()
                {
                    self::NAME;
                }
            }
            echo A::NAME;
    5、parent 重写父类方法时,保留父类的方法体
        示例:
             class A extendB
            {
                public function __construct()
                {
                    parent::__construct();
                    echo '111';
                }
            }
    6、clone 克隆对象,用在类的外部
        示例:
            $a = new A;
            $a1 = clone $a;
魔术方法:(类的内部使用)
    1、__set 在类的外部为私有变量赋值时,会自动调用;可以实现对私有属性的过滤
        示例:
            class A
            {
                private $uname;
                public function __set($name,$val) //$name是私有属性的变量名,$val是外部设置的值
                {
                    echo $name . '====' . $val;
                }
            }
            $a1 = new A; 
            $a1->uname = 'tom';
    2、__get 在类的外部调用私有变量时,会自动调用
        示例:
            class A
            {
                private $uname;
                public function __get($name)
                {
                    return $this->$name;
                }
            }
            $a1 = new A; 
            echo $a1->uname;
    3、__isset 类外部判断内部变量时会默认调用此函数 
    4、__unset 类外部删除私有属性时会自动调用
    5、__call  当调用类内部不存在的方法时会自动调用
        示例:
            class A
            {
                private $uname;
                public function __call($method,$param) //$method是外部调用的不存在方法名,$param是调用时传递的参数
                {
                    echo 'hello'.$method;
                    echo '<br/>';
                    var_dump($param);
                }
            }
            $a1 = new A; 
            $a1->test();
    6、__callStatic 当调用类内部不存在的静态方法时会自动调用
        示例:
            class A
            {
                private $uname;
                public static function __callStatic($method,$param) //$method是外部调用的不存在方法名,$param是调用时传递的参数
                {
                    echo 'hello'.$method;
                    echo '<br/>';
                    var_dump($param);
                }
            }
            A::test();
    7、__clone  外部调用clone时,会自动调用
        示例:
            class A
            {
                public function __clone()
                {
                    echo 1;
                }
            }
            $a1 = new A;
            $s2 = clone $s1;
    8、__toString 输出对象时自动调用 echo时才会使用,一般返回序列化的对象时才会用
        示例:
            class A
            {
                public function __toString()
                {
                    echo 'hello word';
                }
            }
            $a1 = new A;
            echo $a1; 

对象的序列化(serialize)及反序列化(unserialize):数据的长度手动改变时,反序列化会出错
    序列化的对象反序列化后获得的对象可以直接调用对象的方法
    示例:
        class A
            {
                public $name = 'tom';
                public function a()
                {
                    echo 1;
                }
                public function __toString()
                {
                    echo serialize($this);
                }
            }
            $a1 = new A;
            echo $a1; 

抽象类:(因为拥有抽象方法所以才有抽象类)
    1、类的方法是抽象的(没有方法体),
    2、不能实例化,只能被继承,,(如果实例化会报错)
    3、如果父类中有抽象方法,那么子类中必须重写这个抽象方法;(如果子类不重写会报错)
    4、多态时可以使用
抽象类与抽象方法定义:abstract定义抽象的类和方法
abstract class A  //定义抽象类
{
    public abstract function a();  //定义抽象方法,public可以不写
    public function b() //抽象类中可以定义普通的方法
    {
        echo '2';
    }
}
继承抽象类
class B extends A
{
    public function a()
    {
        echo '1';
    }
}

接口 interface 
    1、是一个特殊的抽象类,不能实例化
    2、实现多继承,
    3、方法必须都是抽象方法,子类必须重写接口的所有方法,
    4、接口类中定义的抽象方法不需要加abstract,如果加了会报错
    5、不能定义变量,可以定义常量
    6、接口可以继承其他接口
    7、可以实现多态
定义:
    interface A //定义了一个接口类
    {
        public function a();
    }

实现:接口类只能被其他类实现,(类似继承)
class B implements A
{
    public function a()
    {
        echo 1;
    }
}

实现多继承:
    interface A 
    {
        public function a();
    }

    interface C
    {
        public function c();
    }

    class B implements A,C
    {
        public function a()
        {
            echo 1;
        }
        public function c()
        {
            echo 2;
        }
    }

接口继承其他接口:
    interface A 
    {
        public function a();
    }

    interface C extends A
    {
        public function c();
    }

    class B implements A
    {
        public function a()
        {
            echo 1;
        }
        public function c()
        {
            echo 2;
        }
    }

新特性 trait PHP5.4开始加入的
    1、代码复用,解决单继承的限制
    2、不能被实例化
    3、从基类继承的成员会被trait插入的成员所覆盖。优先顺序是来自当前类的成员覆盖了trait的方法,而trait则覆盖了被继承的方法
    4、如果两个trait都插入了一个同名的方法,如果没有明确解决冲突将会产生一个致命错误。
    5、为了解决多个trait在同一个类中的命名冲突,需要使用insteadof操作符来明确指定使用冲突方法中的哪一个;或者使用as操作符可以为某个方法引入别名。
    6、as语法还可以用来调整方法的访问控制
    7、trait 支持抽象方法的使用
    8、可以使用静态成员与方法
    9、定义了一个属性后,类就不能定义同样名称的属性,除非定义的属性是同样的访问可见度、初始默认值
定义:
    trait A
    {
        public $a1 = 1;
        public function a()
        {
            echo 1;
        }
        public function c()
        {
            echo 1;
        }
        public function d()
        {
            echo 1;
        }
        abstract public function e();
    }
    trait B
    {
        public $b1 = 1;
        public function b()
        {
            echo 1;
        }
        public function c()
        {
            echo 1;
        }
        public function d()
        {
            echo 1;
        }
        public function f()
        {
            echo 1;
        }
    }

使用:
class C
{
    use A,B {
        B::c insteadof A; //使用B的c方法
        A::d insteadof B; //使用A的d方法
        B::d as talk;     //给B的d方法起一个别名
        B::f as private f1;
    }
    public funtionc t()
    {
        echo $this->b1;
    }
    public function e()
    {

    }
}

$c = new C;
$c->a();
echo $c->a1;
$c->t();

魔术常量:
    __FUNCTION__  返回当前函数的方法名称,不会显示方法名的类名
    __CLASS__  返回当前的类名,(包含当前类的作用于及命名空间)
    __TRAIT__ 返回当前的trait名称
    __METHOD__ 返回当前的方法名,会显示方法名的类名
    __NAMESPACE__ 返回当前的命名空间

    示例:
        class A
        {
            public static function a()
            {
                return __FUNCTION__
            }
        }
        echo a::a();
与类有关系统函数:
    class_extsis 判断类名是否存在(有命名空间需要加上命名空间)
    get_class 获取对象对象的类名
    get_class_methods 获取对象内的所有的方法名
    get_class_vars 获取一个类的所有属性
    is_object 判断是否是对象

 

{/if}