ホームページ  >  記事  >  php教程  >  PHP V5 でオブジェクトを使ってみる

PHP V5 でオブジェクトを使ってみる

WBOY
WBOYオリジナル
2016-06-21 09:07:55789ブラウズ

对象

    本文描述 PHP V5 中对象和类的基础知识,从最基本的概念一直讲到继承,主要针对经验丰富的面向对象程序员和尚未接触过对象的读者。

  作为 PHP 程序员,您肯定知道变量和函数。但类和对象可能就是另一回事。不定义单个类,就可以创建完美的系统。但即使您决定在自己的代码中不使用面向对象的编程,您仍可能需要了解面向对象的编程。例如,如果使用第三方库,比如通过 PHP Extension and Application Repository (PEAR) 可以使用的库,您将发现自己在实例化对象和调用方法。

  什么是类和对象?

  简单地说,类 是一个由变量和方法组成的独立块或束。这些组件通常结合实现单个责任或一组责任。在本文中,您将创建一个类,该类收集了用于查询和填充由项和值组成的词典的方法。

  类可以直接用作组织数据和功能的简单方法,就像一组函数和变量一样。但使用类可以忽略它的存在。类可用于在内存中生成多个实例。这样的实例叫做对象。每个对象可以访问一组相同的函数(在面向对象上下文中叫做方法)和变量(叫做特性或实例变量),但每个变量的实际值在每个对象中是不同的。

  考虑角色扮演游戏中的一个单元——比如坦克。类可能为坦克设置一组变量:防御和进攻能力,范围,健康状况,等等。该类也可能定义一组函数,其中包括 move() 和 attack()。当系统包含一个坦克类时,该类可用于生成数十个或数百个坦克对象,每个对象都潜在地具有自己的健康状况或范围特征。因此,类是用于生成对象的蓝图或模板。

  理解类和对象最简单的方法可能就是创建一些类和对象。

  第一个类

  可以用 class 关键字创建类。最简单的情况是,类由关键字类、名称和代码块组成:

class Dictionary {
}

  类名可以包含字母、数字和下划线字符的任何组合,但不能以数字打头。

  上例中的 Dictionary 类尽管用处有限,但完全合法。那么如何使用该类来创建一些对象呢?

$obj1 = new Dictionary();
$obj2 = new Dictionary();
$obj3 = new Dictionary();

  至少在形式上,实例化对象与调用函数相似。对于函数调用,必须提供圆括号。与函数一样,一些类需要您为其传递参数。您还必须使用 new 关键字。这就告诉 PHP 引擎您希望实例化一个新对象。然后,返回的对象可以存储在一个变量中以供将来使用。

  属性

  在类的主体中,可以声明叫做属性的特殊变量。在 PHP V4 中,属性必须用关键字 var 调用。这仍是合法的语法,但主要是为了向后兼容。在 PHP V5 中,属性必须声明为 public、private 或 protected。可以在 关键字:在此我们是否可以有一点隐私?中阅读有关这些限定词的内容。但现在在例子中将所有属性声明为 public。清单 1 显示一个声明了两个属性的类。

  清单 1. 声明两个属性的类

class Dictionary {
    public $translations = array();
    public $type ="En";
}

  正如所看到的,可以同时声明属性并为其赋值。可以用 print_r() 函数快速浏览一下对象的状态。清单 2 显示 Dictionary 对象现在具有更多成员。

  清单 2. Dictionary 对象一览

$en = new Dictionary();
print_r( $en ); 

  如果运行该脚本,将看到如下对象的输出:

Dictionary Object
(
    [translations] => Array
        (
        )
    [type] => En
)

  可以使用对象操作符 -> 访问公共对象属性。所以 $en->type 表示由 $en 引用的 Dictionary 对象的 $type 属性。如果可以访问属性,就意味着可以设置和获得其值。清单 3 中的代码创建 Dictionary 类的两个实例 —— 换言之,它实例化两个 Dictionary 对象。它更改一个对象的 $type 属性,并添加两个对象的翻译:

  清单 3. 创建 Dictionary 类的两个实例

$en = new Dictionary();
$en->translations['TREE'] = "tree";
$fr = new Dictionary();
$fr->type = "Fr";
$fr->translations['TREE'] = "arbre";
foreach ( array( $en, $fr ) as $dict ) {
    print "type: {$dict->type} ";
    print "TREE: {$dict->translations['TREE']}\n";

  该脚本输出如下

type: En TREE: tree
type: Fr TREE: arbre

  所以 Dictionary 类现在比较有用了。单个对象可以存储不同的键值组合,还有一个标志,该标志告诉客户端有关这种 Dictionary 的详细信息。

  尽管 Dictionary 类当前与关联数组的包装器相差无几,但这里有一些了解对象功能的线索。目前,我们已经可以很好地表示我们的示例数据了,如清单 4 所示。

  清单 4. 示例数据

$en = array(
    'translations'=>array( 'TREE' => 'tree' ),
    'type'=>'En'
);
$fr = array(
    'translations'=>array( 'TREE' => 'arbre' ),
    'type'=>'Fr'
);

  虽然该数据结构完成了与 Dictionary 类相同的目的,但它没有提供结构的保证。如果传递 Dictionary 对象,我们知道它具有 $translations 属性。但如果是一个关联数据,则没有这样的保证。这个事实使得类似 $fr['translations']['TREE']; 的查询有些碰运气,除非进行查询的代码确定数组的起源。这是对象的重点:对象的类型是其特征的保证。

  虽然用对象存储数据有优点,但是您可能没有一点感觉。对象可以是东西,但关键在于它们还可以做事情。

  方法

  简单地说,方法是在类中声明的函数。它们通常(但不总是)通过对象实例使用对象操作符来调用的。清单 5 向 Dictionary 类中添加一个方法,并调用该方法。

  清单 5. 向 Dictionary 类中添加方法

class Dictionary {
    public $translations = array();
    public $type ="En";
    function summarize() {
        $ret  = "Dictionary type: {$this->type}\n";
        $ret .= "Terms: ".count( $this->translations )."\n";
        return $ret;
    }
}
$en = new Dictionary();
$en->translations['TREE'] = "tree";
print $en->summarize();

  它提供如下输出:

Dictionary type: En
Terms: 1

  正如所看到的,声明 summarize() 方法与声明任何函数的方式一样,只不过它是在类中声明。summarize() 方法是通过 Dictionary 实例使用对象操作符调用的。summarize() 函数访问属性来提供对象状态的简述。

  注意对于本文来说的一个新特性的用法。$this 伪变量提供了一种用于对象引用自己的属性和方法的机制。在对象外部,可以使用句柄来访问它的元素(在本例子中是 $en)。在对象内部,则无此句柄,所以必须求助于 $this。如果觉得 $this 有些迷惑,则在代码中遇到它时,试着在头脑中用当前实例 替换它。

  类通常使用通用建模语言 (Universal Modeling Language,UML) 表示在图表中。UML 的详细信息超出了本文的范围,但这种图表不过是一种可视化类关系的好方法。图 1 显示用 UML 表示的 Dictionary 类。类名位于顶层,属性在中间,方法在底层。

图 1. 使用 UML 显示 Dictionary 类

  构造函数

  PHP 引擎识别许多“魔术”方法。如果定义了方法,则 PHP 引擎将在相应的情况发生时自动调用这些方法。最常实现的方法是构造函数方法。PHP 引擎在实例化对象时调用构造函数。对象的所有基本设置代码都放在构造函数中。在 PHP V4 中,通过声明与类同名的方法来创建构造函数。在 V5 中,应声明叫做 __construct() 的方法。清单 6 显示需要 DictionaryIO 对象的构造函数。

  清单 6. 需要 DictionaryIO 对象的构造函数

class Dictionary {
    public $translations = array();
    public $type;
    public $dictio;
    function __construct( $type, DictionaryIO $dictio ) {
        $this->type = $type;
        $this->dictio=$dictio;
    }
    //...

Dictionary オブジェクトをインスタンス化するには、型文字列と DictionaryIO オブジェクトをそのコンストラクターに渡します。コンストラクターはこれらのパラメーターを使用して独自のプロパティを設定します。次のコードは、Dictionary オブジェクトをインスタンス化する方法を示しています: $en = new Dictionary( "En", new DictionaryIO() );
Dictionary クラスは以前より安全になりました。すべての Dictionary オブジェクトは、必要なパラメータで初期化されています。

もちろん、誰かが後で $type 属性を変更したり、$dictio を空に設定したりすることを妨げるものは何もありません。良いニュースとしては、PHP V5 がこの機能の実現に役立つということです。

キーワード:ここで少しプライバシーを保ってもいいですか?

先ほど財産申告に関連する公開キーワードを見てきました。このキーワードは属性の可視性を表します。実際、プロパティの可視性はパブリック、プライベート、保護に設定できます。 public として宣言されたプロパティは、クラスの外部から読み書きできます。private として宣言されたプロパティは、オブジェクトまたはクラスのコンテキストでのみ表示されます。 protected として宣言されたプロパティは、現在のクラスとそのサブクラスのコンテキスト内でのみ表示されます。 (これは「継承」セクションで実際に動作しているのがわかります。) プライベート プロパティを使用して、クラスを実際にロックダウンすることができます。プロパティをプライベートとして宣言し、クラス スコープの外からアクセスしようとすると (リスト 7 を参照)、PHP エンジンは致命的なエラーをスローします。

リスト 7. クラススコープ外からプロパティへのアクセスを試みる

class Dictionary {
private $translations = array();
private $dictio;
private $type;
function __construct( $type, DictionaryIO $dictio ) {
$ this->type = $type;
出力は次のとおりです: Fatal error: Cannot access private property
Dictionary::$dictio in...
一般的に言えば、ほとんどのプロパティはprivateとして宣言する必要があります。 、必要に応じてこれらのプロパティを取得および設定するためのメソッドを提供します。これにより、クラスのインターフェイスを制御したり、一部のデータを読み取り専用にしたり、パラメーターをプロパティに割り当てる前にパラメーターをサニタイズまたはフィルターしたり、オブジェクトと対話するための明確なルール セットを提供したりすることができます。
メソッドの可視性を変更する方法は、プロパティの可視性を変更する方法と同じで、メソッド宣言に public、private、または protected を追加します。クラスが外部に知られる必要のないハウスキーピング メソッドを使用する必要がある場合、そのクラスをプライベートとして宣言できます。リスト 8 の get() メソッドは、Dictionary クラスのユーザーに翻訳を取得するためのインターフェースを提供します。このクラスはすべてのクエリを追跡する必要があるため、プライベート メソッド logQuery() が提供されています。
リスト 8. get() メソッドは、Dictionary クラスのユーザーにインターフェースを提供します
function get( $term ) {

$value = $this->translations[$term];
$this->logQuery( $ term, $value, "get" );
return $value;

}

private function logQuery( $term, $value, $kind ) {

// ログ情報を書き込みます
}

logQuery() を private として宣言すると、パブリック インターフェイスを使用し、クラスが logQuery() を不適切に呼び出すことを防ぎます。プロパティと同様に、含まれているクラスの外部からプライベート メソッドを呼び出そうとすると、致命的なエラーが発生します。



[1] [2] 次のページ

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。