大概1年前我总结过,可是那时候太菜,如今我又来总结了。 (本文是总结,不是入门,刚学oop的不适合看,基础写的比较省略。)php
其实oop编程发展到如今,知识点不少,并且很杂,好比static就很乱,很容易混淆,我本身这么分类:编程
类和对象是模拟现实中,一群类似的物体,以及他们的抽象模板的关系,在编程中便于将方法(功能)和属性(数据)组织到一块儿,作到封装,解耦,提升代码的健壮性和复用性。 是一个很是重要的概念发明。bash
类和对象的基本概念一言难尽,总结:app
属性和方法,都有三种可见性,分别用三个单词去修饰函数
在类的外部可访问 | 子类可访问 | |
---|---|---|
public | Y | Y |
protected | N | Y |
private | N | N |
类由属性和方法组成,属性和方法能够调用,一个类实例化成多个对象后,每一个对象都有本身的属性和方法,并且调用一样的方法后结果不必定同样,这叫多态。工具
然而属性和方法不必定要实例化后才能调用,定义为static的属性和方法就是直接能够调用,无需实例化。oop
我这么理解,类是一个特殊的做用域,就当成一个特殊的对象,他持有静态属性和静态方法,对象也能够调用静态方法,可是类不能调用非静态方法。测试
对象改变静态属性的值后,当对象销毁了,静态属性的值还在,由于他属于类。ui
使用类前必须定义类,当前文件没有这个类,就要include,当应用变大,就会很难搞。 就要用到自动加载。this
自动加载就是依靠spl_autoload_register()
实现,参数是一个函数,当找不到使用的类的时候,就会将类名做为参数传入注册的函数。
<?php
spl_autoload_register(function($class_name){
require_once 'www/app/lib/'.$calss_name.'.php';
})
复制代码
构造函数是最重要的一个魔术方法,因此提早单说。
发明类和对象的关系已经很厉害了,可是还不够,为了处理更加复杂的关系,出现了对象层级。
一个对象能够继承另外一个对象,这样能够更好得组织代码和复用代码。而后还有抽象类,接口和trait都是oop中组织和复用代码的工具。
一言难尽,直接说重点
是否多继承 | 代码是有功能性的仍是规范性的 | |
---|---|---|
类 | N | 功能 |
抽象类 | N | 规范(主要)和功能 |
接口 | Y | 规范 |
trait | Y | 功能(主要)和规范 |
注意
class ClassA{
//属性
public $var1 = 1;
//静态属性 静态就是归类管,不归对象管
public static $var2 = 2;
//常量 常量不可更改 访问方式相似静态
const VAR3 = 3;
//非静态方法
public function m1(){
echo 'm1 working ......';
echo PHP_EOL;
//引入$this和self
//类内访问正常属性 不用加$
echo $this->var1;
echo PHP_EOL;
//类内访问静态属性 要加$ 用类名也行
echo self::$var2;
echo ClassA::$var2;
echo PHP_EOL;
//类内访问常量 就用类名 self也行
echo ClassA::VAR3;
echo self::VAR3;
echo PHP_EOL;
}
//静态方法
public static function m2(){
echo 'm2 working ......';
echo PHP_EOL;
//静态方法不能访问非静态属性或方法,由于没有实例,$this没意义
// echo $this->var1; //Fatal error: Uncaught Error: Using $this when not in object context
// echo PHP_EOL;
//类内访问静态属性 要加$ 用类名也行
echo self::$var2;
echo ClassA::$var2;
echo PHP_EOL;
//类内访问常量 就用类名 self也行
echo ClassA::VAR3;
echo self::VAR3;
echo PHP_EOL;
}
}
//调用非静态方法
(new ClassA())->m1();
//调用静态方法
ClassA::m2();
//测试在类外,调用属性
echo '----------';
echo PHP_EOL;
//非静态属性
echo (new ClassA())->var1;
echo PHP_EOL;
//静态属性
echo ClassA::$var2;
echo PHP_EOL;
//常量
echo ClassA::VAR3;
echo PHP_EOL;
复制代码
/*非静态 访问控制 重载和访问父级*/
class ClassA{
//属性
public $var1 = 1;
protected $var2 = 2;
private $var3 = 3;
//方法
public function m1(){
echo 'm1 working ......';
echo $this->var1;
echo $this->var2;
echo $this->var3;
echo PHP_EOL;
}
protected function m2(){
echo 'm2 working ......';
echo $this->var1;//发现仍是4 重载就就覆盖了 没有方法那样的保持层级
echo PHP_EOL;
}
private function m3(){
echo 'm3 working ......';
echo PHP_EOL;
}
}
$obj1 = new ClassA();
$obj1->m1();
//$obj1->m2();//Fatal error: Uncaught Error: Call to protected method ClassA::m2()
//$obj1->m3();//Fatal error: Uncaught Error: Call to private method ClassA::m3()
echo '--------------------';
echo PHP_EOL;
class ClassB extends ClassA{
//属性 这里叫重载
public $var1 = 4;
private $var3 = 6;
//方法 重载m1
public function m1(){
echo 'm1 working ......';
echo $this->var1;
//echo parent::var1;//这是错误的 只有静态才能这样调用
echo $this->var2;//没有重载就调用父类的属性
echo $this->var3;
echo PHP_EOL;
}
//重载m2
public function m2(){
echo 'class B m2 working ......';
// echo parent::$var1; 属性没有这种调用,若是没有
echo PHP_EOL;
parent::m2();
}
public function m4(){
echo 'm4 working ......';
// $this->m3();//Fatal error: Uncaught Error: Call to private method ClassA::m3()
}
}
$obj2 = new ClassB();
$obj2->m1();
$obj2->m2();
$obj2->m4();
复制代码
/*静态 访问控制 重载和访问父级*/
class ClassA{
//属性
public static $var1 = 1;
protected static $var2 = 2;
private static $var3 = 3;
//方法
public static function m1(){
echo 'm1 working ......';
echo self::$var1;
echo self::$var2;
echo self::$var3;
echo PHP_EOL;
self::m2();
}
protected static function m2(){
echo 'm2@A working ......';
echo PHP_EOL;
}
private static function m3(){
echo 'm3 working ......';
echo PHP_EOL;
}
}
echo ClassA::$var1;
echo PHP_EOL;
// echo ClassA::$var2;//Fatal error: Uncaught Error: Cannot access protected property ClassA::$var2
ClassA::m1();
// ClassA::m2();//Fatal error: Uncaught Error: Call to protected method ClassA::m2()
//$obj1->m2();//Fatal error: Uncaught Error: Call to protected method ClassA::m2()
echo '--------------------';
echo PHP_EOL;
class ClassB extends ClassA{
//属性 重载
public static $var1 = 4;
//方法 重载m1
public static function m1(){
echo 'm1@B working ......';
echo self::$var1;
echo parent::$var1;
echo self::$var2;
// echo self::$var3;//Fatal error: Uncaught Error: Cannot access property ClassB::$var3
echo PHP_EOL;
self::m2();
parent::m2();
}
protected static function m2(){
echo 'm2@B working ......';
echo PHP_EOL;
}
}
ClassB::m1();
复制代码
1 | __construct() __destruct() | 构建和析构方法,在建立和销毁对象时调用 |
2 | __call() __callStatic() | 调用不存在的方法时调用 |
3 | __set(),__get(),__isset(),__unset() | 拦截器系列 |
4 | __sleep() __wakeup() | 在serialize()unserialize()时调用,能够额外加一些逻辑 |
5 | __toString() | 在echo时调用,不定义就echo会error |
6 | __invoke() | 当以函数方式调用对象时启动 |
7 | __set_state() __debugInfo() | 我也不知道有啥用 |
8 | __clone() | 自定义如何复制对象 |
/*魔术方法2*/
/*sleep wakeup invoke toString*/
class B{
function __construct($name,$age){
$this->name = $name;
$this->age = $age;
}
function __sleep(){
echo $this->name.'is sleep';
echo PHP_EOL;
return array('name','age');
}
function __wakeup(){
echo $this->name.'is wakeup';
echo PHP_EOL;
}
function __toString(){
return 'i am '.$this->name;
}
function invoke($arg){
echo 'what are u doing';
echo PHP_EOL;
}
}
//sleep
$obj = new B('hahaha','19');
$data = serialize($obj);
var_dump($data);
$test = unserialize($data);
//tostring
echo $test;
//invoke
$test('111');
/*魔术方法1*/
/*构建 析构 call get*/
class A{
public $name = 'default';
public $data = [];
//构建方法
public function __construct($name=NULL){
if($name){
$this->name = $name;
}
echo '__construct runing.....';
echo PHP_EOL;
}
//析构方法
public function __destruct(){
echo '__destruct runing.....';
echo PHP_EOL;
}
//拦截器
public function __call($name,$arguments){
echo 'you are try to run method'.$name.'but its not exists';
echo PHP_EOL;
}
public static function __callStatic($name,$arguments){
echo 'you are try to run static method'.$name.'but its not exists';
echo PHP_EOL;
}
//获取器设置器
public function __set($name,$value){
$this->data[$name] = $value;
echo 'setter runing ';
echo PHP_EOL;
}
public function __get($name){
if(isset($this->data[$name])){
return $this->data[$name];
}else{
return 'empty';
}
}
public function __isset($name){
if(isset($this->data[$name])){
echo 'Y';
}else{
echo 'N';
}
echo PHP_EOL;
}
public function __unset($name){
if(isset($this->data[$name])){
unset($this->data[$name]);
}
echo 'done ';
echo PHP_EOL;
}
}
$obj = new A('xyz');
echo $obj->name;
echo PHP_EOL;
$obj->tag = 'mmmm';
echo $obj->tag;
echo PHP_EOL;
echo $obj->bag;
echo PHP_EOL;
echo $obj->run();
echo PHP_EOL;
echo A::fly();
echo PHP_EOL;
复制代码