PHPでの関数のオーバーロードとオーバーライドとは何ですか?


130

PHPでは、関数のオーバーロードと関数のオーバーライドとはどういう意味ですか。そして、両者の違いは何ですか?それらの違いは何であるか理解できませんでした。


:あなたは、このリンクにオーバーロードクラスを使用することができます stackoverflow.com/questions/4697705/php-function-overloading/...
ヒシャムDalal

回答:


192

オーバーロードとは、似たようなシグネチャを持つが、異なるパラメーターを持つ関数を定義することです。オーバーライドは、親クラスがメソッドを定義し、派生クラスそのメソッドをオーバーライドすることを望む派生クラスにのみ関係します

PHPでは、マジックメソッドを使用してのみメソッドをオーバーロードできます__call

オーバーライドの例:

<?php

class Foo {
   function myFoo() {
      return "Foo";
   }
}

class Bar extends Foo {
   function myFoo() {
      return "Bar";
   }
}

$foo = new Foo;
$bar = new Bar;
echo($foo->myFoo()); //"Foo"
echo($bar->myFoo()); //"Bar"
?>

31
ただし、PHPはオーバーロードをサポートしていません。
サーシャチェディゴフ2010年

18
はい、使用し__callます。
Jacob Relkin

50
PHPは、オプションのパラメーターによるオーバーロードを置き換えます。
b01

3
オプションのパラメーターのアイデアをありがとう、それは本当に役立つヒントです
ファブリシオPH

2
__call()は、アクセスできないメソッドがオブジェクトコンテキストで呼び出されたときにトリガーされます__callStatic()megicメソッドは、アクセスできないメソッドが静的コンテキストで呼び出されたときにトリガーされます。これに従って、PHPコンテキストでのオーバーロードの詳細な例と説明を取得してください
コードバスター

107

異なるパラメーターセットを使用して同じ関数名を2回(またはそれ以上)定義すると、関数のオーバーロードが発生します。例えば:

class Addition {
  function compute($first, $second) {
    return $first+$second;
  }

  function compute($first, $second, $third) {
    return $first+$second+$third;
  }
}

上記の例では、関数computeは2つの異なるパラメーターシグネチャでオーバーロードされています。*これはPHPではまだサポートされていません。別の方法として、オプションの引数を使用することができます。

class Addition {
  function compute($first, $second, $third = 0) {
    return $first+$second+$third;
  }
}

関数のオーバーライドは、クラスを拡張して親クラスに存在していた関数を書き換えると発生します。

class Substraction extends Addition {
  function compute($first, $second, $third = 0) {
    return $first-$second-$third;
  }
}

たとえば、でcompute説明されている動作をオーバーライドしますAddition


9
関数のオーバーロードを除いて、PHP、AFAIKではサポートされていません。また、無関係の副次的注意として、Subtractionクラスでクラスを拡張する理由がわかりませんAddition。:)
サーシャチェディゴフ2010年

6
@musicfreak:現地時間の午前12時40分...良い例は考えられませんでした。
Andrew Moore

5
PHPは弱く型付けされた言語であり、この場合何も変更されないため、これはPHPではまだサポートされておらず、おそらくサポートされないでしょう。
Crozin 2010

2
オーバーロードは、異なるパラメーターセットを使用して同じ関数名を2回(またはそれ以上)定義する場合だけではありません。一般に、オーバーロードは、同じ数のパラメーターを使用して、タイプが異なる同じ関数名を2回(またはそれ以上)定義する場合にも当てはまります。PHPでは(Javaのように)変数型宣言がないため、この一般化は問題になりません。オーバーロードとは何かを正確に説明するために、これについて触れています。
sbrbot 2013年

2
@sbrbot:セットは数とタイプの両方を意味します。
Andrew Moore、

22

厳密には、どちらも実行できないため、違いはありません。

関数のオーバーライドは、APDのようなPHP拡張機能を使用して行うことができますが、非推奨であり、以前のバージョンのafaikは使用できませんでした。

PHPでの関数のオーバーロードは動的型付けが原因で実行できません。つまり、PHPでは変数を特定の型に「定義」しません。例:

$a=1;
$a='1';
$a=true;
$a=doSomething();

各変数は異なる型ですが、実行前に型を知ることができます(4番目を参照)。比較として、他の言語は以下を使用します:

int a=1;
String s="1";
bool a=true;
something a=doSomething();

最後の例では、変数の型を強制的に設定する必要があります(例として、データ型「something」を使用しました)。


PHPで関数のオーバーロードができないもう1つの「問題」:PHPには、現在の引数の配列を返すfunc_get_args()という関数があります。次のコードを検討してください。

function hello($a){
  print_r(func_get_args());
}

function hello($a,$a){
  print_r(func_get_args());
}

hello('a');
hello('a','b');

両方の関数が任意の量の引数を受け入れることを考えると、コンパイラはどちらを選択する必要がありますか?


最後に、上記の返信が部分的に間違っている理由を指摘したいと思います。 関数のオーバーロード/オーバーライドは、メソッドのオーバーロード/オーバーライドと同じではありません。

メソッドが関数のようでクラスに固有である場合、その場合、PHPはクラスでのオーバーライドを許可しますが、言語のセマンティクスにより、オーバーロードは許可しません。

結論として、JavaScriptなどの言語はオーバーライドを許可します(ただし、オーバーロードは許可されません)。ただし、ユーザー関数とメソッドのオーバーライドの違いを示す場合もあります。

/// Function Overriding ///

function a(){
   alert('a');
}
a=function(){
   alert('b');
}

a(); // shows popup with 'b'


/// Method Overriding ///

var a={
  "a":function(){
    alert('a');
  }
}
a.a=function(){
   alert('b');
}

a.a(); // shows popup with 'b'

2
PHP 5.xxはオーバーロードをサポートしていないため、PHPは完全にOOPではありません。
PHPフェラーリ

30
PHPがオーバーロードをサポートしていないということではなく、意味がありません。この問題は、動的型を使用するPHPが原因です。実際、JavaScriptもオーバーロードをサポートしておらず、まだOOPです。「PHPは完全にOOPではない」という疑問は、チェックリストを使用してOOPかどうかを判断することに決めた人がいるためにのみ存在します。
クリスチャン

@ringøいいえ、PHPの名前付き関数は不変です。PHPで名前付き関数を作成すると、その内部動作を変更(オーバーライド)する方法はありません。メソッドのオーバーライドを意味する場合を除き、これは何か別のことです。最初の行にコメントする前に、回答全体を読む必要があります。:)
クリスチャン

@Christian Well、もちろんPHP(および他の多くの言語)では、オーバーライドがクラスで発生します。つまり、メソッドについて話しているのですが、それぞれの前にキーワードfunctionが付いています。しかし、確かに私は最初にすべての答えを最初に読んでいるべきだった...
e2-e4

9

オーバーロードの例

class overload {
    public $name;
    public function __construct($agr) {
        $this->name = $agr;
    }
    public function __call($methodname, $agrument) {
         if($methodname == 'sum2') {

          if(count($agrument) == 2) {
              $this->sum($agrument[0], $agrument[1]);
          }
          if(count($agrument) == 3) {

              echo $this->sum1($agrument[0], $agrument[1], $agrument[2]);
          }
        }
    }
    public function sum($a, $b) {
        return $a + $b;
    }
    public function sum1($a,$b,$c) {

        return $a + $b + $c;
    }
}
$object = new overload('Sum');
echo $object->sum2(1,2,3);

素晴らしいカスタム実装ですが、言語で指定する必要があります。
2017年

これはメソッドではなく、関数のオーバーロードですが、puporseごとに異なるメソッド名を使用しています
TomSawyer

5

オーバーロードのパラダイムはPHPで完全にはサポートされていませんが、同じ(または非常に類似した)効果がデフォルトのパラメーターで実現できます(前述のとおり)。

次のように関数を定義すると、

function f($p=0)
{
  if($p)
  {
    //implement functionality #1 here
  }
  else
  {
    //implement functionality #2 here
  }
}

この関数を次のように呼び出すと:

f();

1つの機能(#1)が得られますが、次のようなパラメーターを指定して呼び出すと、

f(1);

別の機能を利用できます(#2)。これがオーバーロードの影響です。関数の入力パラメーターに応じて機能が異なります。

私が知っている、誰かがこの関数をf(0)として呼び出すと、どのような機能が得られるかを尋ねるでしょう。


1

ここで指摘しておきたいのは、PHPでのオーバーロードは他のプログラミング言語と比べてまったく異なる意味を持つということです。多くの人々は、PHPではオーバーロードはサポートされていないと述べ、オーバーロードの従来の定義では、機能が明示的に利用可能ではないと述べています。

ただし、PHPでのオーバーロードの正しい定義は完全に異なります。

PHPでは、オーバーロードとは、__ set()や__get()などの魔法のメソッドを使用してプロパティとメソッドを動的に作成することを指します。これらのオーバーロードメソッドは、アクセスできない、または宣言されていないメソッドまたはプロパティと対話するときに呼び出されます。

PHPマニュアルからのリンクは次のとおりです。http//www.php.net/manual/en/language.oop5.overloading.php


1

メソッドのオーバーロードは、1つのクラス内のメソッド名は同じであるがパラメーターの数が異なる2つ以上のメソッドで発生します。PHPはメソッドのオーバーロードをサポートしていません。メソッドのオーバーライドとは、2つの異なるクラスで同じメソッド名と同じ数のパラメーターを持つ2つのメソッドが、親クラスと子クラスを意味することを意味します。


0

関数のオーバーロードとオーバーライドには、同じ関数名が含まれていますが、いくつかの違いがあります。オーバーロードでは、同じ名前の関数には、異なるタイプの引数または戻り値のタイプが含まれます。例: "function add(int a、int b)"& " function add(float a、float b);ここではadd()関数がオーバーロードされています。オーバーライドすると、引数と関数名の両方が同じになります。これは通常、継承またはトレイトにあります。導入するためのいくつかの戦略に従う必要があります、どの関数が今すぐ実行されるかを指定します。そのため、プログラマーをオーバーライドする場合は、いくつかの戦術に従って、目的の関数を実行します。


0

オーバーロード:現実の世界では、オーバーロードとは、誰かに余分なものを割り当てることを意味します。現実世界と同様に、PHPのオーバーロードとは、追加の関数を呼び出すことを意味します。別の方法では、異なるパラメーターを持つよりスリムな関数を持っていると言えます。PHPでは、__ get、__ set、__ callなどのマジック関数でオーバーロードを使用できます。

オーバーロードの例:

class Shape {
   const Pi = 3.142 ;  // constant value
  function __call($functionname, $argument){
    if($functionname == 'area')
    switch(count($argument)){
        case 0 : return 0 ;
        case 1 : return self::Pi * $argument[0] ; // 3.14 * 5
        case 2 : return $argument[0] * $argument[1];  // 5 * 10
    }

  }

 }
 $circle = new Shape();`enter code here`
 echo "Area of circle:".$circle->area()."</br>"; // display the area of circle Output 0
 echo "Area of circle:".$circle->area(5)."</br>"; // display the area of circle
 $rect = new Shape();
 echo "Area of rectangle:".$rect->area(5,10); // display area of rectangle

オーバーライド:オブジェクト指向プログラミングでは、オーバーライドは子クラスの親メソッドを置き換えることです。オーバーライドでは、子クラスで親クラスメソッドを再宣言できます。したがって、基本的にオーバーライドの目的は、親クラスのメソッドの動作を変更することです。

オーバーライドの例:

class parent_class
{

  public function text()    //text() is a parent class method
  {
    echo "Hello!! everyone I am parent class text method"."</br>";
  }
  public function test()   
  {
    echo "Hello!! I am second method of parent class"."</br>";
  }

}

class child extends parent_class
{
  public function text()     // Text() parent class method which is override by child 
  class
  {
    echo "Hello!! Everyone i am child class";
  }

 }

 $obj= new parent_class();
 $obj->text();            // display the parent class method echo
 $obj= new parent_class();
 $obj->test();
 $obj= new child();
 $obj->text(); // display the child class method echo

-14

PHP 5.xxはオーバーロードをサポートしていないため、PHPは完全にOOPではありません。


18
オブジェクト指向プログラミングの要件をオーバーロードするという考えがどこで得られたのかわかりません。
2011

6
@drewishパラメトリックポリモーフィズムはOOPの最も重要な機能の1つなので、
Davor、

1
多態性をOOPの主な停滞の1つとして数える場合は@drewish。次に、コンパイルのために表面的にオーバーロードがあります。ただし、メソッドのオーバーロードはコンパイル時のポリモーフィズムであり、静的ポリモーフィズムとも呼ばれます。
Yasir Arefin 2014年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.