PHP面向对象(二)
7 多态
多态: 多种形态
多态分俩种: 方法重写和方法加载
7.1 方法重写
子类重写了父类的同名的方法
<?php
class Person{
public function show(){
echo '这是父类<br>';
}
}
class Stu extends Person{
public function show(){
echo '这是子类<br>';
}
}
$stu=new Stu;
$stu->show();
?>
子类的方法必须和父类的方法同名
参数个数要一致
子类修饰不能比父类更加严格
7.2 方法重载
在同一个类中, 有多个同名的函数, 通过参数的不同来区分不同的方法.
PHP不支持方法重载, 但是PHP可以通过其他方法来模拟方法重载
<?php
class Stu{
public function show(){}
public function show($num){}
public function show($num1,$num2){}
}
?>
8 私有属性继承和重写
私有属性可以继承但不能重写
<?php
class A {
private $name='php';
public function showA(){
echo $this->name,'<br>';
}
}
class B extends A {
private $name='Java';
public function showB(){
echo $this->name;
}
}
$obj=new B();
$obj->showA();
$obj->showB();
?>
showA()和showB()中的$this
都表示B的对象, B中继承了A的私有属性,所以B中有两个$name
.
在showA()中只能访问A中的$name
,不能访问B中的$name
.
在showB()中只能访问B中的$name
, 不能访问A中的$name
.
<?php
class A {
protected $name='tom';
public function showA(){
echo $this->name,'<br>';
}
}
class B extends A {
public $name='berry';
public function showB(){
echo $this->name,'<br>';
}
}
$obj=new B();
$obj->showA();
$obj->showB();
?>
B中将A的$name
重写, 所以$obj
中只有一个$name
,($name
='berry
'), 不管$this
在哪个方法中访问,就只能访问这个$name
.
<?php
class A {
private $name='tom';
public function showA(){
echo $this->name,'<br>';
}
}
class B extends A {
public $name='berry';
public function showB(){
echo $this->name,'<br>';
}
}
$obj=new B();
$obj->showA();
$obj->showB();
?>
$obj
中有两个$name
, 一个是私有的,一个是公有的,
在showA()中既能访问私有的$name
,也能访问公有的$name
,但是私有的比公有的权限高, 所以输出tom.
在showB()中不能访问私有的$name
,只能访问公有的$name
,所以输出berry.
9 方法修饰符
方法修饰符有: static final abstract
9.1 static 静态
static修饰的属性叫静态属性, static修饰的方法叫静态方法
静态成员加载类的时候分配空间, 程序执行完毕后销毁
静态成员在内存中就一份
调用方法 类名::属性 类名::方法名()
<?php
class Person{
//修饰符之间没有顺序
public static $add='北京';
static public function show(){
echo '这是一个静态的方法<br>';
}
}
echo Person::$add,'<br>';
Person::show();
?>
9.1.1 统计在线人数
self表示所在类的类名, 使用self降低耦合性
<?php
class Stu{
private static $num=0;
function __construct(){
self::$num++;
}
function __destruct(){
self::$num--;
}
function show(){
echo '总人数是:'.self::$num,'<br>';
}
}
$stu1=new Stu;
$stu2=new Stu;
$stu3=new Stu;
$stu4=new Stu;
$stu5=new Stu;
$stu1->show();
unset($stu2);
unset($stu4);
$stu3->show();
?>
9.1.2 静态成员的继承
<?php
class Person{
public static $add='中国';
public static function show(){
echo '这是人类<br>';
}
}
class Stu extends Person{
}
echo Stu::$add,'<br>';
Stu::show();
?>
9.1.3 静态延时绑定
static 表示当前对象所属的类
<?php
class Person{
public static $type='人类';
public function show1() {
echo self::$type,'<br>'; //人类
echo static::$type,'<br>'; //学生 延时绑定
}
}
class Student extends Person {
public static $type='学生';
public function show2() {
echo self::$type,'<br>'; //学生
echo static::$type,'<br>'; //学生
}
}
$obj=new Student();
$obj->show1();
$obj->show2();
?>
9.1.4 总结
static在内存中就一份, 在类加载的时候分配空间
如果有多个修饰符, 修饰符之间是没有顺序的
self表示所在类的类名
static表示当前对象所属的类
static有两个作用, 第一表示静态, 第二表示类名
9.2 final 最终
final修饰的方法不能被重写
final修饰的类不能被继承
作用
如果一个类确认不被继承, 一个方法确定不会被重写,用final修饰可以提高执行效率.
如果一个方法不允许被其他类重写,可以用final修饰.
9.3 abstract 抽象
abstract修饰的方法是抽象方法, 修饰的类是抽象类
只有方法的声明, 没有方法的实现称为抽象方法
一个类中只要有一个方法是抽象方法, 这个类必须是抽象类
抽象类的特点是不能被实例化
子类继承了抽象类, 就必须重新实现父类的所有的抽象方法, 否则不允许实例化
类中没有抽象方法也可以声明为抽象类. 用来阻止类的实例化
<?php
//抽象类
abstract class Person{
//抽象方法
public abstract function setInfo();
public function getInfo(){
echo '获取信息<br>';
}
}
class Student extends Person {
//重写实现父类的抽象方法
public function setInfo() {
echo '重新实现父类的抽象方法<br>';
}
}
$stu=new Student;
$stu->setInfo(); //重新实现父类的抽象方法
$stu->getInfo(); //获取信息
?>
抽象类的作用
定义命名的规范
阻止实例化, 如果一个类中所有的方法都是静态方法,这时候没有必要去实例化,可以通过abstract来阻止来的实例化。
10 类常量 & 接口
10.1 类常量
类常量是const常量
<?php
class Stu{
const add='地址不详';
//7.1版本后支持修饰符
// public const add='地址不详';
}
echo Stu::add;
?>
define常量和conset常量区别
const常量可以做类成员, define常量不可以做类成员
常量和静态的属性的区别
相同点: 都在加载类的时候分配空间
不同的: 常量的值不可以更改, 静态属性的值可以更改
10.2 接口
如果一个类中所有的方法都是抽象方法, 那么这个抽象类可以声明成接口
接口是一个特殊的抽象类, 接口中只能有抽象方法和常量
接口中的抽象方法只能是public, 可以省略, 默认是public
通过implements关键字来实现接口
不能使用abstract和final来修饰接口中的抽象方法
<?php
//声明接口
interface IPerson{
const ADD='中国';
function fun1();
function fun2();
}
//接口实现
class Stu implements IPerson{
public function fun1(){
}
public function fun2(){
}
}
// 访问接口中的常量
echo IPerson::ADD;
?>
10.3 接口的多重实现
类不允许多重继承, 但是接口允许多重实现.
<?php
interface IPic1{
function fun1();
}
interface IPic2{
function fun2();
}
class Stu implements IPic1,IPic2{
public function fun1(){}
public function fun2(){}
}
?>
在接口的多重实现中, 如果有同名的方法, 只要实现一次即可
类可以继承的同时实现接口
class Student extends Person implements IPIc1,IPic2{}
11 匿名 & 方法绑定
11.1 匿名
PHP7.0 以上支持
<?php
$stu=new class{
public $name='tom';
public function __construct(){
echo '构造函数<br>';
}
};
echo $stu->name;
?>
如果类只被实例化一次就可以使用匿名类
好处, 在执行过程中, 类不占用空间
11.2 方法绑定
PHP7.0 以上支持
将方法绑定到对象上, 并调用
闭包->call(对象):
在PHP中匿名函数称为闭包
<?php
$lang='en';
//类
class Stu{
}
//匿名函数
if($lang=='ch'){
$fun=function(){
echo '我是一名学生';
};
}else{
$fun=function(){
echo 'I am a student';
};
}
//绑定
$stu=new Stu;
$fun->call($stu);
?>
12 异常处理
集中处理在代码块中发生的异常
在代码块中发生了异常直接抛出, 代码块不处理异常, 将异常集中起来一起处理.
12.2 关键字
try: 监测代码块
catch: 捕获异常
throw: 抛出异常
finally: 无论有无异常都会执行,可以省略
Exception: 异常类
语法结构
try{
//检测代码
}catch(Exception $ex){
//捕获异常
}
finally{
//不论是否有异常, 都要执行, finally可以省略
}
抛出异常后, try块终止执行, 执行权限交给catch块
<?php
if (isset($_POST['button'])) {
try{
$age=$_POST['age'];
if($age=='')
// 抛出异常
throw new Exception('年龄不能为空',1000);
if(!is_numeric($age))
throw new Exception("年龄必须是数字", 1001);
if(!($age>10 && $age<=30))
throw new Exception('年龄必须在10~30之间', 1002);
echo '您的年龄合适';
}catch(Exception $ex){ //捕获异常
echo '错误信息:'.$ex->getMessage(),'<br>';
echo '错误码:'.$ex->getCode(),'<br>';
echo '文件地址:'.$ex->getFile(),'<br>';
echo '错误行号:'.$ex->getLine(),'<br>';
}
finally{//不管是否有异常,finally都要执行
echo '关闭数据库连接';
}
}
?>
<form method="post" action="">
年龄: <input type="text" name="age"><br>
<input type="submit" name="button" value="提交">
</form>
12.3 自定义异常
场景: 如何实现异常的分类处理? 比如异常有三个级别异常对应三种处理方式
自定义三种异常即可
所有异常类的父类是Exception, Exception中的方法不允许重写
<?php
//自定义空异常类
class MyNullException extends Exception {
}
//自定义类型异常
class MyTypeException extends Exception {
}
//自定义范围异常
class MyRangeException extends Exception {
}
//逻辑代码
if(isset($_POST['button'])) {
try{
$name=$_POST['name'];
$age=$_POST['age'];
if($name=='')
throw new MyNullException('姓名不能为空');
if($age=='')
throw new MyNullException('年龄不能为空');
if(!is_numeric($age))
throw new MyTypeException('年龄不是数字');
if($age<10 || $age>30)
throw new MyRangeException('年龄必须在10-30之间');
echo '姓名:'.$name,'<br>';
echo '年龄:'.$age;
}catch(MyNullException $ex){
echo $ex->getMessage(),'<br>';
echo '错误记录在日志中';
}catch(MyTypeException $ex){
echo $ex->getMessage(),'<br>';
echo '发送电子邮件';
}catch(MyRangeException $ex){
echo $ex->getMessage(),'<br>';
echo '给管理员打电话';
}
}
?>
<form method="post" action="">
姓名: <input type="text" name="name"> <br />
年龄: <input type="text" name="age"> <br />
<input type="submit" name="button" value="提交">
</form>
PHP面向对象(二)的更多相关文章
- 2. 星际争霸之php面向对象(二)
题记==============================================================================本php设计模式专辑来源于博客(jymo ...
- Javascript面向对象二
Javascript面向对象二 可以通过指定原型属性来对所有的对象指定属性, Object.prototype.name="zhangsan"; Object.prototype. ...
- python面向对象二
1.1类的静态属性,类方法,类的静态方法 1.1.1静态属性(@property) 在类中: python内置的@property装饰器就是负责把一个方法(函数)变成属性来调用. class Stud ...
- canvas学习和面向对象(二)
Canvas 学习(二) 上一篇Canvas 学习(一)中我是用canvas绘制了一些基本和组合的图形. 现在开始绘制图片和动画帧,以及面向对象的升级版本. 还是一样,看代码,所有的代码都托管在git ...
- JavaScript 面向对象(二) —— 案例篇
看案例前可以先看看基础篇:JavaScript 面向对象(一) —— 基础篇 案例——面向对象的选项卡:把面向过程的程序一步步改成面向对象的形式,使其能够更加的通用(但是通用的东西,一般会比较臃肿). ...
- JavaScript面向对象(二)——成员属性、静态属性、原型属性与JS原型链
前 言 JRedu 上一篇博客中,我们介绍了JS中的面向对象,并详细的解释了this的指向问题.本篇博客,我们继续来学习JS的面向对象.来深入理解一下JavaScript OOP中的成员属性/方 ...
- 第八章:Python基础の面向对象(二)
本課主題 面向对象的多态 面向对象的成员 成员修饰符 特殊成员 面向对象其他应用 异常处理 设计模式与单例模式 面向对象的多态 指定参数类型只是多态的一种表现 另外一种是允许自己类型和自己的子类型(典 ...
- Python之面向对象二
面向对象的三大特性: 继承 继承是一种创建新类的方式,在python中,新建的类可以继承一个或多个父类,父类又可称为基类或超类,新建的类称为派生类或子类 python中类的继承分为:单继承和多继承 c ...
- Python自动化开发 - 面向对象(二)
本节内容 1.isinstance(obj,cls)和issubclass(sub,super) 2.反射 3.__setattr__,__delattr__,__getattr__ 一. isins ...
- python 面向对象二 类和实例
一.类和实例 面向对象最重要的概念就是类(Class)和实例(Instance),必须牢记类是抽象的模板,比如Student类,而实例是根据类创建出来的一个个具体的“对象”,每个对象都拥有相同的方法, ...
随机推荐
- 一个使用命令行编译Android项目的工具类
一个使用命令行编译Android项目的工具类 简单介绍 编译apk项目须要使用的几个工具,基本都在sdk中,它们各自是(Windows系统): 1.aapt.exe 资源打包工具 2.android. ...
- 9517 Link Link Look
9517 Link Link Look 该题有题解 时间限制:2000MS 内存限制:65535K提交次数:67 通过次数:18 题型: 编程题 语言: G++;GCC Description ...
- Storm集群组件和编程模型
Storm工作原理: Storm是一个开源的分布式实时计算系统,常被称为流式计算框架.什么是流式计算呢?通俗来讲,流式计算顾名思义:数据流源源不断的来,一边来,一边计算结果,再进入下一个流. 比 ...
- hdu 5411 CRB and Puzzle 矩阵高速幂
链接 题解链接:http://www.cygmasot.com/index.php/2015/08/20/hdu_5411/ 给定n个点 常数m 以下n行第i行第一个数字表示i点的出边数.后面给出这些 ...
- cdev_init和register_chrdev区别
--- 01:include/linux/fs.h static inline int register_chrdev(unsigned int major, const char *name, co ...
- Linux - Nginx的集群与负载均衡
Nginx的集群与负载均衡 集群就是一群人干同样的活,负载均衡就是保证每个人都干得差不多.或者大人干得多一些,小孩干得少一些. Nginx实现负载均衡很方便. 准备三台服务器,一台是用于访问图片(66 ...
- Find a way--hdoj
Find a way Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total ...
- 【BZOJ3218】【UOJ#77】a + b Problem
题目 题目在这里 思路&做法 明显的最小割(其实是之前做过一道类似的题) S向每一个格子连容量为\(b_i\)的边 每一个格子向T连容量为\(w_i\)的边 对于格子\(i\)向满足条件的格子 ...
- 【读书笔记】UEFI原理与编程(1)概述及开发环境的搭建
一.概述: 0.为什么会有这篇文章 说实在的,在2016初的时候,我就萌生了写一个操作系统的念头,但是这对于我一个菜鸟来说,犹如登天. 既然想了就去写,即使最后做不完,也不后悔. 抱着这样的念头,我开 ...
- listview 控件
private void Form1_Load(object sender, EventArgs e) { //设置该listview关联的imagelist listView1.LargeImage ...