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();
?>
  1. 子类的方法必须和父类的方法同名

  2. 参数个数要一致

  3. 子类修饰不能比父类更加严格

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 静态

  1. static修饰的属性叫静态属性, static修饰的方法叫静态方法

  2. 静态成员加载类的时候分配空间, 程序执行完毕后销毁

  3. 静态成员在内存中就一份

  4. 调用方法 类名::属性 类名::方法名()

<?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 总结
  1. static在内存中就一份, 在类加载的时候分配空间

  2. 如果有多个修饰符, 修饰符之间是没有顺序的

  3. self表示所在类的类名

  4. static表示当前对象所属的类

  5. static有两个作用, 第一表示静态, 第二表示类名

9.2 final 最终

final修饰的方法不能被重写

final修饰的类不能被继承

作用

如果一个类确认不被继承, 一个方法确定不会被重写,用final修饰可以提高执行效率.

如果一个方法不允许被其他类重写,可以用final修饰.

9.3 abstract 抽象

  1. abstract修饰的方法是抽象方法, 修饰的类是抽象类

  2. 只有方法的声明, 没有方法的实现称为抽象方法

  3. 一个类中只要有一个方法是抽象方法, 这个类必须是抽象类

  4. 抽象类的特点是不能被实例化

  5. 子类继承了抽象类, 就必须重新实现父类的所有的抽象方法, 否则不允许实例化

  6. 类中没有抽象方法也可以声明为抽象类. 用来阻止类的实例化


<?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(); //获取信息
?>

抽象类的作用

  1. 定义命名的规范

  2. 阻止实例化, 如果一个类中所有的方法都是静态方法,这时候没有必要去实例化,可以通过abstract来阻止来的实例化。

10 类常量 & 接口

10.1 类常量

类常量是const常量


<?php
class Stu{
const add='地址不详';
//7.1版本后支持修饰符
// public const add='地址不详';
}
echo Stu::add;
?>

define常量和conset常量区别

const常量可以做类成员, define常量不可以做类成员

常量和静态的属性的区别

相同点: 都在加载类的时候分配空间

不同的: 常量的值不可以更改, 静态属性的值可以更改

10.2 接口

  1. 如果一个类中所有的方法都是抽象方法, 那么这个抽象类可以声明成接口

  2. 接口是一个特殊的抽象类, 接口中只能有抽象方法和常量

  3. 接口中的抽象方法只能是public, 可以省略, 默认是public

  4. 通过implements关键字来实现接口

  5. 不能使用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(){}
}
?>
  1. 在接口的多重实现中, 如果有同名的方法, 只要实现一次即可

  2. 类可以继承的同时实现接口


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面向对象(二)的更多相关文章

  1. 2. 星际争霸之php面向对象(二)

    题记==============================================================================本php设计模式专辑来源于博客(jymo ...

  2. Javascript面向对象二

    Javascript面向对象二 可以通过指定原型属性来对所有的对象指定属性, Object.prototype.name="zhangsan"; Object.prototype. ...

  3. python面向对象二

    1.1类的静态属性,类方法,类的静态方法 1.1.1静态属性(@property) 在类中: python内置的@property装饰器就是负责把一个方法(函数)变成属性来调用. class Stud ...

  4. canvas学习和面向对象(二)

    Canvas 学习(二) 上一篇Canvas 学习(一)中我是用canvas绘制了一些基本和组合的图形. 现在开始绘制图片和动画帧,以及面向对象的升级版本. 还是一样,看代码,所有的代码都托管在git ...

  5. JavaScript 面向对象(二) —— 案例篇

    看案例前可以先看看基础篇:JavaScript 面向对象(一) —— 基础篇 案例——面向对象的选项卡:把面向过程的程序一步步改成面向对象的形式,使其能够更加的通用(但是通用的东西,一般会比较臃肿). ...

  6. JavaScript面向对象(二)——成员属性、静态属性、原型属性与JS原型链

      前  言 JRedu 上一篇博客中,我们介绍了JS中的面向对象,并详细的解释了this的指向问题.本篇博客,我们继续来学习JS的面向对象.来深入理解一下JavaScript OOP中的成员属性/方 ...

  7. 第八章:Python基础の面向对象(二)

    本課主題 面向对象的多态 面向对象的成员 成员修饰符 特殊成员 面向对象其他应用 异常处理 设计模式与单例模式 面向对象的多态 指定参数类型只是多态的一种表现 另外一种是允许自己类型和自己的子类型(典 ...

  8. Python之面向对象二

    面向对象的三大特性: 继承 继承是一种创建新类的方式,在python中,新建的类可以继承一个或多个父类,父类又可称为基类或超类,新建的类称为派生类或子类 python中类的继承分为:单继承和多继承 c ...

  9. Python自动化开发 - 面向对象(二)

    本节内容 1.isinstance(obj,cls)和issubclass(sub,super) 2.反射 3.__setattr__,__delattr__,__getattr__ 一. isins ...

  10. python 面向对象二 类和实例

    一.类和实例 面向对象最重要的概念就是类(Class)和实例(Instance),必须牢记类是抽象的模板,比如Student类,而实例是根据类创建出来的一个个具体的“对象”,每个对象都拥有相同的方法, ...

随机推荐

  1. T2: 一种能累积计算积分的EC2实例类型

    假设您打算在AWS云端执行一个小型的 Web Server,或是一个小型的数据库,平时并没有大量的工作负载.在绝大多数时间里,您的实例并不须要消耗大量的CPU资源.可是,再不怎么受欢迎的博客也可能会有 ...

  2. 8 Reasons why SharePoint is Bad for Your Business 8个理由告诉你,为什么SharePoint对你的业务有害

    8 Reasons why SharePoint is Bad for Your Business 8个理由告诉你,为什么SharePoint对你的业务有害         SharePoint近期已 ...

  3. Java封装FushionCharts

    近期公司接了个关于数据统计的系统.须要用到报表功能.找了几天认为还是FushionCharts 适合.所以就对FushionCharts进行了java代码封装,方便,前台,后台调用. 1.报表Mode ...

  4. Intel Media SDK安装步骤

    !!!(gcc/g++版本要在4.8以上,本人使用的是5.4版本) 要先安装依赖,按以下步骤依次执行 1.LIBVA git clone https://github.com/intel/libva. ...

  5. Android4.0.4-在build.prop中添加属性的方法【转】

    本文转载自:http://blog.csdn.net/imyfriend/article/details/8939964 1.在*.rc文件中用setprop添加,例如在源码android4.0\sy ...

  6. linux下udev简介【转】

    本文转载自:http://blog.csdn.net/skyflying2012/article/details/9364555 一.关于Udev u即user space,dev是device,通过 ...

  7. Linux - vim的基本使用

    通过which指令来查看文件位置! [root@local ~]# which vim /usr/bin/vim [root@local ~]# which vi /usr/bin/vi [root@ ...

  8. android 学习记录-----------android 活动 意图 碎片

    将此篇博客作为记录android项目开发过程中的学习记录

  9. 2015 多校赛 第一场 1002 (hdu 5289)

    Description Tom owns a company and he is the boss. There are n staffs which are numbered from 1 to n ...

  10. C - Insomnia cure

    Problem description «One dragon. Two dragon. Three dragon», — the princess was counting. She had tro ...