PHP与MySQL程序设计 学习笔记 第六章 面向对象的PHP

本文主要是介绍PHP与MySQL程序设计 学习笔记 第六章 面向对象的PHP,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

封装将接口与内部实现分离。

继承使派生出来的类拥有基类的所有属性和方法。

多态使继承出来的类可重写基类的某些方法,使得可以根据类的上下文选择特定的属性和方法。

创建类:

class Employee {private $name;private $title;protected $wage;protected function clockIn() {echo "Member $this->name clocked in at " . date("h:i:s");}protected function clockOut() {echo "Member $this->name clocked out at " . date("h:i:s");}
}

根据预定义的类创建对象常被称为类的实例化:

$employee = new Employee();

类的属性可以不声明:

class a { }
$aObj = new a();
$aObj->member1 = 5;
var_dump($aObj);

运行它:
在这里插入图片描述
但最好在类中声明属性。

获取对象中属性:

$employee->name;    // 获取name成员的值

在类中调用属性:

// 为employee类定义新方法
function setName($name) {$this->name = $name;    // 引用当前类中属性时要使用$this
}

属性作用域:
1.public:可由相应的对象直接操作和访问。
2.private:只能在定义该属性的类中被访问。
3.protected:可在定义该属性的类及其派生类中被访问。
4.final:派生类中不能覆盖此属性。也可用于方法。但我用php 7测试时会报错final不能用于属性。

class a {public $v = 8;
}class b extends a {public $v = 5;
}$bObj = new b();
var_dump($bObj);

运行它:
在这里插入图片描述

class a {private $v = 8;public function basefunc() {$this->v = 2;}
}class b extends a {public $v = 5;public function func() {$this->v = 3;}
}$bObj = new b();
print_r($bObj);
$bObj->func();
print_r($bObj);
$bObj->basefunc();
print_r($bObj);

运行它:
在这里插入图片描述
由上图,如果派生类中的public属性覆盖了基类中的public属性,则基类中的public属性不再存在;如果覆盖的是基类中的private属性,则会有两个同名属性,一个是public的,一个是private的,在派生类中访问的是派生类的public属性,在基类中访问的是基类中的private属性。如果派生类中的同名属性是protected的,则结果相同,也会出现两个同名属性,且派生类中访问的是派生类中的protected属性,基类中访问的是基类的private属性。

派生类在覆盖基类中的同名属性时,访问权限必须更大,不能缩小:

class a {public $v = 8;
}class b extends a {private $v = 5;
}

运行它:
在这里插入图片描述
当基类中的属性v是protected的时,也会报类似的错误,要求派生类中的同名属性的访问权限要与基类中的同名属性的访问权限相同。

当对类中不存在的属性赋值时,会调用:
在这里插入图片描述
它接受一个属性名和其值作为输入。

class a {public $v = 2;public function __set($propName, $propValue) {print("Nonexistent variable $propName." . PHP_EOL);}
}$aObj = new a();
$aObj->v = 4;
$aObj->v1 = 3;
print_r($aObj);

运行它:
在这里插入图片描述

也可通过此方法扩展类:

class a {public $v = 2;public function __set($propName, $propValue) {$this->$propName = $propValue;}
}$aObj = new a();
$aObj->v = 3;
$aObj->v1 = 4;
var_dump($aObj);

运行它:
在这里插入图片描述
当__set方法未定义时对不存在的属性赋值时,效果同上。

当访问一个不存在的属性时会调用:
在这里插入图片描述

class a {public $v = 2;public function __get($propName) {print("in __get");print("Nonexistant variable $propName.");}
}$aObj = new a();
print($aObj->v . PHP_EOL);
print($aObj->v1);

运行它:
在这里插入图片描述
当__get方法未定义时访问不存在的属性会报错找不到该属性:

class a {public $v = 2;
}$aObj = new a();
print($aObj->v . PHP_EOL);
print($aObj->v1);

运行它:
在这里插入图片描述

类中可定义常量,常量在对象的整个生命周期中都保持不变。

常量的定义和使用:

class a { const PI = 3.14159;
}$aObj = new a();
print($aObj::PI);

声明方法:

scope function funcName(parameters) { }

public方法不必显式声明作用域。

调用方法:

$obj->funcName(arguments);

方法作用域:
1.public:可在任何时间地点访问。书上演示:
在这里插入图片描述
但我用php 7测试时发现非static的方法必须通过对象调用,否则报错这是被弃用的特性,报错后是正常的输出,可通过修改error_reporting的错误报告等级消除警告。
2.private:只能在类的内部使用。
3.protected:只能在类中或该类的派生类中使用。
4.abstract:在父类中声明,在子类中实现。只有声明为abstruct的类可声明抽象方法:

abstract class a {     // 定义抽象方法的类必须也是抽象类abstract public function func();
}class b extends a {private function func() { }    // 错误,实现时访问级别也必须是public
}

5.final:可防止被子类覆盖:

class a { final public function func() { }
}class b extends a {public function func() { }    // 报错,无法重写方法
}

类型提示是php 5新特性,可确保传递给方法的对象类型是期望类型。php 5的类型提示只用于类类型和数组类型,无法为整数、浮点数、字符串提供类型提示。而php 7的类型提示可扩展至标量数据类型:

class a { }function func(a $aObj) { }func(1);    // 报错

构造函数名为__constructor,但在php 4时,构造函数名字与类名相同,为了兼容,在现在的php版本中如果找不到名为__constructor的构造函数,则会接着寻找与类同名的函数,如果找到了,会将其认为是构造函数:

class a { public function a() {print("in constructor");}
}$aObj = new a();

运行它:
在这里插入图片描述
php不会自动调用父类的构造函数,必须在子类中显式调用:

class a { public function __construct() {print("in parent's constructor\n");}
}class b extends a {public function __construct() {parent::__construct();    // 也可以改为a::__construct()print("in child's constructor");}
}$bObj = new b();

运行它:
在这里插入图片描述
如果没有显式调用父类的构造函数,则第一句输出不会被输出。

书上说即使两个类没有继承层次关系,也能在一个类的构造函数中使用另一个类的构造函数,但我用php 7测试:

class a { public function __construct() {print("in parent's constructor\n");}public $va = 1;
}class b {public function __construct() {a::__construct();    // 会报错print("in child's constructor\n");}public $vb = 2;
}$bObj = new b();    

脚本执行结束时,php会撤销内存中所有对象,此时会调用对象的析构函数:

class a {public function __construct() {print("in constructor" . PHP_EOL);}public function __destruct() {print("in destructor" . PHP_EOL);}
}$aObj = new a();

运行它:
在这里插入图片描述

静态成员不属于对象,属于该对象所属的类:

class Vistor {public static $Visitors = 0;public function __construct() {++self::$Visitors;}public static function getVisitors() {return self::$Visitors;}
}$aVistor = new Vistor();print(Vistor::getVisitors() . "\n");    // 通过类名访问静态方法
print($aVistor::getVisitors());    // 通过对象名访问静态方法
print(Vistor->getVisitors() . "\n");    // 错误,类名没有->运算符
print($aVistor->getVisitors() . "\n");    // 正确,可通过对象->访问静态方法print(Vistor::$Visitors . "\n");    // 通过类名访问静态属性
print($aVistor::$Visitors . "\n");    // 通过对象名访问静态属性
print(Vistor->$Visitors . "\n");    // 错误,类名没有->运算符
print($aVistor->$Visitors);    // 错误,报错该对象不存在$Visitors属性

总结:
1.静态属性和静态方法都可以通过::来访问;
2.类名只能通过::访问静态对象;
3.静态方法可通过类名或对象名访问,而静态属性只能通过类名访问;
4.静态方法也可通过对象名->静态方法名访问。

最好在编写代码时在类外使用静态成员都通过类名::静态成员来访问,在类内最好使用self::静态成员来访问,这样比较清晰。

php 5引入了instanceof关键字,可确定一个对象是否是一个类的实例:

class a { }$aObj = new a();if ($aObj instanceof a) {print("1");    // 会被输出
}

派生类对象是基类的实例:

class a { }class b extends a { }$aObj = new a();
$bObj = new b();if ($bObj instanceof a) {print("1");    // 会输出
}if ($aObj instanceof b) {print("2");    // 不会输出
}

php 5.3新增了创建类别名的函数:

class a { }class_alias("a", "b");$bObj = new b();if ($bObj instanceof a) {print("1");    // 会被输出
}

确定一个类是否存在:

class a { }if (class_exists("a")) {print("1");    // 会被输出
}

返回一个对象所属的类名,如果它不是类的对象则返回false:

class a { }$aObj = new a();
$aInt = 1;$objName1 = get_class($aObj);
$objName2 = get_class($aInt);if ($objName1) {print($objName1 . "\n");
} else  {print("not a obj\n");
}if ($objName2) {print($objName2);
} else  {print("not a obj");
}

运行它:
在这里插入图片描述
返回类中包含的所有public方法名:

class a {public $v = 4;public function pubFunc() { }protected function proFunc() { }private function priFunc() { }
}print_r(get_class_methods("a"));

运行它:
在这里插入图片描述

返回类中定义的public属性:

class a {public $v = 4;public $v1;protected $v2;private $v3;public function func() { }
}print_r(get_class_vars("a"));

运行它:
在这里插入图片描述
返回当前脚本中定义的所有类名,返回值根据php发行包不同而不同:

class a { }print_r(get_declared_classes());

运行它:
在这里插入图片描述
自定义的类名在最后输出。

返回对象的所有public属性:

class a {public $v = 4;public $v1;protected $v2;private $v3;
}$aObj = new a();
$aObj->v4 = 5;print_r(get_object_vars($aObj));

运行它:
在这里插入图片描述

确定对象所属的父类,如果参数为字符串,则返回该字符串表示的类的父类:

class a { }class b extends a { }$bObj = new b();print(get_parent_class("b") . "\n");
print(get_parent_class($bObj));

运行它:
在这里插入图片描述
确定一个接口是否存在:

interface a { }if (interface_exists("a")) {print("1\n");
} if (!interface_exists("b")) {print("2");
}

运行它:
在这里插入图片描述
如果一个对象属于一个类或该类的子类时,返回true,否则返回false的函数:

class a { }class b extends a { }$bObj = new b();if (is_a($bObj, "b")) {print("1\n");
}if (is_a($bObj, "a")) {print("2");
}

运行它:
在这里插入图片描述
php 5.0.0到5.3.0中删除了此函数,使得遇到此函数时显示一个E_STRICT警告。

当对象是一个类的子类对象时,以下函数返回true:

class a { }class b extends a { }$bObj = new b();if (is_subclass_of($bObj, "a")) {print("1\n");    // 会被输出
}if (is_subclass_of($bObj, "b")) {print("2");
} else {print("3");    // 会被输出
}

确定一个对象中是否有某方法;

class a { public function func() { }
}$aObj = new a();if (method_exists($aObj, "func")) {print("1");    // 会输出
}if (method_exists($aObj, "__construct")) {print("1");    // 不会输出
}

php 5引入了自动加载对象,允许通过定义__autoload函数自动加载类,当引用未在脚本中定义的类时会自动调用该函数:

./myClass.php
<?php
class myClass {public function __construct() {echo "myClass init'ed successfuly!!!";}
}
?>./index.php
<?php
// we have writen this code where we need 
function __autoload($classname) {$filename = "./". $classname .".php";include_once($filename);
}// we've called a class ***
$obj = new myClass();

该方法已在php 7.2.0中废除,不要使用它。

final类不能作为基类:

final class a { }class b extends a{ }

运行它:
在这里插入图片描述

这篇关于PHP与MySQL程序设计 学习笔记 第六章 面向对象的PHP的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/940687

相关文章

LLM 大模型学习必知必会系列(一):大模型基础知识篇

LLM 大模型学习必知必会系列(一):大模型基础知识篇 魔搭 ModelScope 开源的 LLM 模型 魔搭 ModelScope 欢迎各个开源的 LLM 模型在社区上做开源分享。目前社区上已经承载了来自各个机构贡献的不同系列的 LLM 模型。并且社区的开发者也在这些模型的基础上,贡献了许多创新应用,并在 ModelScope 的创空间上进行分享。本专题初步梳理了当前社区上一些典型的 LLM

从零开始!学习绘制3D表情的详细指南

在2020 年的苹果全球开发者大会(WWDC),苹果发布了新的 macOS 11(又名 Big Sur)。其中在UI视觉方面macOS Big Sur 系统最大的变化就是图标上, Big Sur更新了很多新设计风格的 3D应用图标,3D设计的确可以提升UI整体的视觉氛围,并且现在在一些APP中已经可以看到小范围3D案例。 表情符号成为生活中丰富情感的必要交流工具。用表情符号,几个像素就能以有趣、

算法学习008-登山爬石梯 c++动态规划/递归算法实现 中小学算法思维学习 信奥算法解析

目录 C++登山爬石梯 一、题目要求 1、编程实现 2、输入输出 二、算法分析 三、程序编写 四、程序说明 五、运行结果 六、考点分析 七、推荐资料 C++登山爬石梯 一、题目要求 1、编程实现 小明周末和朋友约好了一起去爬山,来到山下,发现登山道是由石头铺成,每一段会有向上铺的石阶,然后是一段平路,如此反复,直到山顶。刚好最近在学c++编程,就想到小兔子老

JAVA学习日记初涉SWING

在读完SWING 这章后,自己交的作业 具体实现以上布局 ,练习了一些SWING语句 以下代码: import java.awt.*; import javax.swing.*; import java.awt.event.*; public class MyDialog extends JFrame { public MyDialog(){     String

java 内部类笔记

一般情况下,类和类之间是相互独立的关系,内部类的意思是打破这种独立,让一个类成为另外一个类的内部成员,和成员变量、成员方法同等级别。 内部类的种类: 1.1 非静态内部类 非静态内部类的使用,就是将内部类作为外部类的一个成员变量/成员方法来使用。所以必须依赖于外部类的对象才能调用,用法和成员变量/成员方法一致的。 package test;public class OuterClass {/

Pytorch入门—Tensors张量的学习

Tensors张量的学习 张量是一种特殊的数据结构,与数组和矩阵非常相似。在PyTorch中,我们使用张量来编码模型的输入和输出,以及模型的参数。 张量类似于NumPy的ndarrays,只是张量可以在GPU或其他硬件加速器上运行。事实上,张量和NumPy数组通常可以共享相同的底层内存,从而无需复制数据(请参阅使用NumPy进行桥接)。张量还针对自动微分进行了优化(我们将在稍后的Autogra

【基于 PyTorch 的 Python深度学习】5 机器学习基础(2)

前言 文章性质:学习笔记 📖 学习资料:吴茂贵《 Python 深度学习基于 PyTorch ( 第 2 版 ) 》【ISBN】978-7-111-71880-2 主要内容:根据学习资料撰写的学习笔记,该篇主要介绍了如何选择合适的激活函数、损失函数和优化器。 一、选择合适的激活函数 激活函数 在神经网络中的作用有很多,主要作用是给神经网络提供 非线性建模能力 。如果没有激活函数,

预编码算法学习笔记要点

文章目录 1. 线性预编码2. 非线性预编码3. 实现考虑4. 学习建议5. 预编码设计的挑战与对策挑战:对策: 6. 预编码在未来通信系统中的趋势7. 实际应用中的案例分析5G网络中的应用Wi-Fi 6E/Wi-Fi 7卫星通信车联网(V2X) 8. 性能评估与优化9. 结论 预编码应用案例 预编码(Pre-coding)算法,尤其是在通信领域,特别是无线通信中,是一种重要的信号

Mysql进阶-索引篇

Mysql进阶 存储引擎前言特点对比 索引介绍常见的索引结构索引分类索引语法sql分析索引使用原则索引失效的几种情况sql提示覆盖索引前缀索引索引设计原则 存储引擎 前言 Mysql的体系结构: 连接层 最上层是一些客户端和链接服务,主要完成一些类似于连接处理、授权认证、及相关的安全方案。服务器也会为安全接入的每个客户端验证它所具有的操作权限。服务层 第二层架构主要完成大

Python爬虫基础知识学习(以爬取某二手房数据、某博数据与某红薯(书)评论数据为例)

一、爬虫基础流程 爬虫的过程模块化,基本上可以归纳为以下几个步骤:1、分析网页URL:打开你想要爬取数据的网站,然后寻找真实的页面数据URL地址;2、请求网页数据:模拟请求网页数据,这里我们介绍requests库的使用;3、解析网页数据:根据请求获得的网页数据我们用不同的方式解析成我们需要用的数据(如果网页数据为html源码,我们用Beautiful Soup、xpath和re正则表达式三