第十八章 面向对象的特性

学习要点:
1.OOP
的封装
2.OOP 的继承
3.OOP 的多态

面向对象的三个主要特性是封装、继承和多态。

一.OOP的封装

隐藏对象的字段和实现细节,仅对外公开接口,控制在程序中字段的读和修改的访问级
别;将抽象得到的数据和行为(或功能)相结合,形成一个有机的整体,也就是将数据与
操作数据的源代码进行有机的结合,形成“类”,其中数据和函数都是类的成员。

字段的作用域
1.public 公共的(类外可以访问)
2.private
私有的(类内可以访问)
3.protected 受保护的(类内和子类可以访问,类外不可访问)

创建使用了私有的字段,这样外部就无法访问了

class Computer {
//类的字段(成员)
private $_name = ‘联想120‘;
private $_model = ‘LX‘;
}

通过一个公共方法作为入口,访问私有字段,而必须使用$this关键字。


class Computer {
//类的字段(成员)
private $_name = ‘联想120‘;
private $_model = ‘LX‘;
//通过公共方法来访问私有字段
function run() {
echo $this->_name;
}
}
$computer->run ();

属性操作(私有字段的赋值与取值)

可以设计两个公共方法,一个方法为setName(),用于赋值;一个方法为getName(),
用于取值。


class Computer {
//类的字段(成员)
private $_name;
private $_model;
//赋值
function setName($_name) {
$this->_name = $_name;
}
//取值
function getName() {
return $this->_name;
}
}
$computer = new Computer ();
$computer->setName ( ‘IBM‘ );
echo $computer->getName ();

如果有十个字段那么就必须要二十个方法才能够赋值和取值,那么有没有更简便的方法
呢?PHP内置两个方法(拦截器)专门用于取值与赋值:__set(),__get()。


class Computer {
//类的字段(成员)
private $_name;
private $_model;
//所有字段的赋值都在这里进行
function __set($_key, $_value) {
$this->$_key = $_value;
}
//所有字段的取值都在这里进行
function __get($_key) {
return $this->$_key;
}
}
$computer = new Computer ();
$computer->_model = ‘LX‘;
echo $computer->_model;

方法私有:有些使用类里面的方法并不需要对外公开,只是里面运作的一部分,这个时
候可以将方法也封装起来。


class Computer {
//类的字段(成员)
private $_name;
private $_model;
//私有方法
private function getEcho() {
echo ‘我是私有化的方法‘;
}
//公共方法一般是对外的入口
public function run() {
$this->getEcho ();
}
}
$computer = new Computer ();
$computer->run ();

建议:方法前面如果没有修饰符,那么就是外部可访问的公共方法,但为了让程序更加
的清晰,建议在前面加上public。

常量(constant)
在类中可以定义常量,用来表示不会改变的值。对于从该类实例化的任何对象来说,常
量值在这些对象的整个生命周期中都保持不变。

class Computer {
const PI = 3.1415926;
}
echo Computer::PI;

静态类成员
有时候,可能需要创建供所有类实例共享的字段和方法,这些字段和方法与所有的类实
例有关,但不能由任何特定对象调用。

class Computer {
public static $_count = 0;
}
echo Computer::$_count;

一般来说,必须将字段做成私有化。所以可能需要这么做:


class Computer {
private static $_count = 0;
public static function setRun() {
self::$_count ++;
}
public static function getRun() {
return self::$_count;
}
}
Computer::setRun ();
echo Computer::getRun ();

Instanceof关键字
PHP5有一个instanceof关键字,使用这个关键字可以确定一个对象是类的实例、类的
子类,还是实现了某个特定接口,并进行相应的操作。

class Computer {

}
$computer = new Computer ();
echo ($computer instanceof Computer);

二.OOP继承

继承是从一个基类得到一个或多个类的机制。
继承自另一个类的类被称为该类的子类。这种关系通常用父类和孩子来比喻。子类将继
承父类的特性。这些特性由属性和方法组成。子类可以增加父类之外的新功能,因此子类也
被称为父类的“扩展”。

在PHP中,类继承通过extends关键字实现。继承自其他类的类成为子类或派生类,子
类所继承的类成为父类或基类。(PHP只支持单继承,PHP不支持方法重载)。


class Computer {
private $_name = ‘联想120‘;
private function __get($_key) {
return $this->$_key;
}
public function run() {
echo ‘我是父类‘;
}
}
class NoteBookComputer extends Computer {
}
$notebookcomputer = new NoteBookComputer ();
$notebookcomputer->run ();
echo $notebookcomputer->_name;

字段和方法的重写(覆盖)
有些时候,并不是特别需要父类的字段和方法,那么可以通过子类的重写来修改父类的
字段和方法。


class Computer {
public $_name = ‘联想120‘;
protected function run() {
echo ‘我是父类‘;
}
}

class NoteBookComputer extends Computer {
public $_name = ‘IBM‘;
public function run() {
echo ‘我是子类‘;
}
}

子类调用父类的字段或方法
为了安全,我们一般将父类的方法封装了起来,这样,外部就无法调用,只能被继承它
的子类所看到。这个时候,就需要通过子类操作来调用父类了。


class Computer {
protected $_name = ‘联想120‘;
protected function run() {
echo ‘我是父类‘;
}
}

class NoteBookComputer extends Computer {
public function getName() {
echo $this->_name;
}
public function getRun() {
echo $this->run ();
}
}

通过重写调用父类的方法
有的时候,我们需要通过重写的方法里能够调用父类的方法内容,这个时候就必须使用
语法:父类名::方法()
或者parent::方法()即可调用。


class Computer {
protected function run() {
echo ‘我是父类‘;
}
}

class NoteBookComputer extends Computer {
public function run() {
echo Computer::run ();
}
}

final关键字可以防止类被继承,有些时候只想做个独立的类,不想被其他类继承使用,
那么就必须使用这个关键字。建议只要是单独的类,都加上这个关键字。


final class Computer {
//无法继承的类
final public function run() {
} //无法被继承的方法
}

class NoteBookComputer extends Computer {
//会报错
}

抽象类和方法(abstract)
抽象方法很特殊,只在父类中声明,但在子类中实现。只有声明为abstract的类可以声
明抽象方法。

规则:
1.抽象类不能被实例化,只能被继承。
2.抽象方法必须被子类方法重写。


abstract class Computer {
abstract function run();
}

final class NotebookComputer extends Computer {
public function run() {
echo ‘我实现了‘;
}
}

接口(interface)
接口定义了实现某种服务的一般规范,声明了所需的函数和常量,但不指定如何实现。
之所以不给出实现的细节,是因为不同的实体可能需要用不同的方式来实现公共的方法定
义。关键是要建立必须实现的一组一般原则,只要满足了这些原则才能说实现了这个接口。

规则:
1.类全部为抽象方法(不需要声明abstract)
2.接口抽象方法必须是public
3.成员(字段)必须是常量


interface Computer {
const NAME = ‘联想120‘;
public function run();
}

final class NotebookComputer implements Computer {
public function run() {
echo ‘实现了接口的方法‘;
}
}
$notebookcomputer = new NoteBookComputer ();
$notebookcomputer->run ();
echo Computer::NAME;

子类可以实现多个接口


interface Computer {
const NAME = ‘联想120‘;
public function run();
}

interface Notebook {
public function book();
}

final class NotebookComputer implements Computer, Notebook {
public function run() {
echo ‘实现了接口的方法‘;
}
public function book() {
echo ‘实现了接口的方法‘;
}
}

三.多态

多态是指OOP
能够根据使用类的上下文来重新定义或改变类的性质或行为,或者说接
口的多种不同的实现方式即为多态。把不同的子类对象都当作父类来看,可以屏蔽不同子类
对象之间的差异,写出通用的代码,做出通用的编程,以适应需求的不断变化。


interface Computer {
public function version();
public function work();
}

class NotebookComputer implements Computer {
public function version() {

echo ‘联想120‘;
}
public function work() {
echo ‘笔记本正在随时携带运行!‘;
}
}

class desktopComputer implements Computer {
public function version() {
echo ‘IBM‘;
}
public function work() {
echo ‘台式电脑正在工作站运行!‘;
}
}

class Person {
public function run($type) {
$type->version ();
$type->work ();
}
}

$person = new Person ();
$desktopcomputer = new desktopComputer ();
$notebookcomputer = new NoteBookComputer ();
$person->run ( $notebookcomputer );

注:文章出自李炎恢PHP视频教程,本文仅限交流使用,不得用于商业用途,否则后果自负。

第十八章 面向对象的特性,布布扣,bubuko.com

时间: 2024-08-05 19:37:43

第十八章 面向对象的特性的相关文章

面向对象编程(十四)——面向对象三大特性之多态②

面向对象最核心的机制——动态绑定,也叫多态. 通过下面的例子理解动态绑定,即多态 1 package javastudy.summary; 2 3 class Animal { 4 /** 5 * 声明一个私有的成员变量name. 6 */ 7 private String name; 8 9 /** 10 * 在Animal类自定义的构造方法 11 * @param name 12 */ 13 Animal(String name) { 14 this.name = name; 15 } 16

第十八章----面向对象(宠物乱斗之子类篇)

1.关于时间格式的修改 package com.maya.chongwu; import java.text.SimpleDateFormat; import java.util.Date; public class DateFormat { public static String convert(Date date) { SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); String dateStr = sdf.f

第十篇 面向对象的程序设计

第十篇 面向对象的程序设计 阅读目录 一 面向对象的程序设计的由来 二 什么是面向对象的程序设计及为什么要有它 三 类和对象 3.1 什么是对象,什么是类 3.2 类相关知识 3.3 对象相关知识 3.4 对象之间的交互 3.5 类名称空间与对象/实例名称空间 3.6 小结 四 继承与派生 4.1 什么是继承 4.2 继承与抽象(先抽象再继承) 4.3 继承与重用性 4.4 组合与重用性 4.5 接口与归一化设计 4.6 抽象类 4.7 继承实现的原理(继承顺序) 4.8 子类中调用父类方法 五

Linux内核分析——第十八章 调试

第十八章    调试 18.1 准备开始 1.在用户级的程序里,bug表现比较直接:在内核中却不清晰. 2.内核级开发的调试工作远比用户级开发艰难的多. 3.准备工作需要的是: (1)一个bug (2)一个藏匿bug的内核版本 (3)相关内核代码的知识和运气 18.2 内核中的bug 1.内核中的bug多种多样. 2.引用空指针会产生一个oops:垃圾数据会导致系统崩溃. 3.定时限制和竞争条件都允许多个线程在内核中同时运行产生的结果. 18.3 通过打印来调试 一.健壮性 1.健壮性——在任何

TCP/IP详解 卷1 第十八章 TCP的建立与终止

第十八章 TCP的建立与终止 tcpdump Tcpdump可以将网络中传送的数据报完截获下来进行分析.它支持针对网络层.协议.主机.网络或端口的过滤,并提供and.or.not等逻辑语句来帮助你去掉无用的信息 就有点像Wireshark那个工具一样,只不过是命令行的,这里不作详细分析,直接给个实例: 每行输出格式如下:  源 > 目的:标志 这里的标志就是TCP首部中6个标志比特中的4个,下面是标志中5个字符的含义: ack和urg将做特殊显示. 字段ack表示确认序号,只有在首部中ack标志

Python进阶(十六)----面向对象之~封装,多态,鸭子模型,super原理(单继承原理,多继承原理)

Python进阶(十六)----面向对象之~封装,多态,鸭子模型,super原理(单继承原理,多继承原理) 一丶封装 , 多态 封装: ? ? ? ? ? ?将一些东西封装到一个地方,你还可以取出来 ? ? ? ? ? ?类设置静态属性, 设置一些方法 或者 对象, 对象可以在其对象封装一些属性 多态: ? ? ? ? ? ?python默认支持多态, 多态指的是一种事务具有多种形态 ? ? ? ? ? ?1.多态可以增加代码的灵活度: ? ? ? ? ? ?2.以继承和重写父类方法为前提: ?

【WPF学习】第二十八章 程序集资源

原文:[WPF学习]第二十八章 程序集资源 WPF应用程序中的程序集资源与其他.NET应用程序中的程序集资源在本质上是相同的.基本概念是为项目添加文件,从而Visual studio可将其嵌入到编译过的应用程序的EXE或DLL文件中.WPF程序集资源与其他应用程序中的程序集资源之间的重要区别是引用他们的寻址系统不同. 在前面章节已讨论过程序集资源的工作原理.因为每次编译应用程序时,项目中的每个XAML文件都转换为解析效率更高的BAML文件.这些BAML文件作为独立资源嵌入到程序集中.添加自己的资

C#高级编程第11版 - 第二十八章

导航 C# 全版本特性一览 全书目录 第二十八章 Testing 28.1 概述 678 28.2 使用MSTest 进行单元测试 679 28.2.1 使用MSTest 创建单元测试 679 28.2.2 运行单元测试 681 28.2.3 使用MSTest 预期异常 682 28.2.4 测试全部代码路径 683 28.2.5 外部依赖 683 28.3 使用xUnit 进行单元测试 685 28.3.1 使用xUnit 和.NET Core 686 28.3.2 创建Fact 属性 686

《Linux内核设计与实现》读书笔记 第十八章 调试

第十八章调试 18.1 准备开始          需要准备的东西: l  一个bug:大部分bug通常都不是行为可靠而且定义明确的 l  一个藏匿bug的内核版本:找出bug首先出现的版本 l  相关内核代码的知识和运气 最好能让bug重现,有一些bug存在而且有人没办法让他重现,因为内核与用户程序和硬件间的交互很微妙. 18.2内核中的bug 可以有无数种原因产生,表象也变化多端.代码中的错误往往引发一系列连锁反应,目击者才看到bug. 18.3通过打印来调试 内核提供了打印函数printk