php面向对象个人浓缩总结和实例

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


0.思路

其实oop编程发展到现在,知识点很多,而且很杂,比如static就很乱,很容易混淆,我自己这么分类:

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

1.类和对象

1.1类和对象的概念

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

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

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

1.2可见性

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

在类的外部可访问子类可访问
publicYY
protectedNY
privateNN

1.3static作用域

类由属性和方法组成,属性和方法可以调用,一个类实例化成多个对象后,每个对象都有自己的属性和方法,而且调用同样的方法后结果不一定一样,这叫多态。

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

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

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

1.4自动加载

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

自动加载就是依靠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规范
traitY功能(主要)和规范

注意

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

转载于:https://juejin.im/post/5c808a47f265da2db54260ed

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值