Python kế thừa từ đối tượng

Lập trình hướng đối tượng [tiếng Anh. Lập trình hướng đối tượng viết tắt. OOP] là một kỹ thuật hỗ trợ, cho phép lập trình viên trực tiếp làm việc với các đối tượng mà chúng định nghĩa. Hiệu quả của kỹ thuật này giúp nâng cao hiệu quả, đơn giản hóa độ phức tạp khi bảo trì cũng như mở rộng phần mềm. Hiện nay có khá nhiều ngôn ngữ lập trình theo hướng đối tượng như C++, Java, PHP,… và cả Python

Khái niệm về OOP trong Python tập trung vào việc tạo mã sử dụng lại. Ý niệm này còn được gọi là DRY [Don't Repeat Yourself]

Các nguyên lý

Trong Python, khái niệm về OOP tuân theo một số nguyên lý cơ bản là tính đóng gói, tính kế thừa và tính đa hình

Tính kế thừa [Inheritance]. cho phép một lớp [lớp] có thể kế thừa các thuộc tính và phương thức từ các lớp khác đã được định nghĩa

Tính đóng gói [Encapsulation]. là quy tắc yêu cầu trạng thái bên trong của một đối tượng được bảo vệ và tránh truy cập từ mã bên ngoài [tức là mã bên ngoài không thể trực tiếp nhìn thấy và thay đổi trạng thái của đối tượng đó]

Tính đa hình [Polymorphism]. là khái niệm mà hai hoặc nhiều lớp có các phương thức giống nhau nhưng có thể thực thi theo các cách thức khác nhau

Lớp [Class] và Đối tượng [Object]

Lớp và Đối tượng là hai khái niệm cơ bản trong việc thiết lập hướng đối tượng

Đối tượng [Object] là những cái có thể tồn tại trong hành vi

Ví dụ đối tượng là xe ô tô có tên hãng, màu sắc, loại nguyên liệu, hành vi đi, dừng, đỗ, nổ máy…

Lớp [Lớp] là một kiểu dữ liệu đặc biệt do người dùng định nghĩa, tập hợp nhiều thuộc tính đặc trưng cho mọi đối tượng được tạo ra từ lớp đó

Thuộc tính là giá trị của lớp. Sau này khi các đối tượng được tạo ra từ lớp, thì thuộc tính của lớp lúc này sẽ trở thành đặc điểm của đối tượng đó

Phân biệt giữa Đối tượng [Object] và Lớp [Class]

Đối tượng [Object]. has status and actions

Lớp [Lớp]. could be default as a template description the status and behavior that the type of objects of support layer. Một đối tượng là một thực thể [thể hiện] của một lớp

Ví dụ về Class và Object

Kết quả trả lại sẽ là

Chương trình trên việc tạo một lớp Xe, sau đó xác định các thuộc tính, đặc điểm của đối tượng

Chúng ta truy cập thuộc tính lớp bằng cách sử dụng __lớp __. loaixe. Các thuộc tính của lớp được chia sẻ cho tất cả các cá thể của lớp

Tương tự, chúng ta truy cập các thuộc tính ví dụ bằng cách sử dụng toyota. tenxe, toyota. mausac và toyota. nguyễnliêu

Tuy nhiên, các thuộc tính instance là khác nhau đối với mỗi cá thể của một lớp

Phương thức

Phương thức [Phương thức] là các hàm được định nghĩa bên trong phần thân của một lớp. Chúng được sử dụng để xác định các hành động của một đối tượng

Ví dụ về Class và Method

Chạy chương trình, màn hình sẽ trả về kết quả

Kế thừa [Inheritance]

Tính kế thừa cho phép một lớp [lớp] có thể kế thừa các thuộc tính và phương thức từ các lớp khác nhau đã được định nghĩa. Lớp đã được gọi là lớp cha, lớp mới phát sinh gọi là lớp con. Lớp con kế thừa tất cả các thành phần của lớp cha, có thể mở rộng các thành phần kế thừa và bổ sung thêm các thành phần mới

# Lớp cha
class Car:

     # Constructor
     def __init__[self, hangxe, tenxe, mausac]:
        # Lớp Car có 3 thuộc tính: tenxe, mausac, hang xe
 self.hangxe = hangxe
        self.tenxe = tenxe
        self.mausac = mausac

     # phương thức
     def chayxe[self]:
        print ["{} đang chạy trên đường".format[self.tenxe]]

     def dungxe[self, mucdich]:
        print ["{} đang dừng xe để {}".format[self.tenxe, mucdich]]

# Lớp Toyota mở rộng từ lớp Car.
class Toyota[Car]:

     def __init__[self, hangxe, tenxe, mausac, nguyenlieu]:
 # Gọi tới constructor của lớp cha [Car] 
        # để gán giá trị vào thuộc tính của lớp cha.
 super[].__init__[hangxe, tenxe, mausac]

        self.nguyenlieu = nguyenlieu

     # Kế thừa phương thức cũ
     def chayxe[self]:
        print ["{} đang chạy trên đường".format[self.tenxe]]

     # Ghi đè [override] phương thức cùng tên của lớp cha.
     def dungxe[self, mucdich]:
        print ["{} đang dừng xe để {}".format[self.tenxe, mucdich]]
        print ["{} chạy bằng {}".format[self.tenxe, self.nguyenlieu]]

 # Bổ sung thêm thành phần mới 
     def nomay[self]:
        print ["{} đang nổ máy".format[self.tenxe]]

toyota1 = Toyota["Toyota", "Toyota Hilux", "Đỏ", "Điện"]
toyota2 = Toyota["Toyota", "Toyota Yaris", "Vàng", "Deisel"]
toyota3 = Toyota["Toyota", "Toyota Vios", "Xanh", "Gas"]

toyota1.dungxe["nạp điện"]
toyota2.chayxe[]
toyota3.nomay[]

Kết quả trả lại

Toyota Hilux đang dừng xe để nạp điện
Toyota Hilux chạy bằng Điện
Toyota Yaris đang chạy trên đường
Toyota Vios đang nổ máy

Chương trình này tạo hai lớp kế thừa. Lớp cha Xe và Lớp con Toyota

Khai báo hàm tạo mới để gán giá trị cho thuộc tính của lớp cha. Hàm super[] đứng trước phương thức __init __ to call to content __init __ of Car

Lớp Toyota kế thừa hàm chạy xe[] và dừng xe[] của lớp Xe đồng thời sửa đổi một hành vi có thể hiện ở phương thức dungxe[]. Sau đó, lớp con được bổ sung thêm vào phần mới là nomay[] để mở rộng kế thừa

Đóng gói [Encapsulation]

Sử dụng OOP trong Python, chúng ta có thể hạn chế quyền truy cập vào trạng thái bên trong của đối tượng. Điều này ngăn chặn dữ liệu bị thay đổi trực tiếp, được gọi là đóng gói. Trong Python, chúng ta có biểu tượng thuộc tính riêng tư này bằng cách sử dụng dấu gạch dưới để làm tiền tố. “_” hoặc “__“

Màn hình hiển thị kết quả

Ở ví dụ này, bạn khởi tạo lớp Máy tính, sử dụng __init __[] để lưu trữ giá bán tối đa của máy tính. Nhưng sau khi sử dụng, bạn có nhu cầu sửa đổi giá, tuy nhiên không thể thay đổi theo cách thông thường vì Python đã coi __maxprice là thuộc tính riêng tư. Do đó, nên thay đổi giá trị, ta sử dụng setter hàm setMaxPrice[]

Đa hình [Polymorphism]

Tính đa hình là khái niệm mà hai hoặc nhiều lớp có các phương thức giống nhau nhưng có thể thực thi theo các cách thức khác nhau

Giả sử, chúng ta cần tô màu cho một khối hình, có rất nhiều lựa chọn cho hình của bạn như hình chữ nhật, hình vuông, hình tròn. Tuy nhiên, bạn có thể sử dụng cùng một phương pháp để tô màu cho bất kỳ hình dạng nào

class Toyota:

def dungxe[self]:
print["Toyota dừng xe để nạp điện"]

def nomay[self]:
print["Toyota nổ máy bằng hộp số tự động"]

class Porsche:

def dungxe[self]:
print["Porsche dừng xe để bơm xăng"]

def nomay[self]:
print["Porsche nổ máy bằng hộp số cơ"]

# common interface
def
kiemtra_dungxe[car]: car.dungxe[]

# instantiate objects
toyota = Toyota[]
porsche = Porsche[]

# passing the object
kiemtra_dungxe[toyota]
kiemtra_dungxe[porsche]

Ở ví dụ này, bạn vừa tạo hai lớp Toyota và Porsche, cả hai lớp đều có phương thức dungxe[]. Chức năng truy vấn của chúng khác nhau. Ta sử dụng tính năng đa hình để tạo hàm chung cho hai lớp, đó là kiemtra_dungxe[]. Tiếp theo, bạn truyền đối tượng toyota và porsche vào chức năng vừa tạo và ta lấy kết quả như thế này

Toyota dừng xe để nạp điện
Porsche dừng xe để bơm xăng

Ad vừa giới thiệu cho các bạn những điểm nổi bật của OOP rồi. Qua bài viết, có thể rút ra một số nhận xét như sau

Chủ Đề