PHP ghi đè chức năng hiện có

Các đặc điểm PHP cung cấp một phương tiện thuận tiện để chia sẻ các phương thức giữa các lớp. Tuy nhiên, đôi khi chúng ta có thể cần ghi đè hoặc mở rộng một phương thức được xác định trong một đặc điểm gắn liền với một lớp. Hãy xem làm thế nào chúng ta có thể đạt được điều này

Hãy bắt đầu bằng cách xác định một đặc điểm rất đơn giản như một ví dụ có tên là FooTrait chứa định nghĩa cho một phương thức công khai có tên là bar(). -

trait FooTrait
{
	public function bar()
	{
		return 'A';
	}
}

Sau đó chúng ta có thể gán đặc điểm đó cho một lớp và gọi bar() như một phương thức của lớp. -

class Example
{
	use FooTrait;
}

echo (new Example())->bar(); // Outputs 'A'

Các phương thức của đặc điểm được đính kèm về cơ bản hoạt động như thể chúng đã được sao chép và dán vào lớp

class Example
{
	use FooTrait;
}

echo (new Example())->bar(); // Outputs 'A'
0 của chúng tôi

Nếu sau đó chúng ta định nghĩa một phương thức bar() mới trong lớp

class Example
{
	use FooTrait;
}

echo (new Example())->bar(); // Outputs 'A'
0 của chúng ta sẽ ghi đè lên phương thức bar() của đặc điểm thì phương thức mới này sẽ được chạy thay thế. -

class Example
{
	use FooTrait;

	public function bar()
	{
		return 'B';
	}
}

echo (new Example())->bar(); // Outputs 'B'

Điều này bao hàm việc ghi đè phương thức của một đặc điểm, nhưng nếu chúng ta muốn mở rộng phương thức đó thay vì thay thế nó thì sao? . Bằng cách định nghĩa bar() trong lớp của chúng ta, nó đã thay thế phương thức bar() được định nghĩa trong FooTrait đính kèm. Do đó, nếu chúng ta muốn mở rộng phương thức được xác định trong trait của chúng ta từ lớp của chúng ta, chúng ta cần đổi tên phương thức bar() của trait thành một cái gì đó giống như

class Example
{
	use FooTrait;
}

echo (new Example())->bar(); // Outputs 'A'
7 trong lớp của chúng ta và sau đó gọi trực tiếp
class Example
{
	use FooTrait;
}

echo (new Example())->bar(); // Outputs 'A'
8 bên trong phương thức bar() của lớp chúng ta như thế này. -

class Example
{
	use FooTrait {
		bar as traitBar;
	}

	public function bar()
	{
		return $this->traitBar() . 'B';
	}
}

echo (new Example())->bar(); // Outputs 'AB'

Bằng cách này, chúng ta có thể mở rộng phương thức theo cách tương tự để mở rộng phương thức lớp kế thừa. Đổi tên một phương thức đặc điểm như thế này cũng có thể hữu ích khi gắn nhiều đặc điểm vào một lớp có thể có xung đột về tên phương thức

Vậy là bạn đã hiểu, chúng ta đã thấy cách chúng ta có thể ghi đè và mở rộng một phương thức đặc điểm. Các đặc điểm là một cách hữu ích để giữ cho mã của chúng ta KHÔ (i. e. không lặp lại) và chia sẻ phương thức giữa các lớp. Việc chúng ta có thể ghi đè và mở rộng các phương thức từ một đặc điểm khiến chúng trở nên cực kỳ hữu ích

Kế thừa là một nguyên tắc lập trình được thiết lập tốt và PHP sử dụng nguyên tắc này trong mô hình đối tượng của nó. Nguyên tắc này sẽ ảnh hưởng đến cách nhiều lớp và đối tượng liên quan với nhau

Ví dụ: khi mở rộng một lớp, lớp con sẽ kế thừa tất cả các phương thức, thuộc tính và hằng số công khai và được bảo vệ từ lớp cha. Trừ khi một lớp ghi đè các phương thức đó, chúng sẽ giữ nguyên chức năng ban đầu của chúng

Điều này hữu ích cho việc xác định và trừu tượng hóa chức năng, đồng thời cho phép triển khai chức năng bổ sung trong các đối tượng tương tự mà không cần phải triển khai lại tất cả các chức năng được chia sẻ

Các phương thức riêng của lớp cha không thể truy cập được đối với lớp con. Kết quả là, các lớp con có thể tự hiện thực lại một phương thức riêng tư mà không cần quan tâm đến các quy tắc kế thừa thông thường. Trước PHP 8. 0. 0, tuy nhiên, các hạn chế của

class Example
{
	use FooTrait;

	public function bar()
	{
		return 'B';
	}
}

echo (new Example())->bar(); // Outputs 'B'
0 và
class Example
{
	use FooTrait;

	public function bar()
	{
		return 'B';
	}
}

echo (new Example())->bar(); // Outputs 'B'
1 đã được áp dụng cho các phương thức riêng tư. Kể từ PHP 8. 0. 0, hạn chế phương thức riêng tư duy nhất được thực thi là hàm tạo
class Example
{
	use FooTrait;

	public function bar()
	{
		return 'B';
	}
}

echo (new Example())->bar(); // Outputs 'B'
2, vì đó là cách phổ biến để "vô hiệu hóa" hàm tạo khi sử dụng các phương thức gốc tĩnh thay thế

Khả năng hiển thị của các phương thức, thuộc tính và hằng số có thể được nới lỏng, e. g. một phương pháp

class Example
{
	use FooTrait;

	public function bar()
	{
		return 'B';
	}
}

echo (new Example())->bar(); // Outputs 'B'
3 có thể được đánh dấu là
class Example
{
	use FooTrait;

	public function bar()
	{
		return 'B';
	}
}

echo (new Example())->bar(); // Outputs 'B'
4, nhưng chúng không thể bị hạn chế, e. g. đánh dấu thuộc tính
class Example
{
	use FooTrait;

	public function bar()
	{
		return 'B';
	}
}

echo (new Example())->bar(); // Outputs 'B'
4 là
class Example
{
	use FooTrait;

	public function bar()
	{
		return 'B';
	}
}

echo (new Example())->bar(); // Outputs 'B'
6

Ghi chú

Trừ khi autoloading được sử dụng, các lớp phải được xác định trước khi chúng được sử dụng. Nếu một lớp mở rộng một lớp khác, thì lớp cha phải được khai báo trước cấu trúc lớp con. Quy tắc này áp dụng cho các lớp kế thừa các lớp và giao diện khác

Ghi chú

Không được phép ghi đè thuộc tính đọc ghi bằng a hoặc ngược lại

class Example
{
	use FooTrait;

	public function bar()
	{
		return 'B';
	}
}

echo (new Example())->bar(); // Outputs 'B'
7

Ví dụ #1 Ví dụ về kế thừa

class Example
{
	use FooTrait;

	public function bar()
	{
		return 'B';
	}
}

echo (new Example())->bar(); // Outputs 'B'
8

class Example
{
	use FooTrait;

	public function bar()
	{
		return 'B';
	}
}

echo (new Example())->bar(); // Outputs 'B'
9

class Example
{
	use FooTrait;

	public function bar()
	{
		return 'B';
	}
}

echo (new Example())->bar(); // Outputs 'B'
10

class Example
{
	use FooTrait;

	public function bar()
	{
		return 'B';
	}
}

echo (new Example())->bar(); // Outputs 'B'
11

class Example
{
	use FooTrait;

	public function bar()
	{
		return 'B';
	}
}

echo (new Example())->bar(); // Outputs 'B'
12

Khả năng tương thích của loại trả về với các lớp nội bộ

Trước PHP 8. 1, hầu hết các lớp hoặc phương thức bên trong không khai báo kiểu trả về của chúng và mọi kiểu trả về đều được phép khi mở rộng chúng

Kể từ PHP 8. 1. 0, hầu hết các phương thức nội bộ bắt đầu "tạm thời" khai báo kiểu trả về của chúng, trong trường hợp đó, kiểu trả về của các phương thức phải tương thích với kiểu gốc được mở rộng; . Lưu ý rằng việc thiếu khai báo trả về rõ ràng cũng được coi là chữ ký không khớp và do đó dẫn đến thông báo không dùng nữa

Nếu kiểu trả về không thể được khai báo cho một phương thức ghi đè do lo ngại về khả năng tương thích giữa các phiên bản PHP, một thuộc tính

class Example
{
	use FooTrait;

	public function bar()
	{
		return 'B';
	}
}

echo (new Example())->bar(); // Outputs 'B'
13 có thể được thêm vào để tắt thông báo không dùng nữa

Làm cách nào để ghi đè lên một hàm trong PHP?

Trong ghi đè hàm, cả lớp cha và lớp con phải có cùng tên hàm và số đối số . Nó được sử dụng để thay thế phương thức cha trong lớp con. Mục đích của việc ghi đè là thay đổi hành vi của phương thức lớp cha. Hai phương thức có cùng tên và cùng tham số được gọi là ghi đè.

Làm cách nào để xác định lại chức năng PHP?

Bạn không thể xác định lại hoặc 'bỏ xác định' một hàm trong PHP (mà không cần dùng đến các mô-đun của bên thứ ba). Tuy nhiên, bạn có thể xác định một chức năng có điều kiện. Với lời cảnh báo xa hơn rằng các cuộc gọi đến sau các định nghĩa. (PHP gần đây không quan tâm đến việc gọi/xác định thứ tự cho các hàm được xác định vô điều kiện. )

Làm cách nào để ghi đè chức năng mặc định trong PHP?

Bạn có thể sử dụng không gian tên để ghi đè tên hàm hiện có . không gian tên blarg; . e. , mọi lệnh gọi tới tên cơ sở() trong không gian tên blarg sẽ sử dụng phiên bản hàm mới của bạn. Hãy nhớ rằng không gian tên chỉ được hỗ trợ trong PHP 5. 3 trở lên.

Làm cách nào bạn có thể tạo một phương thức Không thể ghi đè trong PHP?

Từ khóa final ngăn các lớp con ghi đè một phương thức hoặc hằng số bằng cách thêm tiền tố định nghĩa bằng final .