PHP面向对象的学习(封装,继承,多态)
这个文章就是记录 巩固一下PHP的面向对象的部分 ,无非就是封装,继承,多态等等这几部分
这里参考了一位大佬总结的文章:https://www.cnblogs.com/adaia/p/6986576.html 十分感谢
首先面向对象的思想需要明白,类和方法(也就是函数)的定义也需要弄清楚,什么是对象?什么是类?
1、什么是类?
具有相同属性(特征)和方法(行为)的一系列个体的集合,类是一个抽象的概念
2、什么是对象?
从类中拿到的具有具体属性值得个体,称为对象,对象是一个具体的个体 所以,面向对象即我们专注对象来处理问题,通过从一个个具有属性和功能的类中拿到对象来处理问题。
0、继承
在PHP中我们主要通过Extends关键字来实现继承 ->class Student extends Person { }
下面是几个比较重要的注意事项:
①子类只能继承父类的非私有属性。
②子类继承父类后,相当于将父类的属性和方法copy到子类,可以直接使用$this调用该属性;
③PHP只能单继承,不支持一个类继承多个类。但是一个类可以进行多层继承(即A继承于B,而C又继承于A,C通过A间接继承了B)
一、封装
类实现封装是为了不让外面的类随意的修改一个类的成员变量,所以在定义一个类的成员的时候,我们使用private关键字设置这个成员的访问权限
只能被这个类的其他成员方法调用,而不能被其他类中的方法调用,即通过本类中提供的方法来访问本类中的私有属性。
①所以在该类中我们会提供一个访问私有属性的方法
②然后我们一般会定义两个方法来实现对一个变量的操作,即:get()与set()方法。
class Person{
private $name;
private $age; public function __construct($name,$age){ //__construct称之为构造函数 定义:在对象实例化的时候会自动执行一段代码 说白了就是自动给对象附上一些值
$this->name = $name;
$this->age = $age;
}
function setAge($age){
if($age>=0&&$age<=120){
$this->age = $age;
}else{
error_log("年龄设置有误!");
}
} function getAge(){
return $this->age;
}
public function say(){
echo "我叫{$this->name},我今年{$this->age}岁了"; //private声明的变量在这个类的其他方法里调用的格式就是 $this->xxx
} function __get($name){
switch ($name) {
case 'name':
return $this ->$name."这是读取时加的文字";
case 'age':
return "0".$this ->$name;
default:
return $this ->$name;
} }
function __set($key,$value){
//__set()与__get()是两个魔术方法,用于设置和输出对象里的私有成员属性的,存在于类中
//当外面直接设置私有成员属性$name的时候被_set()自动调用 ,当外面直接使用私有成员属性$name的时候_get()被自动调用
if($key=="name"){
$this->$key = $value."这是设置时加的文字<br>";
}else{
$this->$key = $value;
}
}
function __isset($name){
//php _isset()方法详细解释 : https://www.php.cn/php-weizijiaocheng-426362.html
//_isset() 方法就是当在类外部使用isset()判定类的私有成员是否存在的时候就会调用_isset()方法
return isset($this->$name);
} function __unset($name){
if($name=="age"){
return;
}
unset($this->$name);
}
} $zhangsan = new Person("zhangsan",14);
$zhangsan->setAge(12);
echo $zhangsan->getAge()."<br>";
var_dump(isset($zhangsan->name));
unset($zhangsan->age);
echo $zhangsan->age;
三、多态
什么是多态?
一个类,被多个子类继承,如果这个类的某个方法,在多个子类中,表现出不同的功能,我们称这种行为为多态。(同一个类的不同子类表现出不同的形态)
那么我们如何来实现多态呢?
子类继承父类 ->子类重写父类方法 ->父类引用指向子类对象
abstract class Person{ //注:父类使用abstract关键字修饰
abstract function say();
} class Chinese extends Person{ //注:子类重写父类方法
function say(){
echo "我是中国人<br>";
}
}
class English extends Person{ //注:子类重写父类方法
function say(){
echo "我是英国人";
}
} $zhangsan = new Chinese();
$zhangsan->say();
$z = new English();
$z->say();
Person $p = new Chinese(); //注:父类引用指向子类对象
//作用:抽象类不实现具体方法,具体方法由子类完成。
//定义抽象类 abstract
abstract class A{
//abstract 定义抽象类的方法,这里没有花括号。子类必须实现这个抽象方法。
abstract public function say();
//抽象类可以有参数
abstract public function eat($argument);
//在抽象类中可以定义普通的方法。
public function run(){
echo '这是run方法';
}
}
class B extends A{
//子类必须实现父类的抽象方法,否则是致命的错误。
public function say(){
echo '这是say方法,实现了抽象方法';
}
public function eat($argument){
echo '抽象类可以有参数 ,输出参数:'.$argument;
}
}
$b =new B;
$b->say();
echo '<br>';
$b->eat('apple');
echo '<br>';
$b->run();
定义为抽象的类不能被实例化。任何一个类,如果它里面至少有一个方法是被声明为抽象的,那么这个类就必须被声明为抽象的。被定义为抽象的方法只是声明了其调用方式(参数),不能定义其具体的功能实现。
继承一个抽象类的时候,子类必须定义父类中的所有抽象方法;另外,这些方法的访问控制必须和父类中一样(或者更为宽松)。例如某个抽象方法被声明为受保护的,那么子类中实现的方法就应该声明为受保护的或者公有的,而不能定义为私有的。此外方法的调用方式必须匹配,即类型和所需参数数量必须一致。例如,子类定义了一个可选参数,而父类抽象方法的声明里没有,则两者的声明并无冲突。 这也适用于 PHP 5.4 起的构造函数。在 PHP 5.4 之前的构造函数声明可以不一样的。
参考文章:https://www.php.net/manual/zh/language.oop5.abstract.php
* 四、单例设计模式
单例模式也叫单态模式
可以保证一个类只能有一个对象实例
实现要点:
①构造函数私有化,不允许使用new关键字创建对象。
②对外提供获取对象的方法,在方法中判断对象是否为空,如果为空则创建对象并返回,如果不为空则直接返回
③实例对象的属性以及获取对象的方法必须都是静态的。
④之后,创建对象只能使用我们提供的静态方法。
示例代码如下:
class Singleton{
static public $Single = null;
private function __construct(){}
static function getSingle() {
if(!self::$Single){
self::$Single = new Singleton();//self代指类名 new Singleton()和newself()是完全一样的
//静态方法调用静态属性,使用self关键词 //echo $this->height 这么表示是错的。静态方法不能调用非静态属性 因为 $this代表实例化对象,而这里是类,不知道 $this 代表哪个对象
} return self::$Single;
} function __destruct() {
echo "我被销毁了<br>";
}
}
$s1 = Singleton::getSingle();
$s1 = Singleton::getSingle();
$s1 = Singleton::getSingle();
五、PHP重载
这里需要注意的是,PHP这个语言是没有方法重载的,只有属性重载
属性重载:
含义:对一个对象的不存在的属性进行使用的时候,这个类种预先设定好的应对方法(处理机制)
属性,本质就是一个变量,其有4个操作:
取值:当对一个对象的不存在的属性进行“取值”的时候,就会自动调用方法:__get();
赋值:当对一个对象的不存在的属性进行“取值”的时候,就会自动调用方法:__set();
判断(isset):当对一个对象的不存在的属性进行“判断”的时候,就会自动调用方法:__isset();
判断(isset):当对一个对象的不存在的属性进行“判断”的时候,就会自动调用方法:__unset()。
__set($属性名,值):
含义:当对一个对象的不存在属性进行“赋值”的时候就会自动调用这个内部的魔术方法,它有两个形参,分别代表对不存在的属性进行赋值的时候的“属性名”和“属性值”。
这个方法结合__get()方法,往往可以使我们定义的类,就有一种“可简便扩展属性”的特性,即类(或对象)的属性,可以更为方便自由,如下所示:
class A{
protected $prop_list = array();
function __set($p,$v){
$this->prop_list[$p] = $v;
}
function __get($p){
return $this->prop_list[$p];
}
}
__isset()
含义:当对一个对象的不存在属性进行“判断”的时候就会自动调用这个内部的魔术方法。
__unset()
含义:当对一个对象的不存在属性进行“销毁”的时候就会自动调用这个内部的魔术方法。
六、对象接口
使用接口(interface),可以指定某个类必须实现哪些方法,但不需要定义这些方法的具体内容。
接口是通过 interface
关键字来定义的,就像定义一个标准的类一样,但其中定义所有的方法都是空的。
定义形式
interface 接口名 {
常量1;
常量2;
...
抽象方法1;
抽象方法2;
...
}
说明:
接口中只有常量(接口常量)和抽象方法两种成员;
接口常量的使用形式为:接口名称::常量名称;
接口中的抽象方法,不要使用abstract修饰,也需要使用访问控制修饰符,因为其天然就是Public;
php中接口和类一样也可以继承(接口继承接口)。
还谈php和java面向对象
相同点:
抽象类和抽象方法,及它们之间的细节都一样;
php的接口和java的接口都一样。
不同点:
重载不一样,php重载和其他面向对象语言的重载不同,而java和其他面向对对象语言的重载一样。
PHP面向对象的学习(封装,继承,多态)的更多相关文章
- -1-2 java 面向对象基本概念 封装继承多态 变量 this super static 静态变量 匿名对象 值传递 初始化过程 代码块 final关键字 抽象类 接口 区别 多态 包 访问权限 内部类 匿名内部类 == 与 equal
java是纯粹的面向对象的语言 也就是万事万物皆是对象 程序是对象的集合,他们通过发送消息来相互通信 每个对象都有自己的由其他的对象所构建的存储,也就是对象可以包含对象 每个对象都有它的类型 也就是 ...
- 深入理解Java面向对象三大特性 封装 继承 多态
1.封装 封装的定义: 首先是抽象,把事物抽象成一个类,其次才是封装,将事物拥有的属性和动作隐藏起来,只保留特定的方法与外界联系 为什么需要封装: 封装符合面向对象设计原则的第一条:单一性原则,一个类 ...
- python面向对象(封装,继承,多态)
python面向对象(封装,继承,多态) 学习完本篇,你将会深入掌握 如何封装一个优雅的借口 python是如何实现继承 python的多态 封装 含义: 1.把对象的属性和方法结合成一个独立的单位, ...
- java面向对象(封装-继承-多态)
框架图 理解面向对象 面向对象是相对面向过程而言 面向对象和面向过程都是一种思想 面向过程强调的是功能行为 面向对象将功能封装进对象,强调具备了功能的对象. 面向对象是基于面向过程的. 面向对象的特点 ...
- 浅谈学习C++时用到的【封装继承多态】三个概念
封装继承多态这三个概念不是C++特有的,而是所有OOP具有的特性. 由于C++语言支持这三个特性,所以学习C++时不可避免的要理解这些概念. 而在大部分C++教材中这些概念是作为铺垫,接下来就花大部分 ...
- php面向对象 封装继承多态 接口、重载、抽象类、最终类总结
1.面向对象 封装继承多态 接口.重载.抽象类.最终类 面向对象 封装继承多态 首先,在解释面向对象之前先解释下什么是面向对象? [面向对象]1.什么是类? 具有相同属性(特征)和方法(行为)的一 ...
- Java基础——面向对象(封装——继承——多态 )
对象 对象: 是类的实例(实现世界中 真 实存在的一切事物 可以称为对象) 类: 类是对象的抽象描述 步骤: 1.定义一个类 (用于 描述人:) ( * 人:有特征和行为) 2.根据类 创建对象 -- ...
- Python 入门 之 面向对象的三大特性(封装 / 继承 / 多态)
Python 入门 之 面向对象的三大特性(封装 / 继承 / 多态) 1.面向对象的三大特性: (1)继承 继承是一种创建新类的方式,在Python中,新建的类可以继承一个或多个父类,父类又可以 ...
- Java三大特性(封装,继承,多态)
Java中有三大特性,分别是封装继承多态,其理念十分抽象,并且是层层深入式的. 一.封装 概念:封装,即隐藏对象的属性和实现细节,仅对外公开接口,控制在程序中属性的读和修改的访问级别:将抽象得到的数据 ...
- PHP面向对象 实例化 构造函数 封装 继承 静态
PHP面向对象 实例化 构造函数 封装 继承 静态 面向对象: 一:定义类 class Dog { var $name; var $age; var $pinzhong; function Jiao( ...
随机推荐
- MathType总结编辑括号的类型(上)
括号的种类有很多,我们用得也很多,可以说无处不见,不只是在数学物理这些自然科学的公式中来断地出现括号,即使是在人文艺术类的领域也会有括号的出现.下面就和小编一起来看看公式编辑器编辑括号的类型吧! Ma ...
- Invalid operation updata 错误解决方法
错误: huny@DESKTOP-N1EBKQP:/mnt/c/Users/Administrator$ sudo apt-get updata E: Invalid operation updata ...
- CF980C Posterized
先来吐槽一下这个 sb 翻译,根本就没做过题吧-- 大概就是让你给值域分成连续的几组,每组大小不能超过 \(k\),然后将序列中的值全部替换成其组内的最小值,要使得序列的字典序最小. 因为是字典序,所 ...
- 【数据结构】关于前缀树(单词查找树,Trie)
前缀树的说明和用途 前缀树又叫单词查找树,Trie,是一类常用的数据结构,其特点是以空间换时间,在查找字符串时有极大的时间优势,其查找的时间复杂度与键的数量无关,在能找到时,最大的时间复杂度也仅为键的 ...
- LaTeX中的特殊字符
空白符号代码及注释: 显示效果: 控制符.排版符号.标志符号.引号.连字符.非英文字符和重音符号的代码及注释: 显示效果:
- web服务器专题:tomcat基础及模块
Web服务器专题:Tomcat(一)基础架构 针对java系的经典服务器,打算系统的整理一下Tomcat的机制和一些原理,以此记录. 插一则题外话,关于tomat这个名字的由来:Tomcat 名称的由 ...
- Spring Boot + Elasticsearch 使用示例
本文分别使用 Elasticsearch Repository 和 ElasticsearchTemplate 实现 Elasticsearch 的简单的增删改查 一.Elastic Stack El ...
- AtomicInteger的addAndGet(int delta)与getAndAdd(int delta)有什么区别?
结论:区别仅在于返回的结果,修改的值是相同的,但是返回的值不同. 看一下源码注释 1 /** 2 * Atomically adds the given value to the current va ...
- Python使用property函数定义属性访问方法如果不定义fget会怎么样?
我们知道Python使用property函数定义属性访问方法时的语法如下: 实例属性=property(fget=None, fset=None, fdel=None, doc=None) 而是要@p ...
- Java 线程安全问题的本质
原创声明:作者:Arnold.zhao 博客园地址:https://www.cnblogs.com/zh94 目录: 线程安全问题的本质 理解CPU JVM虚拟机类比于操作系统 重排序 汇总 一些解释 ...