慕课网面向对象
面向对象介绍: object oriented
项目代码都应该由单个能够起子程序作用的对象组成.
达到软件工程的目标:
重用性
灵活性
扩展性
类和对象的使用
类是生成对象的代码模板
装机单->电脑
类->对象
类包含{
属性;
方法;
$this 可以理解为这个类的一个实例
}
对象包含两部分:
-对象的组成元素
是对象的"数据模型",用于描述对象的数据
又被称为对象的"属性",或者对象的"成员变量"
-对象的行为
是对象的"行为模型",用于描述对象能够做什么事情
又被传称为对象的"方法"
对象的特点:
每一个对象都是独一无二的;
对象是一个特定事物,他的职能是完成特定功能
对象是可以重复使用的
面向对象编程就是在编程的时候数据结构(数据组织方式)都通过对象的结构进行存储 - 属性,方法
为什么要使用面向对象?
对象的描述方式更加贴合真实的世界,有利于大型业务的理解
在程序设计的过程中用对象的视角分析世界的时候能够拉近程序设计和真实世界的距离
面向对象的实质
面向对象就是把生活中要解决的问题都用对象的方式进行存储
- 属性
- 方法
对象与对象之间通过方法的调用进行互动
面向对象的基本思路
第一步:识别对象
- 任何实体都可以被识别为一个对象
第二步:识别对象的属性
-对象里面存储的数据被识别为属性
-对于不同的业务逻辑,关注的数据不同,对象里面存储的属性也不同
第三步:识别对象的行为
-对象自己属性数据的改变
-对象和外部交互
eg:
一个桌子
桌子的组成元素
-四个桌腿
-一个桌面
-长宽高
-重量
桌子的行为
-移动桌面的位置
NBA球员
组成元素
球队,球员号码
行为
投篮,传球
面向对象的基本原则
-对象内部是高内聚的
-对象只负责一项特定的职能
-所有对象相关的内容都封装到对象内部
-对象对外是低耦合的
-外部世界可以看到对象的一些属性
-外部世界可以看到对象可以做某些事情
面向对象基本实践
类的概念
实例化的概念
构造函数
析构函数
数据访问
类
-物以类聚,把具有相似特性的对象归类到一个类中
-类定义了这些相似对象拥有的相同的属性和方法
-类是相似对象的描述,称为类的定义,是该类对象的蓝图或者原型
-类的对象称为类的一个实例 (Instance)
-类的属性和方法统称为类成员
类的实例化 instantiate
类的实例化instantiate 就是通过类定义创建一个类的对象
对象继承
继承的好处
-父类里面定义的类成员可以不用在子类中重复定义,节约了编程的时间和代价
-同一个父类的子类拥有相同的父类定义的类成员,因此外部代码调用它们的时候可以一视同仁
-子类可以修改和调整父类定义的类成员
-我们成为重写overwrite
-一旦子类修改类,就按照子类修改之后的功能执行。
面向对象-访问控制
三种访问权限
-public 公有的类成员,可以在任何地方被访问;
-protected 受保护的类成员,可以被其自身以其子类访问
-private 私有的类成员,只能被自身访问
面向对象 -static 静态关键字
1 静态属性用于保存类的公有数据
2 静态方法里面只能访问静态属性
3 静态成员(属性/方法)不需要实例化对象就可以访问
4 类的内部可以通过self 或者static关键字来访问
5 可以通过parent关键字访问父类的静态成员
6 可以通过类的名称在类定义外部访问静态成员
重写:子类可以编写可以同父类完全相同的方法名,我们称之为重写overwrite
final关键字
对于不想被任何类继承的类可以在class前添加final关键字,
对于不想被子类重写的方法,可以在方法定义的前面添加final关键字
数据访问
用parent关键字可以访问父类中被子类重写的方法
$this->method();
self::method()
都可以访问自身类中的方法
self:: 可以访问类常量
self:: 或者static:: 都可以访问类中的静态属性
面向对象-接口 interface
接口就是把不同类的共同行为进行了定义,然后在不同的类里面实现不同的功能
一旦某个类实现类某个接口,那么就必须实现接口定义的方法
interface关键词用于定义接口,
接口里面的方法不需要有方法的实现,
implements关键字用于表示某个类实现某个接口
不能实例化接口
instanceof (一)判断某个对象是否是某个类的实例 (二)判断某个对象是否实现了某个接口
可以用extends接口可以继承接口,当类实现子接口,父接口定义的方法也需要在这个类里面具体实现
某个类实现了implements某个接口和继承extends某个类的区别
-实现接口跟继承类很相似,但是接口不能直接创建自己的对象
-继承的父类必须有该方法的具体实现,子类可以重写父的方法,也可以不重写
-接口里的方法是不需要具体实现的,只要定义类方法的名称和参数就可以,具体的实现必须在类中定义
类的方法必须有实现,接口的方法必须为空
面向对象-多态
因为接口的方法实现可以有很多,所以对于接口里面定义的方法的实现是多种多样的,这种特性我们称之为多态
面向对象-抽象类
1.使用关键字 abstract
2.类中只要有一个方法声明为abstract抽象方法,那么这个类就必须声明为抽象类
3.抽象方法只允许有方法声明与参数列表,不允许有方法体
4.因为抽象方法的不确定性,所以抽象类禁止实例化,仅允许通过继承来实例化
5.继承抽象类的子类中,必须将抽象类中的所有抽象方法全部实现
6.子类成员的访问限制级别必须等于或者小于抽象类的约定,
7.子类方法参数必须与抽象方法参数完全一致,但允许增加默认参数
php 魔术方法
__toString();
当对象会被当作string使用的时候,这个方法会被自动调用
echo $obj;
__invoke();
当对象会被当作方法调用的时候,这个方法会被自动调用
$obj($param)
__call()
当对象访问不存在的方法名称时,__call方法会被自动调用
__callStatic()
当对象访问不存在的静态方法时,__callStatic方法会被自动调用
<?php
class Maigc{
public function __call($name, $arguments)
{
return "this is Magic class the request method is <" .$name.">"."this arg is ".implode('-',$arguments);
}
}
$obj = new Maigc();
echo $obj->call("param","param1");
//运行结果为
this is Magic class the request method is <call>this arg is param-param1
这两个方法在php里面也被称为方法的重载overloading,通过这两个方法,同一方法的名称的调用可以对应不同的方法的实现
__get();
读取不可访问属性的值时,__get会被调用
<?php class Maigc{ protected $name = "name"; public $name1 = "name1"; public function __get($name) { return "this is Magic class __get request method is : " .$name." "; } } $obj = new Maigc(); echo $obj->className; echo $obj->name; echo $obj->name1;
//执行结果为
this is Magic class __get request method is : className
this is Magic class __get request method is : name
name1
__set();
在给不可访问属性赋值时,__set会被调用
<?php class Magic{ protected $name = "name"; public $name1 = "name1"; public function __set($name, $value) { echo "this Magic method is __set that's name is :" . $name. " that'is value is " .$value." "; } } $obj = new Magic(); $obj->className = "haha"; $obj->name = "calssName"; echo $obj->name1;
当对不可访问属性调用isset()或者empty()时,__isset()会被调用;
<?php class Magic{ protected $name = "name"; public $name1 = "name1"; public function __isset($name) { echo "this reqeust param is " . $name . " "; } } $obj = new Magic(); isset($obj->name2); echo "--- "; isset($obj->name1); echo "--- "; isset($obj->name); echo "--- ";
//执行结果为
this reqeust param is name2
---
---
this reqeust param is name
---
当对不可访问属性调用unset()时,__unset()会被调用;
<?php class Magic{ protected $names = "nameg"; public $name1 = "name1"; public function __unset($param) { echo "this is __unset name is :" .$param. " "; } } $obj = new Magic(); unset($obj->name2); echo "-- "; unset($obj->name1); echo "-- "; unset($obj->$names);
所谓不可访问属性,实际上就上在调用某个属性时发现这个属性没有被定义,这时候不同的操作会出发不同的魔术方法
-这几个方法也被成为属性重载的魔术方法
__colne()
<?php class NbaPlayer{ public $name; public function __clone() { $this->name = "james"; } } $obj = new NbaPlayer(); $obj->name = "Ym"; echo $obj->name ." "; $obj1 = clone $obj; echo $obj1->name . " "; $obj1->name = "Wzz"; echo $obj->name ." "; echo $obj1->name ." ";
//执行结果为
Ym
james
Ym
Wzz