面向对象整理

             面向对象知识点整理

面向对象思想介绍

传统的面向过程:将要完成的工作分作若干步骤,或在细分为子步骤,然后按步骤从前往后一步一步完成,然后达到目的,好比做饭,洗菜,切菜,下锅等等每一步都是自己完成最终做成。

现代的面向对象:将要完成的工作拆分为一个一个对象的任务,每个对象独立完成自己的任务,任务之间的连接通过调用来实现,最终也完成了整体的工作。也像做饭只是洗菜,切菜等这些步骤不用自己完成,而是让对象完成,自己最后只负责用就可以。

万事万物皆对象。面向对象是设计思想的升华,面向过程是解决简单问题的自然的思维过程,面向对象是解决大规模的复杂问题的良好思想。

面向对象基本概念

类与对象

张三,李四,王五都是对象,他们都隶属于“人”这个类,同时我们也可以说隶属于 脊椎动物类 同样都是生物类。

类:是用于描述某一些具有共同特征的物体的概念表,是某一类物体的总称。

      通常,一个雷所具有的共同特征包括2大方面的信息:  属性;方法。

对象:是指一个具体的物体,该物体隶属于某个类别。

通常,对象离不开类,没有类就不能有对象

原来(在面向过程)的语法中,我们的代码有如下几种代码:

定义变量;

定义函数;

使用变量(输出,赋值,等)

调用函数;

流程控制(if,switch,for,while等)

在面向对象的语法中,则情况就发生变化了:

1,定义类;定义类的语法中,只有这3种代码:

1.1定义属性(变量)

1.2定义方法(函数)

1.3定义常量(类常量)

2,创建类的对象;

$对象名=new 类名();

3,使用对象;

使用其属性:因为属性就是“变量”,则使用其属性,也就是跟以前使用变量一样。

使用其方法:因为方法就是“函数”,则使用其方法,也就是跟以前使用函数一样。

使用其常量:类似使用以前的普通常量。

对象的传值

php中,变量传值方式有2个:

值传递:     传递的时候,拷贝的是数据本身。默认都是值传递。

结果:传递完之后,有了2份同样的数据,但两个变量“相互独立”没有关系。

引用传递:  传递的时候,拷贝的是引用关系。需要使用“&”才能实现引用传递。

结果:传递完之后,数据仍然只有一份,但是两个变量共同指向该数据。

则在面向对象这个层面,基本来说,仍然如此:

默认是值传递:

可以使用引用传递:

有一点不同,值传递复制的是对象标识符

类中成员

一个类的内部可以有3种代码:

属性

方法

类常量

一般属性

定义形式:

形式1:     var  $v1 ;         //定义不赋值

形式2:    var  $v2 = 2;         //定义的同时可以赋值,该值只能是“直接值”,常量(值)

//不能是变量值,也不能是“计算表达式”

形式3:     public  $v1;

形式4:     public   $2 = 2;     //其实var是“public”一个别名,正式用public更好。

错误形式:

$v1 = 1;

var  $v2 = 1+3;                 //右边不能是计算表达式

public   $v3 = $v2;       //右边不能是变量

 

使用形式:

$对象->属性名;           //注意:属性名前面没有$符号。

通常,可以出现变量的位置,就可以出现对象的属性

一般方法

方法定义跟原来函数定义几乎一样。

使用是通过类或类的对象来进行的。

$this关键字:$this是一个伪对象,代表当前所属类的当前对象;

类是定义好的某些对象的“模板/模型”

对象是根据该模板/模型所“创建”出来的具体物体

一个对象可以有哪些属性(数据),是由该类来决定的。

一个对象可以做那些事情(方法),也是由该类来决定。

通常认为,一个类(对象),就是拥有一些数据,并通过它自己的方法可以去处理这些数据的“独立体”

系统函数:get_class(对象)  获得某个对象的所属类名,结果是一个类名字符串

静态属性

定义属性的时候,前面加上关键字:static,此时就是静态属性

静态属性有什么用?

对比来说:一般属性,他的值是隶属于该类的具体某个对象(虽然定义在类中),或者说,每个对象的同样的属性的值,有可能不一样。

静态属性就是:只隶属于类本身——也可以看做是所有对象的“共有数据”

静态属性的使用:通过特殊语法,:: 双冒号语法,也叫范围解释符

类::$静态属性名; 普通属性使用 :对象->普通属性名

静态方法

如果在一个方法的前面加上static关键字修饰,则就变成了静态方法。

静态方法同样隶属于类,而不是隶属于具体对象。使用方法跟静态属性类似:

类名::静态方法名();

从理念上,可以认为,静态方法是只隶属于类,而为所有对象所“共有”。

 

如果通过类名来调用静态方法,则该方法中不可以出现$this关键字。

注意:$this不能在静态方法中使用;静态方法不能调用非静态方法

Self:

含义:代表当前类

使用:通常只能在某个类的某个方法内部代表该类的名称

Class s2{

      Public $v1=1;

Static function getNew(){
      return new self;//self 代表当前类  new self就是当前类的一个对象

}

}

$obj2=s2::getNew();

Var_dump($obj2);

构造方法

构造方式是类中的一个“特殊”方法,其作用是在实例化一个对象的同时,给该对象的属性赋值,使之一创建完成,就具有了其本身的特有数据

1,该方法名字是固定的,为:_ _construct();

2,该方法必须是普通方法(不能是静态方法)

3,通常该方法应该是public

4,通常该方法中使用$this这个关键字来对属性进行赋值

5,当new 类名()的时候,其实是在调用该构造方法

6,如果一个类中定义了构造方法,则实例化该类时就会调用该方法,且实例化时的参数需要跟构造方法的参数匹配

析构方法

构造方法是“创建”对象的时候会自动调用。

析构方法是“销毁”对象的时候会自动调用。

系统方法通常用于在销毁对象的时候来“清理数据”(打扫战场)——如果需要,就可以利用这个机会去处理。

通常,php程序结束后,所有对象都会自动销毁(其实属于php内部的垃圾回收机制)

1,析构方法通常不太需要去定义。

2,析构方法不能调用。

3,析构方法不能有形参。

4,析构方法中可以用于清理一些在php代码结束后不能清理的数据,如生成的文件。

对象销毁的几个情形:

1、         脚本程序运行结束,自动销毁

2、         明确的unset()一个对象变量,则被销毁

3、         改变对象变量的值,被销毁

实际上,更本质来说,当一个对象(new 出来的对象)没有任何一个变量指向它的时候,该对象就会被自动销毁——自然,如果整个程序结束,也会销毁。

类的继承

子类继承父类的所有特征,并且子类还有自己的特有特征;

基本概念

继承:一个类从另一个已有的类获得其特性成为继承

派生:从一个已有的类产生一个新的类,称为派生

已有类称为父类,新建类为子类

单继承:一个类只能从一个上级类继承其特性信息。

扩展:在子类中再来定义自己的一些新的特有的属性,方法。常量。没有扩展继承也就没有意义了

访问修饰符

在类中的成员,通常都可以在前面加上以下3个修饰符:

Public:公共

Protected:受保护的

Private:私有的

public公有的

用该修饰符修饰的成员,可以在“任何位置”使用(访问)。

访问(使用)是这样一个语法模式:

对象->成员;

类名::成员;

访问位置分为3个:

1:某个类内部:自然是该类的某个方法中

2:某个类的具有继承关系的子(父)类的内部:是指其他类的某个方法中。

3,某个类的外部:一般就是独立的代码区(不在类中),类似我们之前的代码。

protected 受保护的

protected修饰的成员,可以在当前类或当前类的上下级具有继承关系的类中访问。

private私有的

private 修饰的成员,只能在其所在的类中访问。

parent代表父类

对比self代表当前类,parent通常用于在子类中调用父类的成员的时候使用,多数就是使用父类的静态类成员

class C{

      public $p1 = 1;

      function showMe(){

           echo "<br />我是父类,数据有:";

           echo "<br />C中p1=" . $this->p1;

      }

      function __construct($p1){

           $this->p1 = $p1;

      }

}

class D extends C{

      public $p2 = 2;

      function __construct($p1,$p2){

           //经典用法

           parent::__construct($p1);//调用父类的构造函数来初始化p1

           $this->p2 = $p2;     //初始化p2

      }

      function showMe2(){

           echo "<br />我是子类,数据有:";

           //基本用法:

           parent::showMe();//调用父类的showMe方法,

           echo "<br />D中p2=" . $this->p2;

      }

}

$d1 = new D(10,20);     //此时就需要尊照构造函数的参数结构来使用

$d1->showMe2();

 

构造方法析构方法在继承中的表现

子类中没有定义构造方法时,会自动调用父类的构造方法。因此实例化子类时,需按照父类的构造方法的形式进行。

子类定义了自己的构造方法,则不会自动调用父类的构造方法,但可以手动调用:parent::__construct();

通常,在子类,很多时候,在构造方法中,都应该去调用父类的构造方法减少代码,增加可读性

      Class c{

      Public $p1=1;

      Public $p3=3;

      Function __construct($p1,$p3){

$this->p1=$p1;

$this->p3=$p3;

}

}

Class d extends c{

      Public $p2=2;

      Function __construct($p1,$p2,$p3){

Parent::__construct($p1,$p3);

$this->p2=$p2;

}

Function show(){

Echo “<br>p1=$this->p1”;

Echo “<br>p2=$this->p2”;

Echo “<br>p3=$this->p3”;

}

}

$d1=new d(10,20,40);

$d1->show();

子类中没有定义析构方法时,会自动调用父类的析构方法。

子类定义了自己的析构方法,则不会自动调用父类的析构方法,但可以手动调用:parent::__destruct()

重写override

重写又叫覆盖,就是将从父类继承下来的属性或方法重新“定义”——就是从新写。

注意:重写需要子类跟父类的方法同名同参,构造方法可以不同参

私有属性和私有方法的重写问题:私有属性和方法都不能覆盖,但其实子类可以定义跟父类私有的同名属性或方法。只是当作一个自身的新的属性或方法来看待而已。不过方法的参数必须一致。

最终类final class:

通常,一个类,没有特别声明的话,则“别人”就可以随意拿过来使用并对之进行“扩展”——继承。

但是:

如果某个类不希望对其进行扩展,则可以将其声明为“最终类”。

形式:

final  class  类名{ 。。。。类定义。。。。}

最终方法final method

通常,一个方法,如果没有特别声明,则下级类就可以对其进行“覆盖”(重写)。

但是:

如果某个方法不希望被下级类覆盖,就可以对其生命为“最终方法”。

形式:

final  function  方法名(){。。。。方法定义。。。。}

设计模式

什么叫设计模式

所谓设计模式,就是一些解决问题的“常规做法”,是一种认为较好的经验总结。面对不同的问题,可能会有不同的解决办法,此时就可以称为不同的设计模式。

 

工厂模式

在实际应用中,我们总是需要去实例化很多很多的类——以得到对象。

则:

我们可以设计出一个“工厂”(其实就是类),该工厂的作用(任务)就是为人们“生产”各种对象。这种工厂通常只要指定类名,就可以据此获取一个该类的对象。

单例模式

对于某些类,在使用它的时候,从头到尾(程序运行的开始到结束),都只需要一个对象,就可以完成所有任务。

某个类,只允许其“创建”出一个对象,即使去进行多次创建,也只能得到一个对象。

注意:1、属性私有化

      2、构造私有化

      3、方法私有化

      4、克隆私有化

抽象类,抽象方法

 

抽象类

在正常定义类的前面加上关键字:abstract,就构成抽象类

abstract  class  类名{.....类的定义.....}

抽象类用来规范一些类的共同特性,但不需要对其实例化,专门作为父类

抽象方法:

抽象方法是一个没有方法体(也不含大括号)的方法定义“头”而已。

前面需要加上abstract。

比如:abstract  function  f1($x1, $y, $m) ;

跟抽象类一样,配合抽象类,来实现对下级类的“行为规范”。

即相当于要求下级类去完成该功能(动作),但自己是不做的。

抽象类抽象方法细节关系描述

1,如果一个方法定义为抽象方法,则其所在的类必须定义为抽象类。

2,但,一个抽象类中,可以没有抽象方法——但通常意义不大。

3,子类继承自一个抽象类,则子类必须实现父类中的所有抽象方法,除非子类也继续作为抽象类

4,子类实现抽象父类的方法时,访问控制修饰符的范围不能降低,且方法的参数也须一致——其实这就是重写,所以要满足重写的要求。

Php中的重载技术

属性重载: 如果使用一个不存在的属性,就会去自动调用类中预先定义好的某个方法以处理数据;

方法重载: 如果使用一个不存在的方法,就会去自动调用类中预先定义好的某个方法以处理该行为

属性重载

属性有哪些使用情形?其实跟变量一样,只有4种使用情形:

取值:$v1 = 对象->属性;

赋值:对象->属性 = XX值;

判断是否存在:isset(对象->属性;)

销毁:unset(对象->属性;)

所谓属性重载,就是在面对上述4种情形的属性使用场景中,该对象如果来“应对”的问题。

如果某属性不存在,但在语法中使用如下情形,则会发生:

取值:$v1 = 对象->属性;              ===>自动调用类中的__get()方法

赋值:对象->属性 = XX值;           ===>自动调用类中的__set()方法

判断是否存在:isset(对象->属性;)     ===>自动调用类中的__isset()方法

销毁:unset(对象->属性;)                ===>自动调用类中的__unset()方法

前提都是:类中要预先定义好这些方法。

方法重载

当使用一个对象调用一个不存在的普通方法的时候,会自动去调用预先定义好的"__call"方法。

其中,该方法必须带2个参数

当使用一个对象(类)调用一个不存在的静态方法的时候,会自动去调用预先定义好的"__callStatic"方法。

其中,该方法必须带2个参数。其实跟前面一样!

魔术方法:__get(), __set(),  __isset(), __unset(),  __call(),  __callstatic();

 

posted on 2018-03-06 21:16  啦噜噜  阅读(170)  评论(1编辑  收藏  举报