// Lớp Con
class ConHeo extends DongVat{ public function An(){ parent::An();
echo 'Con Heo Đang Ăn Cám';
}
}
// Khai Báo Lớp on
$conheo = new ConHeo();
// Gọi Hàm Ăn Trong Lớp ConHeo
$conheo->An();
Ta thấy lớp ConHeo đã định nghĩa lại hàm An() của lớp DongVat nên khi gọi đến hàm An() sẽ được tính là gọi ở lớp ConHeo, nếu trong lớp ConHeo không có ham An() thì lúc này mới tính ở hàm DongVat.
Có thể bạn quan tâm!
- Trừu Tượng Hoá Dữ Liệu Ví Dụ: Xây Dựng Chương Trình Quản Lý Sinh Viên
- Các Đối Tượng Trong Trong Thế Giới Thực
- Tính Đa Hình Trong Lập Trình Hướng Đối Tượng Php
- Truyền Và Xử Lý Dữ Liệu Trong Php
- Lập trình mã nguồn mở - 16
- Lỗi Phát Sinh Truy Cập Session Chưa Tồn Tại
Xem toàn bộ 270 trang tài liệu này.
Vậy bản chất của tính đa hình là là kỹ thuật cho phép thay đổi nội dung cùng một hành vi (hàm) trong hai lớp cha và con, hay nói cách khác là viết lại hàm ở lớp cha trong lớp con.
Vi dụ:
// Lớp Hình Học class HinhHoc{
// Hàm Vẽ Hình function Ve(){
// Code
}
// Hàm Tính Diện Tích Của Hình function tinh_Dien_Tich(){
// Code
}
}
// Lớp hình Vuông
class HinhVuong extends HinhHoc{
// Độ Dài Cạnh public $canh = 0;
// Định Nghĩa Lại Hàm Vẽ Hình Vuông function Ve(){
echo 'Vẽ Hình Vuông';
}
// Định Nghĩa Lại Hàm Tính Diện Tích function tinh_Dien_Tich(){
return $this->canh*$this->canh;
}
}
// Lớp hình chữ nhật
class HinhChuNhat extends HinhHoc{
// Chiều Dài Và Chiều Rộng public $dai = 0;
public $rong = 0;
// Định Nghĩa Lại Hàm Vẽ Hình Chữ Nhật public function Ve(){
echo 'Vẽ Hình Chữ Nhật';
}
// Định Nghĩa Lại Hàm Tính Diện Tích public function tinh_Dien_Tich(){ return $this->dai * $this->rong;
}
}
// ------------------ //
// Chương Trình Chính //
// ------------------ //
// Hình Chữ Nhật
$HinhChuNhat = new HinhChuNhat();
$HinhChuNhat->Ve(); echo '<br/>';
$HinhChuNhat->dai = 25;
$HinhChuNhat->rong = 20;
echo $HinhChuNhat->tinh_Dien_Tich(); echo '<br/>';
// Hình Vuông
$HinhVuong = new HinhVuong();
$HinhVuong->Ve(); echo '<br/>';
$HinhVuong->canh = 20;
echo $HinhVuong->tinh_Dien_Tich();
Trong ví dụ này lớp HinhHoc là lớp biểu hiện cho các hình học không gian, lớp HinhVuong và HinhChuNhat là hai hình xác định nằm trong hình học không gian.
Trong hình học không gian có các hành động như vẽ hình, tính diện tích nên ta khai báo hai hàm đó ở lớp HinhHoc.
Ở lớp HinhVuong và HinhChuNhat viết lại hai hàm tính diện tích và vẽ hình vì mỗi hình có một cách tính khác nhau, nên nếu viết ở lớp HinhHoc thì không thể biểu diễn ra được cho tất cả các hình.
Lưu ý: Khi viết lại hàm thì các biến truyền vào hàm ở lớp cha và lớp con phải khớp nhau, nghĩa là hàm ở lớp cha truyền vào bao nhiêu biến thì hàm ở lớp con truyền vào bấy nhiêu biến.
2.11.9 Tính đóng gói trong lập trình hướng đối
Tính đóng gói là tính chất không cho phép người dùng hay đối tượng khác thay đổi dữ liệu thành viên của đối tượng nội tại. Chỉ có các hàm thành viên của đối tượng đó mới có quyền thay đổi trạng thái nội tại của nó mà thôi. Các đối tượng khác muốn thay đổi thuộc tính thành viên của đối tượng nội tại, thì chúng cần truyền thông điệp cho đối tượng, và việc quyết định thay đổi hay không vẫn do đối tượng nội tại quyết định.
Ta có thể hiểu nôm la tính đóng gói là không cho bên ngoài biết được bên trong đối tượng có những gì hay được cài đặt như thế nào. Nếu muốn thay đổi bên trong đối tượng thì phải được sự chấp nhận của đối tượng đó thông qua ba mức độ truy cập private protected và public.
Ví dụ trong đối tượng kế toán có một chức năng tính lương, chức năng này có những phép tính mà các đối tượng khác không hề biết cách tính nó như thế nào. Đối tượng kế toán sẽ có những chức năng dành cho các hàm kế thừa nó có thể truy xuất vào và thông qua ba mức độ truy cập để giới hạn chúng. đây cũng chính là bảo mật thông tin cho đối tượng.
2.11.10 Hàm khởi tạo và hàm hủy
1) Hàm khởi tạo
Hàm khởi tạo cũng là một hàm bình thường nhưng có điểm đặc biệt là nó luôn luôn được gọi tới khi ta khởi tạo một đối tượng. Hàm khởi tạo có thể có tham số hoặc không có tham số, có thể có giá trị trả về hoặc không. Ở một hàm khác cũng có thể gọi lại hàm khởi tạo được. Trong một lớp có thể có hàm khởi tạo hoặc không. Trong php hàm khởi tạo có tên trùng tên với lớp hoặc có tên là ( _construct() ).
Ví dụ:
class SinhVien
{
functionconstruct()
{
echo 'Lớp Sinh Viên vừa được khởi tạo';
}
}
// khởi tạo lớp SinhVien
$sinhvien = new SinhVien();
Kết quả của đoạn code này sẽ xuất ra màn hình dòng chữ “Lớp Sinh Viên vừa được khởi tạo” vì khi khởi tạo đối tượng SinhVien thì hàm khởi tạo _construct() sẽ được chạy.
Cũng có thể khai báo hàm khởi tạo với tên chính là tên của lớp như ví dụ sau:
class SinhVien{ function SinhVien() {
echo 'Lớp Sinh Viên vừa được khởi tạo';
}
}
// khởi tạo lớp SinhVien
$sinhvien = new SinhVien();
Hàm khởi tạo cũng có thể có các đối số, để truyền đối số lúc khởi tạo ta làm như sau:
class SinhVien{
function _construct($message) { echo $message;
}
}
// khởi tạo lớp SinhVien
$sinhvien = new SinhVien('Lớp Sinh Viên vừa được khởi tạo');
2) Hàm khởi tạo trong kế thừa
Khi lớp con kế thừa lớp cha thì khi ta tạo một lớp con mới sẽ có các trường hợp xảy ra sau đây:
Trường hợp 1: Nếu lớp con có hàm khởi tạo và lớp cha có hàm khởi tạo
Trường hợp này hàm khởi tạo của lớp con sẽ được chạy, còn hàm khởi tạo ở lớp cha không được chạy.
Ví dụ:
class A {
function _construct() {
echo 'Lớp A được khởi tạo';
}
}
class B extends A { function _construct() {
echo 'Lớp B được khởi tạo';
}
}
$a = new B(); // Kết quả là Lớp B được khởi tạo
Kết quả xuất ra màn hình là “Lớp B được khởi tạo”.
Trường hợp 2: Nếu lớp con không có hàm khởi tạo, lớp cha có hàm khởi tạo Trường hợp này hàm khởi tạo ở lớp cha sẽ được chạy
Ví dụ:
// Lớp A class A {
functionconstruct() { echo 'Lớp A được khởi tạo';
}
}
// Lớp B
class B extends A {
}
// Khởi Tạo Lớp B
$a = new B(); // Kết quả là Lớp A Chạy
Kết quả xuất ra màn hình là “Lớp A được khởi tạo”
Trường hợp 3: Lớp Con có hàm khởi tạo, lớp cha không có hàm khởi tạo Trường hợp này hàm khởi tạo lớp con sẽ được chạy
Ví dụ:
// Lớp A class A {
}
// Lớp B
class B extends A{ functionconstruct() {
echo 'Lớp B được khởi tạo';
}
}
// Khởi Tạo Lớp B
$a = new B(); // Kết quả là Lớp B Chạy
Kết quả xuất ra màn hình là “Lớp B được khởi tạo”
Trường hợp 4: Cả hai lớp cha và lớp con đều không có hàm khởi tạo Trường hợp này đương nhiên là sẽ không có hàm nào được chạyVí dụ:
// Lớp A class A {
}
// Lớp B
class B extends A {
}
// Khởi Tạo Lớp B
$a = new B(); // Kết quả là Không có gì
3) Hàm hủy
Hàm hủy là hàm tự động gọi sau khi đối tượng bị hủy. Nó thường được sử dụng để giải phóng bộ nhớ chương trình. Trong đối tượng, hàm hủy có thể có hoặc không.
Ví dụ:
// Lớp A class A
{
functionconstruct()
{
echo 'Lớp A được khởi tạo <br/>';
}
function show(
{
echo 'Lớp A đang được sử dụng <br/>';
}
functiondestruct() {
echo 'Lớp A bị hủy <br/>';
}
}
// Chương trình
$a = new A();
$a->show();
Kết quả hiển thị ra màn hình là:
“Lớp A được khởi tạo Lớp A đang được sử dụng Lớp A bị hủy”
4) Hàm hủy trong kế thừa
Tương tự như hàm khởi tạo trong kế thừa. Nếu lớp con có hàm hủy thì được ưu tiên chạy, còn nếu lớp con không có hàm hủy thì sẽ chạy ở lớp cha, còn nếu cả hai đều không có thì sẽ không chạy hàm nào.
2.11.11 Lớp trừu tượng (Abstract)
1) Lớp trừu tượng (Abstract)
Trong PHP đây cũng là một tính chất của lập trình hướng đối tượng nhưng nó không được xếp vào tính chất quan trọng, tính chất này giống như tính kế thừa theo tầm nhìn bề ngoài. Lớp Abstract sẽ định nghĩa các hàm (phương thức) mà từ đó các lớp con sẽ kế thừa nó và Overwrite lại (tính đa hình). Tất cả các phương thức của lớp abstract đều phải được khai báo là abstract và phải ở mức protected và public, không được ở mức private. Lớp Abstract có thể có thuộc tính nhưng thuộc tính không được khai báo là abstract, và không thể khởi tạo một biến của lớp Abstract được.
Để khai báo một lớp Abstract ta dùng cú pháp sau:
abstract class BaseClass{
// phương thức ở mức protected abstract protected function hello();
// Phương thức ở mức public abstract public function hi();
}
Trong lớp Abstract các phương thức khai báo ở dạng Abstract đều phải tuân theo cú pháp trên, tức là không được định nghĩa thêm dòng lệnh nào bên trong nó.
Như ví dụ dưới này là sai.
abstract class BaseClass{
// Phương thức này sai vì hàm hello là
// hàm abstract nên không được code bên trong nó abstract protected function hello(){
// dòng code
}
}
Không thể tạo một biến đối tượng mới của lớp Abstract, như ví dụ dưới này là sai:
abstract class BaseClass{
abstract protected function hello();
}
// Sai vì BaseClass là lớp Abstract nên không
// khởi tạo mới được
$base = new BaseClass();
Mức truy cập các hàm của Abstract phải ở public hoặc protected để lớp kế thừa có thể định nghĩa lại và các thuộc tính của lớp Abstract không được khai báo Abstract. Ví dụ:
abstract class BaseClass{
// Đúng public $name;
// Sai vì các thuộc tính không được để ở dạng abstract abstract public $title;
// Đúng
abstract protected function hello();
// Sai vì hàm abstract không thể ở private abstract private function hi_there();
}
Lớp kế thừa từ lớp Abstracth phải Rewrite lại tất cả các hàm Abstract trong lớp Abstract, nếu không sẽ bị báo sai.
Ví dụ:
abstract class Person
{
protected $ten; protected $cmnd; protected $namsinh;
abstract public function showInfo();
}
// Lớp này sai vì chưa viết lại hàm showInfo class CongNhan extends Person{
}
// Lớp này đúng vì ta đã khai báo, viết lại
// đầy đủ các hàm abstract class SinhVien extends Person{ public function showInfo(){
}
}
2) Hàm và lớp Final
Lớp Final là lớp được khai báo là lớp cuối cùng, không một lớp nào có thể kế thừa nó. Tương tự như hàm Final trong Abstract hoặc trong kế thừa chỉ để gọi sử dụng, không được viết lại (Overwrite). Để dễ hình dung ta xét ví dụ sau đây và thông qua phần ghi chú đã giải thích.