php面向对象我的浓缩总结和实例

大概1年前我总结过,可是那时候太菜,如今我又来总结了。 (本文是总结,不是入门,刚学oop的不适合看,基础写的比较省略。)php


0.思路

其实oop编程发展到如今,知识点不少,并且很杂,好比static就很乱,很容易混淆,我本身这么分类:编程

  • 1.类和对象(建立类和对象的基本概念)
  • 2.层级组织及其衍生(完善和加强类,建立层级,便于组织和复用代码)
  • 3.其余工具和特性(各个语言都有的拦截器,序列化,php有的魔术方法等杂项)

1.类和对象

1.1类和对象的概念

类和对象是模拟现实中,一群类似的物体,以及他们的抽象模板的关系,在编程中便于将方法(功能)和属性(数据)组织到一块儿,作到封装,解耦,提升代码的健壮性和复用性。 是一个很是重要的概念发明。bash

类和对象的基本概念一言难尽,总结:app

  • 类的由属性和方法组成
  • 属性和方法能够调用
  • 类能够实例化(new)出对象

1.2可见性

属性和方法,都有三种可见性,分别用三个单词去修饰函数

在类的外部可访问 子类可访问
public Y Y
protected N Y
private N N

1.3static做用域

类由属性和方法组成,属性和方法能够调用,一个类实例化成多个对象后,每一个对象都有本身的属性和方法,并且调用一样的方法后结果不必定同样,这叫多态。工具

然而属性和方法不必定要实例化后才能调用,定义为static的属性和方法就是直接能够调用,无需实例化。oop

我这么理解,类是一个特殊的做用域,就当成一个特殊的对象,他持有静态属性和静态方法,对象也能够调用静态方法,可是类不能调用非静态方法。测试

对象改变静态属性的值后,当对象销毁了,静态属性的值还在,由于他属于类。ui

1.4自动加载

使用类前必须定义类,当前文件没有这个类,就要include,当应用变大,就会很难搞。 就要用到自动加载。this

自动加载就是依靠spl_autoload_register()实现,参数是一个函数,当找不到使用的类的时候,就会将类名做为参数传入注册的函数。

<?php
spl_autoload_register(function($class_name){
    require_once 'www/app/lib/'.$calss_name.'.php';
})
复制代码

1.5构造函数

构造函数是最重要的一个魔术方法,因此提早单说。

2.层级设计及其衍生

发明类和对象的关系已经很厉害了,可是还不够,为了处理更加复杂的关系,出现了对象层级。

一个对象能够继承另外一个对象,这样能够更好得组织代码和复用代码。而后还有抽象类,接口和trait都是oop中组织和复用代码的工具。

2.1继承和重载

  • 一个对象能够继承另外一个对象,这样他就具备了父对象的属性和方法
  • 子对象能够覆盖父对象的方法
  • 调用时优先在子对象寻找属性和方法,没有就去父类寻找
  • 被final修饰的属性和方法没法重载

2.2抽象类 接口 trait

  • 抽象类的代码是侧重规范性而非实现功能,跟伪代码有点像,他定义要实现哪些函数,可是不写具体实现。
  • 接口跟抽象类很像,可是抽象类只能单继承,接口能够多继承。
  • triat则是代码片断的复用。

一言难尽,直接说重点

是否多继承 代码是有功能性的仍是规范性的
N 功能
抽象类 N 规范(主要)和功能
接口 Y 规范
trait Y 功能(主要)和规范

注意

  • 1.抽象类
    • 只要类中有抽象方法,就必须定义为抽象类,同时里面能够有非抽象方法
  • 2.接口
    • 接口的的方法都是public的,而且是没有内容的, 接口能够有常量
    • 接口还能够继承接口,扩展
  • 3.trait
    • 能够有属性、方法、能够是静态的,
    • 甚至能够写抽象方法,
    • trait还能够包含trait,
    • 导入trait的时候还能更改里面方法的可见性

2.3各类组合下的调用属性和方法

静态非静态*内外部+常量

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();

复制代码

3.其余

  • 魔术方法
    • 经常使用8
      • __construct() __destruct(),
      • __call() __callStatic(),
      • __get() __set() __isset() __unset(),
    • 不经常使用4
      • __sleep() __wakeup(),
      • __toString(),
      • __invoke(),
    • 我不会3
      • __set_state(),
      • __clone()
    • __debugInfo()
  • 相关函数
    • get_class()
    • instanceof ()
    • ::class
  • 对象操做
    • 对象序列化
    • 对象比较
    • 对象遍历
    • 对象复制
  • 其余
    • 类型约束
    • 应用的理解
    • 匿名类
    • static延迟绑定

魔术方法

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;
复制代码

static有两种意思

  • 1.区分做用域在类仍是对象,静态变量是类做用域
  • 2.有“最初调用类”的意思,主要2个用法,
    • new static,
    • 和延迟静态绑定static::funct()
相关文章
相关标签/搜索