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类,而实例是根据类创建出来的一个个具体的“对象”,每个对象都拥有相同的方法, ...
随机推荐
- ural 1005 Stone Pile
这是道01背包题 ,尽管背包不会 ,可是还是看出来了,递推公式写啊写没写出来,后来一同学说是dfs.这我就開始了A了, 题意是给你n个重量是Wn的石头 让你放到两个包里面.看他们两个差值最小, ...
- JavaScript中bind、call、apply函数使用方法具体解释
在给我们项目组的其它程序介绍 js 的时候,我准备了非常多的内容,但看起来效果不大,果然光讲还是不行的,必须动手. 前几天有人问我关于代码里 call() 函数的使用方法.我让他去看书,这里推荐用js ...
- Libgdx: android单机斗地主支持局域网wifi联网的网络模块核心代码
这个作品是我近期写的,结合我的毕业设计的通信模块和之前的单机版斗地主.我已经上架到豌豆荚了,贴了点广告,看看能不能赚点茶钱. 但是一点也不乐观.因此我想分享给大家源代码. 仅仅要不用于商业. 以下先贴 ...
- '无法将“vue”项识别为 cmdlet、函数、脚本文件或可运行程序的名称' 或 'vue不是内部或外部命令' 的解决方法
如果在使用 vue 初始化项目的时候提示: vue : 无法将“vue”项识别为 cmdlet.函数.脚本文件或可运行程序的名称.请检查名称的拼写,如果包括路径,请确保路径正确,然后再试一次. 或者: ...
- Centos安装FastDFS+Nginx
一.安装环境: gcc:安装nginx需要先将官网下载的源码进行编译,编译依赖gcc环境,如果没有gcc环境,需要安装gcc: yum install gcc-c++ PCRE:PCRE(Perl C ...
- P1025小飞侠的游园方案
描述 经过抽签选择,小智将军第一个进入考场. 菜虫:(身上散射出华贵(?)的光芒)欢迎你,第一位挑战者!! 小智:……(走到菜虫身后,关灯)女王陛下,虽然我们国家现在很富裕,但也请您不要浪费电来用这么 ...
- java javax.annotation.Resource注解的详解
转自:https://www.jb51.net/article/95456.htm java 注解:java javax.annotation.Resource 当我们在xml里面为类配置注入对象时 ...
- new一个接口
首先我们先看看接口的定义: 接口(英文:Interface),在JAVA编程语言中是一个抽象类型,是抽象方法的集合,接口通常以interface来声明.一个类通过继承接口的方式,从而来继承接口的抽象方 ...
- VirtualBox 5.1.14 获取VirtualBox COM对象错误
Oracle VM VirtualBox 5.1.14 安装完成之后显示错误, Failed to instantiate CLSID_VirtualBox w/ IVirtualBox, but C ...
- JqGrid saveRow方法报404错误
TCX_1807工艺配置/检测项配置页面为jqgrid可编辑页面,使用的脚本为 ){ jQuery('#gridList').saveRow(lastId, true);//保存上一个修改的单元行 } ...