ホームページ  >  記事  >  バックエンド開発  >  PHPのコンストラクターの継承解析

PHPのコンストラクターの継承解析

黄舟
黄舟オリジナル
2017-07-02 10:02:051674ブラウズ

コンストラクター使用法

HP 5 では、開発者がクラス内のコンストラクターとしてメソッドを定義できます。コンストラクターを持つクラスは、新しいオブジェクトが作成されるたびにこのメソッドを呼び出すため、オブジェクトを使用する前に初期化作業を行うのに非常に適しています。

注: コンストラクターがサブクラスで定義されている場合、その親クラスのコンストラクターは暗黙的に呼び出されません。親クラスのコンストラクターを実行するには、子クラスのコンストラクターでparent::construct()を呼び出す必要があります。サブクラスでコンストラクターが定義されていない場合、通常のクラス メソッドと同様に親クラスから継承されます (プライベートとして定義されていない場合)。
例 #1 新しい標準コンストラクターの使用

<?php
class BaseClass {
   function construct() {
       print "In BaseClass constructorn";
   }
}
class SubClass extends BaseClass {
   function construct() {
       parent::construct();
       print "In SubClass constructorn";
   }
}
class OtherSubClass extends BaseClass {
    // inherits BaseClass&#39;s constructor
}
// In BaseClass constructor
$obj = new BaseClass();
// In BaseClass constructor
// In SubClass constructor
$obj = new SubClass();
// In BaseClass constructor
$obj = new OtherSubClass();
?>

下位互換性のため、PHP 5 がクラス内でconstruct() 関数を見つけられず、親クラスから関数を継承していない場合は、古いスタイルのコンストラクターを見つけようとします。つまり、クラスと同じ名前の関数です。したがって、互換性の問題が発生するのは、クラスに既にconstruct()という名前のメソッドがあり、それが他の目的に使用されている場合だけです。

他のメソッドとは異なり、親クラスのconstruct()とは異なるパラメータを持つメソッドによってconstruct()がオーバーライドされた場合、PHPはE_STRICTエラーメッセージを生成しません。

PHP 5.3.3 以降、名前空間 では、クラス名と同じ名前のメソッドはコンストラクターとして使用されなくなりました。この変更は、名前空間にないクラスには影響しません。

例 #2 名前空間クラスのコンストラクター

<?php
namespace Foo;
class Bar {
    public function Bar() {
        // treated as constructor in PHP 5.3.0-5.3.2
        // treated as regular method as of PHP 5.3.3
    }
}
?>

オブジェクトの作成時に初期値を割り当てます。

1. //创建一个人类  
2.  
3. 0class Person   
4. 0{   
5. //下面是人的成员属性   
6. var $name;       //人的名子   
7. var $sex;        //人的性别   
8. var $age;        //人的年龄   
9. //定义一个构造方法参数为姓名$name、性别$sex和年龄$age   
10. function construct($name, $sex, $age)   
11. {   
12. //通过构造方法传进来的$name给成员属性$this->name赋初使值   
13. $this->name=$name;   
14. //通过构造方法传进来的$sex给成员属性$this->sex赋初使值   
15. $this->sex=$sex;   
16. //通过构造方法传进来的$age给成员属性$this->age赋初使值   
17. $this->age=$age;   
18. }   
19. //这个人的说话方法   
20. function say()   
21. {  
22. echo "我的名子叫:".$this->name." 性别:".$this->sex." 我的年龄是:".$this->age."<br>";   
23. }   
24. }   
25. //通过构造方法创建3个对象$p1、p2、$p3,分别传入三个不同的实参为姓名、性别和年龄  
26. $p1=new Person("张三","男", 20);   
27. $p2=new Person("李四","女", 30);   
28. $p3=new Person("王五","男", 40);   
29. //下面访问$p1对象中的说话方法   
30. $p1->say();   
31. //下面访问$p2对象中的说话方法   
32. $p2->say();   
33. //下面访问$p3对象中的说话方法   
34. $p3->say();

出力結果は次のとおりです:

私の名前: Zhang San 性別: 男性 私の年齢: 20
私の名前: Li Si 性別: 女性 私の年齢: 30
私の名前:王五 性別: 男性 私の年齢は40歳です

コンストラクターの継承の問題

まず簡単な例を見てみましょう:

<?php
class Fruit {
public function construct($name)
{
echo &#39;水果&#39;.$name.&#39;创建了&#39;;
}
}
 
class Apple extends Fruit {
public function construct($name)
{
parent::construct($name);
}
}
 
$apple = new Apple("苹果");
 
// 输出 水果苹果创建了
?>

コンストラクターの継承により、メソッドの宣言ではなく、コードの書き換えが節約されます。つまり、親クラスで宣言されたコンストラクターです。実際、これも子クラスで再度宣言する必要があります。

PHP のコンストラクターの継承は次の条件を満たす必要があります:

親クラスにコンストラクター宣言がある場合、サブクラスにも宣言がなければなりません。そうでない場合はエラーが発生します。
親クラスのコンストラクターを実行するときは、子クラスでparentキーワードを引用符で囲む必要があります。
親クラスにコンストラクターがあり、子クラスにコンストラクターがない場合、子クラスがインスタンス化されるときに親クラスのコンストラクターが実際に実行されます。たとえば、Employee クラスに次のコンストラクターがあるとします。

function  construct($name){
$this->setName($name);
}
然后实例化CEO类,获得其name成员:

$ceo= new CEO("Gonn");
echo $ceo->getName();
将得到如下结果:

My name is Gonn

ただし、サブクラスにもコンストラクターがある場合、サブクラスがインスタンス化されると、親クラスにコンストラクターがあるかどうかに関係なく、サブクラス独自のコンストラクターが実行されます。 。たとえば、上記のコンストラクターを含む Employee クラスに加えて、CEO クラスにも次のコンストラクターが含まれているとします。

function  construct(){
echo "CEO object created!";
}

CEO クラスを再度インスタンス化し、同じ方法で getName() を実行すると、今度は異なる出力が得られます。 :


CEO オブジェクトが作成されました!

私の名前は Gonn です
parent::construct() に遭遇すると、PHP は親クラスに沿って適切なコンストラクターを上向きに検索し始めます。 Executive では見つからなかったため、Employee クラスの検索を続け、ここで適切なコンストラクターを見つけました。 PHP は、Employee クラスでコンストラクターを見つけると、そのコンストラクターを実行します。 Employee コンストラクターと Executive コンストラクターの両方を実行する場合は、Executive コンストラクターでparent::construct() を呼び出す必要があります。

また、親クラスのコンストラクターを参照する別の方法を選択することもできます。たとえば、新しい CEO オブジェクトが作成されるときに、Employee コンストラクターと Executive コンストラクターの両方が実行されると仮定します。上で述べたように、これらのコンストラクターは、次のように CEO のコンストラクターで明示的に参照できます:

function construct($name){
Employee::constrcut($name);
Executive::construct();
echo "CEO object created!";
}

異なる PHP バージョンでのコンストラクターの継承

コンストラクター内の参照


PHP 4.x のコンストラクター名とクラス名は同じ。
サブクラスのコンストラクター名はサブクラス名と同じです(ナンセンス)。
親クラスのコンストラクターはサブクラスで自動的に実行されません。
サブクラスで親クラスのコンストラクターを実行するには、次のようなステートメントを実行する必要があります:
$this->[親クラスのコンストラクター名 ()]

例:

class base1
{
  function base1()
  {
echo &#39;this is base1 construct&#39;;
  }
}
class class1 extends base1
{
  function class1()
  {
$this->base1();
echo &#39;this is class1 construct&#39;;
  }
}
$c1 = new class1;

PHP5.xバージョン:

PHP5 バージョン.0 以降では、クラスの機能が大幅に拡張されました。クラスのコンストラクターには、一律にconstruct()という名前が付けられます。
サブクラスのコンストラクター名もconstruct()です(これもナンセンスです)。
親クラスのコンストラクターがサブクラスで実行されるかどうかには、次の 2 つの状況があります:
1. サブクラスがコンストラクターconstruct()を定義していない場合、親クラスのコンストラクターがデフォルトで継承され、実行されます。自動的に。 。
2. サブクラスがコンストラクターconstruct()を定義している場合、コンストラクターの名前もconstruct()であるため、サブクラスのコンストラクターは実際には親クラスのコンストラクターをオーバーライドします。このとき実行されるのはサブクラスのコンストラクタです。
この時点で、サブクラスで親クラスのコンストラクターを実行したい場合は、次のようなステートメントを実行する必要があります:

parent::construct();

例:

class base2
{
  function construct()
  {
echo &#39;this is base2 construct&#39;;
  }
  function destruct()
  {
  }
}
class class2 extends base2
{
  function construct()
  {
parent::construct();
echo &#39;this is class2 construct&#39;;
  }
}

注意 parent::construct(); 语句不一定必须放在子类的构造函数中。放在子类的构造函数中仅仅保证了其在子类被实例化时自动执行。

PHP4.0 和 5.0 类构造函数的兼容问题:

在 PHP5.0 以上版本里,还兼容了 4.0 版本的构造函数的定义规则。如果同时定义了4.0的构造函数和 construct()函数,则construct() 函数优先。
为了使类代码同时兼容 PHP4.0 和 5.0,可以采取以下的方式:

class class3
{
  function construct() //for PHP5.0
  {
echo &#39;this is class2 construct&#39;;
  }
  function class3() //for PHP4.0
  {
$this->construct();
  }
}
$c3 = new class3;

php构造函数中的引用的内容。

<?php
class Foo {
   function Foo($name) {
     
       global $globalref;
       $globalref[] = &$this;
  
       $this->setName($name);
      
       $this->echoName();
   }
   function echoName() {
       echo "<br />",$this->name;
   }
   function setName($name) {
       $this->name = $name;
   }
}
?>

下面来检查一下用拷贝运算符 = 创建的 $bar1 和用引用运算符 =& 创建的 $bar2 有没有区别...
copy to clipboard
显然没有区别,但实际上有一个非常重要的区别:$bar1 和 $globalref[0] 并没有被引用,它们不是同一个变量。这是因为“new”默认并不返回引用,而返回一个拷贝。

<?php
$bar1 = new Foo(&#39;set in constructor&#39;);
$bar1->echoName();
$globalref[0]->echoName();
/* &#36755;&#20986;&#65306;
set in constructor
set in constructor
set in constructor */
$bar2 =& new Foo(&#39;set in constructor&#39;);
$bar2->echoName();
$globalref[1]->echoName();
/* &#36755;&#20986;&#65306;
set in constructor
set in constructor
set in constructor */
?>

以上がPHPのコンストラクターの継承解析の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

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