Chức năng nạp chồng và ghi đè trong php là gì?


Câu trả lời:


192

Quá tải là xác định các hàm có chữ ký tương tự, nhưng có các tham số khác nhau. Ghi đè chỉ thích hợp với các lớp dẫn xuất, trong đó lớp cha đã định nghĩa một phương thức và lớp dẫn xuất muốn ghi đè phương thức đó.

Trong PHP, bạn chỉ có thể quá tải các phương thức bằng cách sử dụng phương thức ma thuật __call.

Một ví dụ về ghi đè :

<?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 không hỗ trợ quá tải, mặc dù.
Sasha Chedygov

18
Có nó, sử dụng __call.
Jacob Relkin

50
PHP thay thế quá tải thông qua các tham số tùy chọn.
b01

3
Cảm ơn ý tưởng về các tham số tùy chọn, Đó là một gợi ý thực sự hữu ích
Fabricio PH

2
__call () được kích hoạt khi các phương thức không thể truy cập được gọi trong bối cảnh đối tượng Phương thức megic __callStatic () được kích hoạt khi các phương thức không thể truy cập được gọi trong ngữ cảnh tĩnh. Thực hiện theo điều này để có được một ví dụ chi tiết và giải thích về Quá tải trong ngữ cảnh PHP
Code Buster

107

Quá tải chức năng xảy ra khi bạn xác định cùng một tên hàm hai lần (hoặc nhiều hơn) bằng cách sử dụng bộ tham số khác nhau. Ví dụ:

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

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

Trong ví dụ trên, hàm computebị quá tải với hai chữ ký tham số khác nhau. * Điều này chưa được hỗ trợ trong PHP. Một cách khác là sử dụng các đối số tùy chọn:

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

Ghi đè hàm xảy ra khi bạn mở rộng một lớp và viết lại một hàm tồn tại trong lớp cha:

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

Ví dụ, computeghi đè hành vi được nêu trong Addition.


9
Ngoại trừ chức năng nạp chồng không được hỗ trợ trong PHP, AFAIK. Ngoài ra, như một lưu ý phụ không liên quan, tôi không chắc tại sao bạn lại có một Subtractionlớp mở rộng Additionlớp. :)
Sasha Chedygov

6
@musicfreak: 12:40 AM giờ địa phương ... Không thể nghĩ ra một ví dụ nào tốt hơn.
Andrew Moore

5
Điều này chưa được hỗ trợ trong PHP và có lẽ sẽ không bao giờ, vì PHP là ngôn ngữ được gõ yếu và không có gì thay đổi trong trường hợp này.
Crozin

2
Quá tải không chỉ khi bạn xác định cùng một tên hàm hai lần (hoặc nhiều lần hơn) bằng cách sử dụng bộ tham số khác nhau. Nói chung, quá tải cũng là khi bạn xác định cùng một tên hàm hai lần (hoặc nhiều lần hơn) bằng cùng một số tham số nhưng thuộc các loại khác nhau. Vì trong PHP không có khai báo kiểu biến (như trong Java) nên việc khái quát hóa này không thành vấn đề. Tôi chỉ đề cập đến điều này vì mục đích chính xác là quá tải là gì.
sbrbot

2
@sbrbot: Đặt hàm ý cả số lượng và loại.
Andrew Moore

22

Nói đúng ra, không có gì khác biệt, vì bạn cũng không thể làm được :)

Chức năng ghi đè có thể đã được thực hiện với một phần mở rộng PHP như APD, nhưng nó không được dùng nữa và phiên bản cuối cùng không thể sử dụng được.

Quá tải chức năng trong PHP không thể được thực hiện do gõ động, tức là, trong PHP bạn không "định nghĩa" các biến là một loại cụ thể. Thí dụ:

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

Mỗi biến là một loại khác nhau, nhưng bạn có thể biết loại trước khi thực hiện (xem cái thứ 4). Để so sánh, các ngôn ngữ khác sử dụng:

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

Trong ví dụ cuối cùng, bạn phải đặt mạnh loại biến (ví dụ: tôi đã sử dụng loại dữ liệu "cái gì đó").


Một "vấn đề" khác tại sao không thể nạp chồng hàm trong PHP: PHP có một hàm gọi là func_get_args (), trả về một mảng các đối số hiện tại, bây giờ hãy xem xét đoạn mã sau:

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

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

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

Xem xét cả hai hàm chấp nhận bất kỳ số lượng đối số, trình biên dịch nên chọn cái nào?


Cuối cùng, tôi muốn chỉ ra lý do tại sao các câu trả lời trên là sai một phần; nạp chồng / ghi đè hàm KHÔNG bằng với nạp chồng / ghi đè phương thức .

Trong đó một phương thức giống như một hàm nhưng đặc trưng cho một lớp, trong trường hợp đó, PHP cho phép ghi đè trong các lớp, nhưng một lần nữa không bị quá tải, do ngữ nghĩa ngôn ngữ.

Để kết luận, các ngôn ngữ như Javascript cho phép ghi đè (nhưng một lần nữa, không quá tải), tuy nhiên, chúng cũng có thể cho thấy sự khác biệt giữa ghi đè chức năng người dùng và phương thức:

/// 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 không hỗ trợ quá tải, đây là lý do tại sao PHP không hoàn toàn OOP.
PHP Ferrari

30
Không phải là PHP không hỗ trợ quá tải, nó không có nghĩa. Vấn đề là do PHP sử dụng các loại động. Trên thực tế, Javascript cũng không hỗ trợ quá tải và nó vẫn là OOP. Fud "PHP không hoàn toàn OOP" chỉ tồn tại vì một số người đã quyết định sử dụng danh sách kiểm tra để đánh giá OOP hay không.
Christian

@ ringø Không, các hàm được đặt tên trong PHP là bất biến. Khi bạn tạo một hàm được đặt tên trong PHP, không có cách nào bạn có thể sửa đổi hành vi bên trong của nó (ghi đè). Trừ khi bạn có nghĩa là ghi đè phương thức, đó là một cái gì đó khác .. Có lẽ bạn nên đọc toàn bộ câu trả lời trước khi bình luận trên dòng đầu tiên. :)
Christian

@Christian Vâng, tất nhiên trong PHP (và nhiều ngôn ngữ khác) ghi đè xảy ra trong một lớp . Vì vậy, vâng, chúng ta đang nói về các phương thức - mặc dù mỗi phương thức đều có tiền tố với chức năng từ khóa . Nhưng thực sự tôi nên đọc toàn bộ câu trả lời trước ...
e2-e4

9

Ví dụ quá tải

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);

Thực hiện tùy chỉnh tốt đẹp, nhưng nó nên được đưa ra bởi ngôn ngữ.
4EACH

Đây không phải là phương thức, chức năng quá tải, trong khi bạn đang sử dụng tên phương thức khác nhau cho mỗi học sinh
TomSawyer

5

Mặc dù mô hình quá tải không được PHP hỗ trợ đầy đủ, nhưng hiệu ứng tương tự (hoặc rất giống nhau) có thể đạt được với (các) tham số mặc định (như ai đó đã đề cập trước đó).

Nếu bạn xác định chức năng của mình như thế này:

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

Khi bạn gọi chức năng này như:

f();

bạn sẽ nhận được một chức năng (# 1), nhưng nếu bạn gọi nó với tham số như:

f(1);

bạn sẽ nhận được một chức năng khác (# 2). Đó là hiệu ứng của quá tải - chức năng khác nhau tùy thuộc vào (các) tham số đầu vào của chức năng.

Tôi biết, bây giờ sẽ có người hỏi chức năng nào người ta sẽ nhận được nếu anh ta / cô ta gọi chức năng này là f (0).


1

Tôi muốn chỉ ra ở đây rằng Quá tải trong PHP có một ý nghĩa hoàn toàn khác so với các ngôn ngữ lập trình khác. Rất nhiều người đã nói rằng quá tải không được hỗ trợ trong PHP và theo định nghĩa thông thường về quá tải, vâng, chức năng đó không có sẵn rõ ràng.

Tuy nhiên, định nghĩa chính xác về quá tải trong PHP là hoàn toàn khác nhau.

Trong quá tải PHP đề cập đến việc tạo động các thuộc tính và phương thức bằng các phương thức ma thuật như __set () và __get (). Các phương thức nạp chồng này được gọi khi tương tác với các phương thức hoặc thuộc tính không thể truy cập hoặc không được khai báo.

Đây là một liên kết từ hướng dẫn sử dụng PHP: http://www.php.net/manual/en/lingu.oop5.overloading.php


1

Quá tải phương thức xảy ra khi hai hoặc nhiều phương thức có cùng tên phương thức nhưng số lượng tham số khác nhau trong một lớp. PHP không hỗ trợ quá tải phương thức. Ghi đè phương thức có nghĩa là hai phương thức có cùng tên phương thức và cùng số lượng tham số trong hai lớp khác nhau có nghĩa là lớp cha và lớp con.


0

Có một số khác biệt giữa nạp chồng & ghi đè chức năng mặc dù cả hai đều chứa cùng một tên hàm. Trong quá tải, giữa các hàm cùng tên chứa loại đối số hoặc kiểu trả về khác nhau, chẳng hạn như: "function add (int a, int b)" & " Hàm add (float a, float b); Ở đây hàm add () bị quá tải. Trong trường hợp ghi đè cả đối số và tên hàm là như nhau. Nó thường được tìm thấy trong thừa kế hoặc trong các đặc điểm. Chúng tôi phải tuân theo một số chiến thuật để giới thiệu , chức năng nào sẽ thực thi ngay bây giờ.


0

Quá tải: Trong thế giới thực, quá tải có nghĩa là gán thêm một số thứ cho ai đó. Như trong thế giới thực Quá tải trong PHP có nghĩa là gọi các hàm bổ sung. Nói cách khác, bạn có thể nói nó có chức năng mỏng hơn với tham số khác nhau. Trong PHP bạn có thể sử dụng quá tải với các hàm ma thuật, ví dụ: __get, __set, __call, v.v.

Ví dụ về quá tải:

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

Ghi đè: Trong lập trình hướng đối tượng, ghi đè là thay thế phương thức cha trong lớp con. Trong phần ghi đè, bạn có thể khai báo lại phương thức lớp cha trong lớp con. Vì vậy, về cơ bản, mục đích của ghi đè là thay đổi hành vi của phương thức lớp cha của bạn.

Ví dụ về ghi đè:

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 không hỗ trợ quá tải, đây là lý do tại sao PHP không hoàn toàn OOP.


18
Tôi không biết bạn đã có ý tưởng về việc làm quá tải một yêu cầu cho Lập trình hướng đối tượng.
thu hút

6
@drewish vì đa hình tham số là một trong những tính năng quan trọng nhất của OOP?
Thưởng thức

1
@drewish nếu bạn tính đa hình là một trong những sự đình trệ chính của OOP. Sau đó, quá tải bề ngoài là ra cho việc biên dịch. Tuy nhiên, quá tải phương thức là đa hình thời gian biên dịch và còn được gọi là đa hình tĩnh.
Yasir Arefin
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.