ฟังก์ชันโอเวอร์โหลดและการแทนที่ใน php คืออะไร?


130

ใน PHP คุณหมายถึงอะไรเมื่อฟังก์ชันโอเวอร์โหลดและการลบล้างฟังก์ชัน และทั้งคู่ต่างกันอย่างไร? คิดไม่ออกว่าอะไรคือความแตกต่างระหว่างพวกเขา


คุณสามารถใช้คลาสโอเวอร์โหลดได้ในลิงค์นี้: stackoverflow.com/questions/4697705/php-function-overloading/…
Hisham 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 ไม่รองรับการโอเวอร์โหลด
Sasha Chedygov

18
ใช่มันใช้__call.
Jacob Relkin

50
PHP ทดแทนการโอเวอร์โหลดผ่านพารามิเตอร์เสริม
b01

3
ขอบคุณสำหรับแนวคิดเกี่ยวกับพารามิเตอร์ที่เป็นทางเลือกซึ่งเป็นคำแนะนำที่มีประโยชน์มาก
Fabricio PH

2
__call () ถูกทริกเกอร์เมื่อเมธอดที่ไม่สามารถเข้าถึงได้ถูกเรียกในอ็อบเจ็กต์บริบท __callStatic () เมธอด megic ถูกทริกเกอร์เมื่อเมธอดที่ไม่สามารถเข้าถึงได้ถูกเรียกในบริบทคงที่ ทำตามสิ่งนี้เพื่อดูตัวอย่างรายละเอียดเพิ่มเติมและคำอธิบายเกี่ยวกับ Overloading ในบริบทPHP
Code Buster

107

การโอเวอร์โหลดฟังก์ชันเกิดขึ้นเมื่อคุณกำหนดชื่อฟังก์ชันเดียวกันสองครั้ง (หรือมากกว่า) โดยใช้ชุดพารามิเตอร์ที่ต่างกัน ตัวอย่างเช่น:

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

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

ในตัวอย่างข้างต้นฟังก์ชันcomputeนี้มีลายเซ็นพารามิเตอร์สองตัวที่แตกต่างกันมากเกินไป * สิ่งนี้ยังไม่รองรับใน 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;
  }
}

ยกตัวอย่างเช่นแทนที่ชุดพฤติกรรมไว้ในcomputeAddition


9
PHP, AFAIK ไม่รองรับการโอเวอร์โหลดยกเว้นฟังก์ชัน นอกจากนี้เนื่องจากเป็นบันทึกด้านข้างที่ไม่เกี่ยวข้องฉันไม่แน่ใจว่าทำไมคุณถึงให้Subtractionชั้นเรียนขยายAdditionชั้นเรียน :)
Sasha Chedygov

6
@musicfreak: 00:40 น. ตามเวลาท้องถิ่น ... ไม่สามารถนึกถึงตัวอย่างที่ดีกว่านี้ได้
Andrew Moore

5
สิ่งนี้ยังไม่รองรับใน PHPและอาจจะไม่เป็นเช่นนั้นเนื่องจาก PHP เป็นภาษาที่พิมพ์ไม่ชัดเจนและไม่มีอะไรเปลี่ยนแปลงในกรณีนี้
Crozin

2
การโอเวอร์โหลดไม่เพียง แต่เมื่อคุณกำหนดชื่อฟังก์ชันเดียวกันสองครั้ง (หรือมากกว่าครั้ง) โดยใช้ชุดพารามิเตอร์ที่แตกต่างกัน โดยทั่วไปการโอเวอร์โหลดจะเกิดขึ้นเมื่อคุณกำหนดชื่อฟังก์ชันเดียวกันสองครั้ง (หรือมากกว่านั้น) โดยใช้พารามิเตอร์จำนวนเท่ากัน แต่เป็นประเภทที่แตกต่างกัน เนื่องจากใน PHP ไม่มีการประกาศประเภทตัวแปร (เช่นใน Java) ลักษณะทั่วไปนี้จึงไม่สำคัญ ฉันแค่พูดถึงเรื่องนี้เพื่อความแม่นยำว่าการบรรทุกเกินพิกัดคืออะไร
sbrbot

2
@sbrbot: Set หมายถึงทั้งจำนวนและประเภท
Andrew Moore

22

พูดอย่างเคร่งครัดไม่มีความแตกต่างเนื่องจากคุณทำไม่ได้ :)

การลบล้างฟังก์ชั่นสามารถทำได้ด้วยส่วนขยาย PHP เช่น APD แต่เลิกใช้งานแล้วและเวอร์ชันล่าสุดของ 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 ไม่ได้: 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');

การพิจารณาว่าฟังก์ชันทั้งสองยอมรับอาร์กิวเมนต์จำนวนเท่าใดคอมไพเลอร์ควรเลือกตัวใด


สุดท้ายนี้ฉันอยากจะชี้ให้เห็นว่าเหตุใดการตอบกลับข้างต้นจึงผิดบางส่วน ฟังก์ชั่น overloading / overriding ไม่เท่ากับmethod overloading / overriding

ในกรณีที่เมธอดเป็นเหมือนฟังก์ชัน แต่เฉพาะสำหรับคลาสซึ่งในกรณีนี้ 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 Ferrari

30
ไม่ใช่ว่า PHP ไม่รองรับการโอเวอร์โหลด แต่มันไม่สมเหตุสมผล ปัญหาเกิดจาก PHP ที่ใช้ประเภทไดนามิก อันที่จริง Javascript ไม่รองรับการโอเวอร์โหลดเช่นกันและยังคงเป็น OOP ฟัด "PHP ไม่ใช่ OOP ทั้งหมด" มีอยู่เพียงเพราะบางคนตัดสินใจใช้รายการตรวจสอบเพื่อตัดสินว่า OOP คืออะไรหรือไม่
คริสเตียน

@ ringø Nope ฟังก์ชันที่มีชื่อใน PHP นั้นไม่เปลี่ยนรูป เมื่อคุณสร้างฟังก์ชันที่ตั้งชื่อใน PHP แล้วคุณจะไม่สามารถปรับเปลี่ยนพฤติกรรมภายในได้ (ลบล้าง) เว้นแต่คุณจะหมายถึงวิธีการแทนที่ซึ่งเป็นอย่างอื่น .. คุณควรอ่านคำตอบทั้งหมดก่อนแสดงความคิดเห็นในบรรทัดแรก :)
คริสเตียน

@Christian ดีแน่นอนใน PHP (และภาษาอื่น ๆ อีกมากมาย) เอาชนะเกิดขึ้นในชั้นเรียน ใช่เรากำลังพูดถึงวิธีการ - แม้ว่าแต่ละวิธีจะมีคำนำหน้าด้วยฟังก์ชันคำหลักก็ตาม แต่ฉันควรอ่านคำตอบทั้งหมดก่อน ...
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);

การใช้งานที่กำหนดเองได้ดี แต่ควรกำหนดตามภาษา
4EACH

นี่ไม่ใช่วิธีการทำงานมากเกินไปในขณะที่คุณใช้ชื่อวิธีการที่แตกต่างกันสำหรับแต่ละดักแด้
TomSawyer

5

แม้ว่า PHP จะไม่รองรับกระบวนทัศน์การโอเวอร์โหลดอย่างเต็มที่ แต่เอฟเฟกต์เดียวกัน (หรือคล้ายกันมาก) ก็สามารถทำได้ด้วยพารามิเตอร์เริ่มต้น (ตามที่ใครบางคนกล่าวไว้ก่อนหน้านี้)

หากคุณกำหนดฟังก์ชันของคุณดังนี้:

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

เมื่อคุณเรียกใช้ฟังก์ชันนี้เช่น:

f();

คุณจะได้รับฟังก์ชั่นเดียว (# 1) แต่ถ้าคุณเรียกมันด้วยพารามิเตอร์เช่น:

f(1);

คุณจะได้รับฟังก์ชันอื่น (# 2) นั่นคือผลของการโอเวอร์โหลด - ฟังก์ชันการทำงานที่แตกต่างกันขึ้นอยู่กับพารามิเตอร์อินพุตของฟังก์ชัน

ฉันรู้ว่าใครบางคนจะถามว่าฟังก์ชันใดที่จะได้รับถ้าเขา / เธอเรียกฟังก์ชันนี้ว่า f (0)


1

ฉันอยากจะชี้ให้เห็นตรงนี้ว่า Overloading ใน PHP มีความหมายที่แตกต่างอย่างสิ้นเชิงเมื่อเทียบกับภาษาโปรแกรมอื่น ๆ หลายคนบอกว่าการโอเวอร์โหลดไม่ได้รับการสนับสนุนใน PHP และตามคำจำกัดความทั่วไปของการโอเวอร์โหลดใช่ว่าฟังก์ชันการทำงานจะไม่สามารถใช้งานได้อย่างชัดเจน

อย่างไรก็ตามคำจำกัดความที่ถูกต้องของการโอเวอร์โหลดใน PHP นั้นแตกต่างกันอย่างสิ้นเชิง

ใน PHP overloading หมายถึงการสร้างคุณสมบัติและวิธีการแบบไดนามิกโดยใช้เมธอดมายากลเช่น __set () และ __get () วิธีการโอเวอร์โหลดเหล่านี้ถูกเรียกใช้เมื่อโต้ตอบกับเมธอดหรือคุณสมบัติที่ไม่สามารถเข้าถึงได้หรือไม่ได้ประกาศ

นี่คือลิงค์จากคู่มือ PHP: http://www.php.net/manual/en/language.oop5.overloading.php


1

การโอเวอร์โหลดเมธอดเกิดขึ้นเมื่อสองเมธอดหรือมากกว่าที่มีชื่อเมธอดเดียวกัน แต่มีจำนวนพารามิเตอร์ต่างกันในคลาสเดียว PHP ไม่สนับสนุนวิธีการโอเวอร์โหลด การแทนที่เมธอดหมายถึงสองวิธีที่มีชื่อเมธอดเดียวกันและจำนวนพารามิเตอร์เท่ากันในสองคลาสที่แตกต่างกันหมายถึงคลาสพาเรนต์และคลาสลูก


0

มีความแตกต่างบางประการระหว่าง Function overloading & overriding แม้ว่าทั้งสองจะมีชื่อฟังก์ชันเหมือนกันในการโอเวอร์โหลดระหว่างฟังก์ชันชื่อเดียวกันจะมีอาร์กิวเมนต์หรือประเภทการส่งคืนที่แตกต่างกันเช่น: "function add (int a, int b)" & " function add (float a, float b); ที่นี่ฟังก์ชัน add () มีมากเกินไปในกรณีของการแทนที่ทั้งอาร์กิวเมนต์และชื่อฟังก์ชันจะเหมือนกันโดยทั่วไปจะพบในการสืบทอดหรือในลักษณะเราต้องปฏิบัติตามกลยุทธ์บางอย่างเพื่อแนะนำ ฟังก์ชันอะไรจะดำเนินการตอนนี้ดังนั้นในการลบล้างโปรแกรมเมอร์ให้ทำตามกลวิธีบางอย่างเพื่อเรียกใช้ฟังก์ชันที่ต้องการซึ่งในการทำงานมากเกินไปโปรแกรมจะสามารถระบุฟังก์ชันที่ต้องการได้โดยอัตโนมัติ ... ขอบคุณ!


0

การโอเวอร์โหลด:ในโลกแห่งความเป็นจริงการโอเวอร์โหลดหมายถึงการมอบหมายสิ่งของพิเศษบางอย่างให้กับใครบางคน เช่นเดียวกับในโลกแห่งความเป็นจริง Overloading ใน 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
ฉันไม่รู้ว่าคุณมีความคิดที่ว่าการใช้งาน Object Oriented Programming มากเกินไป
วาด

6
@drewish เพราะพหุนามพาราเมตริกเป็นหนึ่งในคุณสมบัติที่สำคัญที่สุดของ OOP?
Davor

1
@drewish ถ้าคุณนับความหลากหลายเป็นหนึ่งในความเมื่อยล้าหลักของ OOP จากนั้นการโอเวอร์โหลดอย่างเห็นได้ชัดจะอยู่ที่นั่นสำหรับการรวบรวม อย่างไรก็ตามวิธีการโอเวอร์โหลดคือความหลากหลายของเวลาคอมไพล์และเรียกอีกอย่างว่าความหลากหลายแบบคงที่
Yasir Arefin
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.