php类的封装、继承和多态的简单理解

面象对向的三大特点:封装性、继承性、多态性 首先简单理解一下抽象:
我们在前面定义一个类的时候,实际上就是把一类事物共有的属性和行为提取出来,形成一个物理模型(模版),这种研究问题的方法称为抽象

一、封装性 
封装就是把抽取出来的数据和对数据的操作封装在一起,数据被保护在内部,程序的其他部分只有被授权的操作(方法)才能对数据进行操作。 
php提供了三种访问控制修饰符 
public 表示全局,本类内部,类外部,子类都可以访问 
protected 表示受保护的,只有本类或子类可以访问 
private 表示私有的,只有本类内部可以访问 
以上三种修饰符既可以修饰方法也可以修饰属性(变量),方法如果没有访问修饰符则默认是public,成员属性必须指定访问修饰符,在PHP4中也有这种写法 var $name,表示公开属性,不推荐这种写法 
例: 
复制代码 代码如下:

< ?php 
class Person{ 
public $name; 
protected $age; 
private $salary; 
function __construct($name,$age,$salary){ 
$this->name=$name; 
$this->age=$age; 
$this->salary=$salary; 

public function showinfo(){ 
//这表示三个修饰符都可以在本类内部使用 
echo $this->name."||".$this->age."||".$this->salary; 


$p1=new Person(‘张三‘,20,3000); 
//这里属于类外部,那么如果用下面的方法访问age和salary都会报错 
// echo $p1->age; echo$p1->salary; 
?>

那么现在就想在外部访问protected和private的元素和方法该怎么办? 通常做法是通过public函数去访问这些变量 格式: 
public function setxxxx($val){ 
$this->xxxx=$val; 

public function getxxxx(){ 
return $this->xxxx; 

这里带set和get只是为了识别方便,并非必要 
如: 
public function getsalary(){ 
return $this->salary; //扩展:这里可以调用一些方法,如判断用户名等,正确才给访问 

在外部就可以通过 echo $p1->getsalary(); 
如果要访问 protected和private也可以使用以下方法,但不推荐使用,只要了解即可 
__set() 和 __get() 
__set()对protected或private属性进行赋值操作 
__set($name,$val); 
__get()获取 protected 或 private的值 
__get($name); 
如: 
复制代码 代码如下:

< ?php 
class testa{ 
protected $name; 
//使用__set()来管理所有属性 
public function __set($pro_name,$pro_val){ 
//上面$pro_name和$pro_val可自定义 
//下面$this->pro_name为既定,不可更改 
$this->pro_name=$pro_val; 

//使用__get()来获取所有属性值 
public function __get($pro_name){ 
if(isset($pro_name)){ 
return $this->pro_name; 
} else { 
return null; 



$n1=new testa(); 
//正常情况,类外部是不能访问protected属性的,但是用了上面的方法就可以对它们进行操作 
$n1->name=‘小三‘; 
echo $n1->name; 
?>

//以上代码看懂就行,不推荐使用 
二、继承性 
先看一个例子: 
复制代码 代码如下:

< ?php 
class Pupil{ 
public $name; 
protected $age; 
public function getinfo(){ 
echo $this->name.‘||‘.$this->age; 

public function testing(){ 
echo ‘this is pupil‘; 


class Graduate{ 
public $name; 
protected $age; 
public function getinfo(){ 
echo $this->name.‘||‘.$this->age; 

public function testing(){ 
echo ‘this is Graduate‘; 


?>

从上面的例子可以看出,当多个类有很多共同属性和方法时,代码的复用性不高,代码冗余,思考css中的处理方法 
解决方法 :继承 
复制代码 代码如下:

< ?php 
class Students{ 
public $name; 
public $age; 
public function __construct($name,$age){ 
$this->name=$name; 
$this->age=$age; 

public function showinfo(){ 
echo $this->name.‘||‘.$this->age; 


class Pupil extends Students{ 
function testing(){ 
echo ‘Pupil ‘.$this->name.‘ is testing‘; 


class Graduate extends Students{ 
function testing(){ 
echo ‘Graduate ‘.$this->name.‘ is testing‘; 


$stu1=new Pupil(‘张三‘,20); 
$stu1->showinfo(); 
echo ‘<br/>‘; 
$stu1->testing(); 
?>

从上面可以看出,继承就是一个子类(Subclass)通过 extends 父类 把父类(BaseClass)中的public 和 protected 的属性和方法继续下来,不能继承private属性和方法 
语法结构: 
class 父类名{} 
class 子类名 extends 父类名{} 
细节: 
1、一个子类只能继承一个父类(这里指直接继承);如果希望继承多个类的属性和方法,可以使用多层继承 
例: 
复制代码 代码如下:

< ?php 
class A{ 
public $name=‘AAA‘; 

class B extends A{ 
public $age=30; 

class C extends B{} 
$p=new C(); 
echo $p->name;//这里会输出AAA 
?>

2、在创建某个子类对象时,默认情况下不会自动调用其父类的构造函数 
例: 
class A{ 
public function __construct(){ 
echo ‘A‘; 


class B extends A{ 
public function __construct(){ 
echo ‘B‘; 


$b=new B();//这里会优先输出B中的构造方法,如果B中没有构造方法才会输出A中的 
3、在子类中如果需要访问父类的方法(构造方法、成员方法 方法的修饰符为protected或private),那么可以使用 父类::方法名 或者 parent::方法名 来完成【这里parent和以前提到的self都均为小写,大写报错】 
class A{ 
public function test(){ 
echo ‘a_test‘; 


class B extends A{ 
public function __construct(){ 
//两种方法都行 
A::test(); 
parent::test(); 


$b=new B(); 
5、如果一个子类(派生类)的方法与父类的方法完全一样时(public,protected),我们称为方法覆盖或方法重写(override),看下面的多态性 
三、多态性 
例 : 
复制代码 代码如下:

< ?php 
class Animal{ 
public $name; 
public $price; 
function cry(){ 
echo ‘i don\‘t know‘; 


class Dog extends Animal{ 
//覆盖、重写 
function cry(){ 
echo ‘Wang Wang!‘; 
Animal::cry();//这里不会报错,能正确执行父类的cry(); 


$dog1=new Dog(); 
$dog1->cry(); 
?>

小结: 
1、当一个父类知道所有的子类都有一个方法,但是父类不能确定该方法如何写,可以让子类去覆盖它的方法,方法覆盖(重写),必须要求子类的方法名和参数个数完全一致 
2、如果子类要去调用父类的某个方法(protected/public),可以使用 父类名::方法名 或者 parent::方法名 
3、在实现方法重写的时候,访问修饰符可以不一样,但是子类方法的访问权限必须大于等于父类方法的访问权限(即不能缩小父类方法的访问权限) 
如 父类public function cry(){} 子类 protected function cry(){} 则会报错 
但是子类的访问权限可以放大,如: 
父类private function cry(){} 子类 protected function cry(){} 可以正确执行 
扩展: 
方法重载(overload) 
基本概念:函数名相同,但参数的个数或参数的类型不同,达到调用同一个函数,可以区分不同的函数 
在PHP5中虽然也支持重载,但是和其它语言还是有很大区别的,php中不能定义多个同名函数 
PHP5中提供了强大的“魔术”函数,使用这些魔术函数,我们可以做到函数重载, 
这里我们要到到 __call,当一个对象调一个方法时,而该方法不存在,则程序会自动调用__call 
【官方不推荐使用】 
PHP中有以下几个魔术常量:__LINE__ __FILE__ __DIR__ __FUNCTION__ __CLASS__ 等 
例: 
复制代码 代码如下:

< ?php 
class A{ 
function test1($p){ 
echo ‘test1<br/>‘; 

function test2($p){ 
echo ‘test2<br/>‘; 

function __call($method,$p){ 
//这里$p为数组,上面两个变量名可自定义 
if($method == ‘test‘){ 
if(count($p)==1){ 
$this->test1($p); 
} else if(count($p)==2){ 
$this->test2($p); 




$a=new A(); 
$a->test(5); 
$a->test(3,5); 
?>

时间: 2024-12-22 08:27:02

php类的封装、继承和多态的简单理解的相关文章

黑马程序员--oc 类的封装 继承 和多态

------Java培训.Android培训.iOS培训..Net培训.期待与您交流! ------- 成员变量的命名规范: 成员变量名要以 _开头 作用: 1.可以让成员变量和get方法的名称区分开 2.可以和局部变量区分开,一看到以_开头的变量一般都是成员变量 封装: 在定义成员变量时,尽量不要用@public 这种写法 ,而是使用set方法和get方法 @interface Student : NSObject { int _age; } /* set方法: 作用:提供一个方法给外界设置成

类的封装 继承和多态

package 银行账户管理;import java.text.SimpleDateFormat;   //常用日期操作工具类import java.util.Calendar;     //使用默认时区和语言环境获得一个日历import java.util.Date;public class yinhang {  private String acount;     //账户  private String name;   //姓名  private String time;   //时间  

day33 序列类型,绑定方法,类方法,静态方法,封装继承和多态

Python之路,Day20 = 序列类型,绑定方法,类方法,静态方法,封装继承和多态 序列是指有序的队列,重点在"有序". 一.Python中序列的分类 Python中的序列主要以下几种类型: 3种基本序列类型(Basic Sequence Types):list.tuple.range 专门处理文本的附加序列类型(Text Sequence Types):str 专门处理二进制数据的附加序列类型(Binary Sequence Types): bytes.bytearray.mem

Mysql数据库大量删除操作及谈面向对象中的封装继承和多态原理(图)

Mysql数据库大量删除操作及谈面向对象中的封装继承和多态原理(图)最近进行数据库操作,遇到一个问题,就是大量删除一个数据表中的数据后,由于设定了id是自增的,导致再插入时,默认生成的id会很大,这个时候想要再次插入新的数据,应该怎么办呢?1.明确目前最后一个id的大小select id from tags order by id DESC limit 0,1; 假设返回的是9,则设置数据表从10开始自增 2.修改这个数据表从10开始自增alter table tags auto_increme

c语言中继承和多态的简单实现

C语言本身是不支持继承和多态的,但其实在 C 的世界里,有一套非常有名的面向对象的框架,用的也非常广,那就是 GObject,它是整个图形界面开发库 GTK 的基石,在IBM developerWorks上有一篇很好的文章介绍 GObject<GObject对象系统>.另外,在 Linux 内核里面也大量使用了面向对象的思想,比如虚拟文件系统,设备驱动等模块,在 lwn上有两篇文章就讲到了内核中的面向对象,详细请看:<Object oriented design patterns in

面向对象:封装继承和多态、接口

1.多态 定义:不同对象对于同一个方法(Cut)调用表现出不同行为多态性主要是靠重写和隐藏来实现 a.(父类引用指向子类对象)b.(父类类型做参数,传递子类对象)自定义方法参数是父类类型 传递的实参是子类对象c.(父类类型作返回类型,return子类对象)自定义方法的返回类型是父类类型,return是类对象注:都是把子类对象赋给父类类型 举例: 添加乐器类using System;using System.Collections.Generic;using System.Linq;using S

C++之封装继承和多态

C++中非常重要的概念,尤其是相对于C语言而言,也是其具有如此高的工程使用性的重要原因. 封装 所谓封装是将某些东西隐藏起来,让外界无法直接使用,而必须通过某些特定的方式才能访问.也即是,将抽象得到的数据和行为(类似于属性和方法)结合构成一个有机整体,将数据与操作数据的函数构成类,其中数据和函数都是类的成员. 其目的是将对象的使用者和设计者隔离开来,提高软件的可维护性和可修改性,使用者不必了解具体的实现细节而只是通过外部接口及特定的访问权限使用类成员,从而增强了安全性且简化了编程,也使得不同类之

java类的封装 继承 多态

1.猜数字小游戏 package cn.jiemoxiaodi_02; import java.util.Scanner; /** * 猜数字小游戏 * * @author huli * */ public class GuessNumberDemo { public static void main(String[] args) { int number = (int) (Math.random() * 100) + 1; while (true) { System.out.println("

面向对象的三大特征,封装、继承、多态的个人理解以及代码分析

面向过程:我们以前使用的是面向过程编程,你需要清除每个实现步骤,每个步骤每行代码都要仔仔细细的编写, 不知道过程就找不到结果,找到实现过程就可以得到实现结果. 例如: 我们在外打工租房子,我们需要了解每个每个房屋的出租信息,不然是找不到房子的. 面向对象:对象帮我们做事情,找到对应的对象我们就可以得到想要的结果.    例如: 我们找房子不在如此的繁琐,只要找到中介我们就不怕没有地方住,中介会帮你找房子,你只需支付对应的服务费即可. 面向对象的三大特征给我们带了巨大的好处,下面我们就来讲解一下.