PHP面向对象v1:

来源:互联网 发布:用单片机实现电子音响 编辑:程序博客网 时间:2024/04/29 23:24

 

-------------------------------------------------

1. 接口使用关键字 interface 来定义,并使用关键字 implements 来实现接口中的方法,且必须完全实现。

 

2. final 关键字用于定义类和方法,该关键字表示该类或方法为最终版本,即该类不能被继承,或该方法在子类中不能被重载(覆盖)。

 

3. static静态类或方法, 声明类成员或方法为 static ,就可以不实例化类而直接访问,不能通过一个对象来访问其中的静态成员(静态方法除外)。静态成员属于类,不属于任何对象实例,但类的对象实例都能共享。

实例:

Class Person{
    public static $coutry = "china";
    public static function myCountry()
    {
        echo "Mycountry is :".self::$country;
    }
}
Class Student extends Person{
    public study()
    {
        ehco "Mycountry is :".parent::$country;
    }
}
echo Person::$country;
$p1 = new Person();

 

4. 范围解析操作符(::), 是一对冒号,可以用于访问静态成员、方法和常量,以及被覆盖类中的成员和方法。

 

5. __set() 方法用于设置私有属性值,
    __get() 方法用于获取私有属性值,
    __isset() 方法用于检测私有属性值是否被设定,
    __unset() 方法用于删除私有属性。

 

6. const, 类里面定义常量用 const 关键字,而不是通常的 define() 函数。

 

7. 重载, 一个类中的方法与另一个方法同名,但是参数不同,这种方法称之为重载方法。PHP是弱类型的语言,没有严格意义上的方法重载。

 

8. __call方法用于监视错误的方法调用。有两个参数,第一个参数 $function_name 会自动接收不存在的方法名,第二个 $args 则以数组的方式接收不存在方法的多个参数。

function __call($function_name, $args)

{

echo "你所调用的函数:$function_name(参数:<br />";

var_dump($args);

echo ")不存在!";

}

9. abstract关键字用于定义抽象方法和抽象类。只要一个类里面有一个方法是抽象方法,那么这个类就要定义为抽象类。

抽象类不能产生实例对象,通常是将抽象方法做为子类方法重载的模板使用的,且要把继承的抽象类里的方法都实现。实际上抽象类是方便继承而引入的。

 

10. clone关键字用于克隆一个完全一样的对象,__clone方法来重写原本的属性和方法。克隆以后,两个对象互不干扰。

$p1 = new Person("张三", 20);

$p2 = clone $p1;

$p2->say();

 

如果想在克隆后改变原对象的内容,需要在类中添加一个特殊的 __clone() 方法来重写原本的属性和方法。__clone() 方法只会在对象被克隆的时候自动调用。

class Person {

private $name;

    private $age;

    function __construct($name, $age) {
        $this->name = $name;
        $this->age = $age;
    }

    function say() {
        echo "我的名字叫:".$this->name;
    echo " 我的年龄是:".$this->age."<br />";
    }
    function __clone() {
        $this->name = "我是假的".$this->name;
        $this->age = 30;
    }
}

$p1 = new Person("张三", 20);
$p1->say();
$p2 = clone $p1;
$p2->say();

 



-------------------------------------------------

PHP面向对象:

 

1.func_num_args()  Returns the number of arguments passed to the function

例子:

function foo(){
    $numargs = func_num_args();
    echo "Number of arguments: $numargs/n";
}
foo(1,2,3);

 

2.func_num_arg(n) 获取传递给当前函数的第n个参数的值

例子:

<?php

class Test {

   function insertUser() {

       // gets the number of parameters
       $numArgs = func_num_args();
      
       // make decisions based on the arguments number
       if ($numArgs == 1) {
           // if it's only one argument, we suppose that it is an array with user info
          
           // gets the first argument
           $user = func_get_arg(0);
          
           // checks if it really is an array
           if (is_array($user)) {
              
               // here you should check if the array contains all necessary fields
              
               // adds the user

               echo "User added.<br/>";
               echo "ID: " . $user["id"] . "<br/>";
               echo "NAME: " . $user["name"] . "<br/>";
               echo "EMAIL: " . $user["email"] . "<br/>";
              
           } else {
              
               // generates an error if argument is not an array
               echo "Argument is not an array: " . $user . ".<br/>";
              
           }
          
       } else if ($numArgs == 3) {
           // if the function receives 3 arguments, we assume that they
           // are 'id', 'name' and 'email' respectively
          
           // inserts the user into the system

           echo "User added.<br/>";
           echo "ID: " . func_get_arg(0) . "<br/>";
           echo "NAME: " . func_get_arg(1) . "<br/>";
           echo "EMAIL: " . func_get_arg(2) . "<br/>";
                      
       } else {
          
           // if the number of arguments is different from 1 and 3
           // an error will be generated

          
           echo "Wrong argument number.<br/>";
           echo "Arguments received: " . func_num_args();
          
       }
   }

}

// creates an Test object
$objTest = new Teste();

// inserts an user passing an array with all his info
$objTest->insertUser(array("id" => 1, "name" => "George W. Bush", "email" => "jackass@whitehouse.gov"));

echo "<br/>";

// inserts an user providing each attribute as a single argument
$objTest->insertUser(2, "Vicente Fox", "iloveusa@disney.com");

echo "<br/>";

// this will generate an error, because only 2 arguments were passed
$objTest->insertUser(3, "Tony Blair");

?>

------------------------------------------------------------------------------------------------------------------------------------------------

 

3.

bool is_a ( object object, string class_name )  如果对象属于该类或该类是此对象的父类则返回 TRUE

bool is_executable ( string filename )  判断给定文件名是否可执行

 

void clearstatcache ( void ) 清除文件状态缓存

file_exists()  来检查不存在的文件

is_readable(),

is_writable(),

is_excutable(),

is_file(),

is_dir(),

is_link(),

 

filectime() 取得文件的 inode 修改时间,

fileatime() 取得文件的上次访问时间,

filemtime() 取得文件修改时间,

 

fileinode() 取得文件的 inode,

filegroup() 取得文件的组

fileowner()

 

filesize()

filetype()

fileperms()

 


is_numeric(),  is_int(),  is_integer(),  is_long(), is_nan(),  is_array(),  is_binary(),  is_bool(),  is_dir(), is_double(), is_float(),  is_real(),  is_null(), is_resource(), 

is_set()检查变量是否定义, 

unset(),

empty() 检查一个变量是否为空,

 

strlen(), count(),

 

array_key_exists -- 检查给定的键名或索引是否存在于数组中

<?php
$search_array = array('first' => null, 'second' => 4);

// returns false
isset($search_array['first']);

// returns true
array_key_exists('first', $search_array);
?>

 

 

4.var_dump -- 打印变量的相关信息,包括表达式的类型与值。


5.常量

   1. 扩展阅读:
   2. 常量前面没有美元符号($);
   3. 常量只能用 define() 函数定义,而不能通过赋值语句;
   4. 常量可以不用理会变量范围的规则而在任何地方定义和访问;
   5. 常量一旦定义就不能被重新定义或者取消定义;
   6. 常量的值只能是标量;
   7. 常量只能包含标量数据(boolean,integer,float 和 string),不要定义 resource常量.
   8. 可以用函数 constant() 来读取常量的值.get_defined_constants()可以获得所有已定义的常量列表.
   9. 如果使用了一个未定义的常量,PHP 假定想要的是该常量本身的名字,如同用字符串调用它一样(CONSTANT 对应 “CONSTANT”),此时将发出一个 E_NOTICE 级的错误.
  10. PHP 的“魔术常量”.

 

__LINE__ 文件中的当前行号。

__FILE__ 文件的完整路径和文件名。如果用在包含文件中,则返回包含文件名。自 PHP 4.0.2 起,__FILE__ 总是包含一个绝对路径,而在此之前的版本有时会包含一个相对路径。

__FUNCTION__ 函数名称(PHP 4.3.0 新加)。自 PHP 5 起本常量返回该函数被定义时的名字(区分大小写)。在 PHP 4 中该值总是小写字母的。

__CLASS__ 类的名称(PHP 4.3.0 新加)。自 PHP 5 起本常量返回该类被定义时的名字(区分大小写)。在 PHP 4 中该值总是小写字母的。

__METHOD__ 类的方法名(PHP 5.0.0 新加)。返回该方法被定义时的名字(区分大小写)。

 

----------------------------------------------------------------------------------------------

6.多态

对于面向对象的程序来说,多态就是把子类对象赋值给父类引用,然后调用父类的方法,去执行子类覆盖父类的那个方法,但在PHP 里是弱类型的,对象引用都是一样的不分父类引用,还是子类引用。

 

interface,  class, implements,  extends,  __construct,  __destruct,  ::,   ->,  

protected,  public,  static

this,  self,  parent

 

----------------------------------------------------------------------------------------------

19.抽象方法和抽象类

在OOP语言中,一个类可以有一个或多个子类,而每个类都有至少一个公有方法做为外部代码访问其的接口。而抽象方法就是为了方便继承而引入的,我们先来看一下抽象类和抽象方法的定义再说明它的用途.

什么是抽象方法?我们在类里面定义的没有方法体的方法就是抽象方法,所谓的没有方法体指的是,在方法声明的时候没有大括号以及其中的内容,而是直接在声明时在方法名后加上分号结束,另外在声明抽象方法时还要加一个关键字“abstract”来修饰;
例如:
abstract function fun1();
abstract function fun2();

上例是就是“abstract”修饰的没有方法体的抽象方法“fun1()”和“fun2()”,不要忘记抽象方法后面还要有一个分号;那么什么是抽象类呢?只要一个类里面有一个方法是抽象方法,那么这个类就要定义为抽象类,抽象类也要使用“abstract”关键字来修饰;在抽象类里面可以有不是抽象的方法和成员属性,但只要有一个方法是抽象的方法,这个类就必须声明为抽象类,使用”abstract”来修饰。

例如:
abstract class Demo
{
     
var $test;


abstract function fun1();
abstract function fun2();
function fun3()
{

….
}
}

上例中定义了一个抽象类“Demo”使用了”abstract”来修饰, 在这个类里面定义了一个成员属性“$test”,和两个抽象方法“fun1”和“fun2”还有一个非抽象的方法fun3();那么抽象类我们怎么使用呢?最重要的一点就是抽象类不能产生实例对象,所以也不能直接使用,前面我们多次提到过类不能直接使用,我们使用的是通过类实例化出来的对象,那么抽象类不能产生实例对象我们声明抽象类有什么用呢?我们是将抽象方法是做为子类重载的模板使用的,定义抽象类就相当于定义了一种规范,这种规范要求子类去遵守,子类继函抽象类之后,把抽象类里面的抽象方法按照子类的需要实现。子类必须把父类中的抽象方法全部都实现,否则子类中还存在抽象方法,那么子类还是抽象类,还是不能实例化对;为什么我们非要从抽象类中继承呢?因为有的时候我们要实现一些功能就必须从抽象类中继承,否则这些功能你就实现不了,如果继承了抽象类,就要实现类其中的抽象方法;
abstract class Demo
{
var $test;

abstract function fun1();
abstract function fun2();
function fun3()
{

….
}
}

$demo=new Demo();

//抽象类为能产生实例对象,所以这样做是错的,实例化对象交给子类

class Test extends Demo
{
    function fun1()

{


}


function fun2()
{


}
}

$test=new Test();
//子类可以实例化对象,因为实现了父类中所有抽象方法
?>

----------------------------------------------------------------------------------------------
20. php5接口技术

       PHP与大多数面向对象编程语言一样,不支持多重继承.也就是说每个类只能继承一个父类.为了解决这个问题,PHP引入了接口,接口的思想是指定了一个实现了该接口的类必须实现的一系列方法.接口是一种特殊的抽象类,抽象类又是一种特殊的类,所以接口也是一种特殊的类,为什么说接口是一种特殊的抽象类呢?如果一个抽象类里面的所有的方法都是抽象方法,那么我们就换一种声明方法使用“接口“;也就是说接口里面所有的方法必须都是声明为抽象方法,另外接口里面不能声明变量,而且接口里面所有的成员都是public权限的。所以子类在实现的时候也一定要使用public权限实限。
声明一个类的时候我们使用的关键字是”class”,而接口一种特殊的类,使用的关键字是“interface”;
类的定义:  class 类名{ … } ,接口的声明:interface 接口名{ …}
       //定义一个接口使用interface关键字,“One”为接口名称

interface One
{

//定义一个常量
const constant = 'constant value';


//定义了一个抽象方法”fun1”

public function fun1();


//定义了抽象方法”fun2”

public function fun2();

}
?>
上例中定义了一个接口”one”,里面声明了两个抽象方法“fun1”和”fun2”,因为接口里面所有的方法都是抽象方法,所以在声明抽象方法的时候就不用像抽象类那样使用”abstract”这个关键字了,默认的已经加上这个关键字,另外在接口里边的”public”这个访问权限也可以去掉,因为默认就是public的,因为接口里所有成员都要是公有的,所在对于接口里面的成员我们就不能使用“private”的和”protected”的权限了,都要用public或是默认的。另外在接口里面我们也声明了一个常量“constant“, 因为在接口里面不能用变量成员,所以我们要使用const这个关键字声明。
因为接口是一种特殊的抽象类,里面所有的方法都是抽象方法,所以接口也不能产生实例对象; 它也做为一种规范,所有抽象方法需要子类去实现。
     
我们可以使用”extends”关键字让一个接口去继承另一个接口;

//使用”extends”继承另外一个接口
interface Two extends One
{

function fun3();

function fun4();

}
?>
而我们定义一接口的子类去实现接口中全部抽象方法使用的关键字是”implements”,而不是我们前面所说的”extends”;


//使用“implements”这个关键字去实现接口中的抽象方法

class Three implements One
{

function fun1()

{

….

}


function fun2()
{

….

}

}

//实现了全部方法,我们去可以使用子类去实例化对象了

$three=new Three();
?>

我们也可以使用抽象类,去实现接口中的部分抽象方法,但要想实例化对象,这个抽象类还要有子类把它所有的抽象方法都实现才行;
在前面我们说过,PHP是单继承的,一个类只能有一父类,但是一个类可以实现多个接口,就相当于一个类要遵守多个规范,就像我们不仅要遵守国家的法律,如果是在学校的话,还要遵守学校的校规一样;

//使用implements实现多个接口
class Four implemtns 接口一, 接口二, ….
{

//必须把所有接口中的方法都要实现才可以实例化对象。
}
?>

PHP中不仅一个类可以实现多个接口,也可以在继承一个类的同时实现多个接口, 一定要先继承类再去实现接口;

//使用extends继承一个类,使用implements实现多个接口
class Four extends 类名一 implemtns 接口一, 接口二, ….
{

//所有接口中的方法都要实现才可以实例化对象
………..
}
?>
----------------------------------------------------------------------------------------------

21.多态的应用

       多态是除封装和继承之外的另一个面象对象的三大特性之一,我个人看来PHP中虽然可以实现多态,但和c++还有Java这些面向对象的语言相比,多态性并不是那么突出,因为PHP本身就是一种弱类型的语言,不存在父类对象转化为子类对象或者是子类对象转化为父类对象的问题,所以多态的应用并不是那么的明显;所谓多态性是指一段程序能够处理多种类型对象的能力,比如说在公司上班,每个月财务发放工资,同一个发工资的方法,在公司内不同的员工或是不同职位的员工,都是通过这个方法发放的,但是所发的工资都是不相同的。所以同一个发工资的方法就出现了多种形态。对于面向对象的程序来说,多态就是把子类对象赋值给父类引用,然后调用父类的方法,去执行子类覆盖父类的那个方法,但在PHP里是弱类型的,对象引用都是一样的不分父类引用,还是子类引用。
我们现在来看一个例子,首先还是要使用多态就要有父类对象和子类对象的关系。做一个形状的接口或是抽象类做为父类,里面有两个抽象方法,一个求周长的方法,另一个是求面积的方法;这接口的子类是多种不同的形状,每个形状又都有周长和面积,又因为父类是一个接口,所以子类里面就必须要实现父类的这两个周长和面积的抽象方法,这样做的目的是每种不同形状的子类都遵守父类接口的规范,都要有求周长和求面积的方法。
<?

//定义了一个形状的接口,里面有两个抽象方法让子类去实现

interface Shape
{

function area();

function
perimeter();

}


//定义了一个矩形子类实现了形状接口中的周长和面积

class Rect implements Shape
{

private $width;

private $height;


function __construct($width, $height)
{

$this->width=$width;

$this->height=$height;

}


function area()
{

return "矩形的面积是:".($this->width*$this->height);

}



function perimeter()
{

return "矩形的周长是:".(2*($this->width+$this->height));

}

}

//定义了一个圆形子类实现了形状接口中的周长和面积

class Circular implements Shape
{
private $radius;

function __construct($radius)
{

$this->radius=$radius;

}


function area()
{

return "圆形的面积是:".(3.14*$this->radius*$this->radius);

}



function perimeter()
{

return "圆形的周长是:".(2*3.14*$this->radius);

}

}




//把子类矩形对象赋给形状的一个引用

$shape=new Rect(5, 10);

echo $shape->area()."<br>";

echo $shape->perimeter()."<br>";


//把子类圆形对象赋给形状的一个引用

$shape=new Circular(10);

echo $shape->area()."<br>";

echo $shape->perimeter()."<br>";
?>
上例执行结果:
矩形的面积是:50
矩形的周长是:30
圆形的面积是:314
圆形的周长是:62.8

       通过上例我们看到,把矩形对象和圆形对象分别赋给了变量$shape, 调用$shape引用中的面积和周长的方法,出现了不同的结果,这就是一种多态的应用,其实在我们PHP这种弱类形的面向对象的语言里面,多态的特性并不是特别的明显,其实就是对象类型变量的变项应用。

----------------------------------------------------------------------------------------------

22.把对象串行化

        有时候需要把一个对象在网络上传输,为了方便传输,可以把整个对象转化为二进制串,等到达另一端时,再还原为原来的对象,这个过程称之为串行化, 就像我们现在想把一辆汽车通过轮船运到美国去,因为汽车的体积比较大,我们可以把汽车拆开成小的部件,然后我们把这些部件通过轮般运到美国去,到了美国再把这些部件组装回汽车。
有两种情况我们必须把对象串行化,第一种情况就是把一个对象在网络中传输的时候要将对象串行化,第二种情况就是把对象写入文件或是数据库的时候用到串行化。
        串行化有两个过程,一个是串行化,就是把对象转化为二进制的字符串,我们使用serialize()函数来串行化一个对象,另一个是反串行化,就是把对象转化的二进制字符串再转化为对象, 我们使用unserialize()函数来反串行化一个对象.
        PHP中serialize()函数的参数为对象名,返回值为一个字符串,Serialize()返回的字符串含义模糊,一般我们不会解析这个串来得到对象的信息,我们只要把返回来的这个字符串传到网络另一端或是保存到方件中即可。
PHP中unserialize()函数来反串行化对象,这个函数的参数即为serialize()函数的返回值,输出当然是重新组织好的对象.
<?
class Person
{

//下面是人的成员属性

var $name;
//人的名子

var $sex;
//人的性别

var $age;
//人的年龄

//定义一个构造方法参数为属性姓名$name、性别$sex和年龄$age进行赋值

function __construct($name="", $sex="", $age="")
{

$this->name=$name;

$this->sex=$sex;

$this->age=$age;

}

//这个人可以说话的方法, 说出自己的属性

function say()
{

echo "我的名子叫:".$this->name." 性别:".$this->sex." 我的年龄是:".$this->age."<br>";

}

}


$p1=new Person("张三", "男", 20);

$p1_string=serialize($p1); //把一个对象串行化,返一个字符串

echo $p1_string."<br>";
//串行化的字符串我们通常不去解析

$p2=unserialize($p1_string);
//把一个串行化的字符串反串行化形成对象$p2

$p2->say();

?>
上例输出结果:
O:6:"Person":3:{s:4:"name";s:4:"张三";s:3:"sex";s:2:"男";s:3:"age";i:20;}
我的名子叫:张三 性别:男 我的年龄是:20

在 php5中有两个魔术方法__sleep()方法和__wakeup()方法,在对象串行化的时候,会调用一个__sleep()方法来完成一些睡前的事情;而在重新醒来,即由二进制串重新组成一个对象的时候,则会自动调用PHP的另一个函数__wakeup(),做一些对象醒来就要做的动作。
__sleep()函数不接受任何参数, 但返回一个数组,其中包含需要串行化的属性。末被包含的属性将在串行化时被忽略,如果没有__sleep()方法,PHP将保存所有属性。

<?
class Person
{

//下面是人的成员属性

var $name;
//人的名子

var $sex;
//人的性别

var $age;
//人的年龄

//定义一个构造方法参数为属性姓名$name、性别$sex和年龄$age进行赋值

function __construct($name="", $sex="", $age="")
{

$this->name=$name;

$this->sex=$sex;

$this->age=$age;

}


//这个人可以说话的方法, 说出自己的属性

function say()
{

echo "我的名子叫:".$this->name." 性别:".$this->sex." 我的年龄是:".$this->age."<br>";

}

  
//指定串行化时把返回的数组中$name和$age值串行化,忽略没在数组中的属性$sex

function __sleep() {

$arr=array("name", "age");

return($arr);

}


//重新生成对象时,并重新赋值$age为40

function __wakeup() {


$this->age = 40;

}

}


$p1=new Person("张三", "男", 20);

//把一个对象串行化,返一个字符串,调用了__sleep()方法,忽略没在数组中的属性$sex
$p1_string=serialize($p1);
echo $p1_string."<br>";
//串行化的字符串我们通常不去解析

$p2=unserialize($p1_string); //反串行化形成对象$p2重新赋值$age为40

$p2->say();
?>
上例输出值为:
O:6:"Person":2:{s:4:"name";s:4:"张三";s:3:"age";i:20;}
我的名子叫:张三 性别: 我的年龄是:40

----------------------------------------------------------------------------------------------
23.自动加载类

      很多开发者写面向对象的应用程序时,对每个类的定义建立一个 PHP 源文件。一个很大的烦恼是不得不在每个脚本(每个类一个文件)开头写一个长长的包含文件的列表。
       在软件开发的系统中,不可能把所有的类都写在一个PHP文件中,当在一个PHP文件中需要调用另一个文件中声明的类时,就需要通过include把这个文件引入。不过有的时候,在文件众多的项目中,要一一将所需类的文件都include进来,是一个很让人头疼的事,所以我们能不能在用到什么类的时候,再把这个类所在的php文件导入呢?这就是我们这里我们要讲的自动加载类。
在 PHP 5 中,可以定义一个 __autoload()函数,它会在试图使用尚未被定义的类时自动调用,通过调用此函数,脚本引擎在 PHP 出错失败前有了最后一个机会加载所需的类, __autoload()函数接收的一个参数,就是你想加载的类的类名,所以你做项目时,在组织定义类的文件名时,需要按照一定的规则,最好以类名为中心,也可以加上统一的前缀或后缀形成文件名,比如xxx_classname.php、classname_xxx.php以及就是 classname.php等等.

本例尝试分别从 MyClass1.php 和 MyClass2.php 文件中加载 MyClass1 和 MyClass2 类
<?php

function __autoload($classname)
{
    require_once $classname . '.php';
}

//MyClass1类不存在自动调用__autoload()函数,传入参数”MyClass1”
$obj  = new MyClass1();

//MyClass2类不存在自动调用__autoload()函数,传入参数”MyClass2”
$obj2 = new MyClass2();
?>