HomeLập trìnhPythonLập trình hướng...

Lập trình hướng đối tượng trong Python


Python là một ngôn ngữ lập trình tuyệt vời cho phép bạn sử dụng cả mô hình lập trình hướng đối tượng và chức năng.

Các lập trình viên Python có thể sử dụng các khái niệm lập trình hướng đối tượng cơ bản, cho dù họ là nhà phát triển phần mềm, kỹ sư máy học hay cái gì khác.

Tất cả bốn khía cạnh cốt lõi của khung OOP chung đều được hỗ trợ bởi hệ thống lập trình hướng đối tượng của Python: đóng gói, trừu tượng hóa, kế thừa và đa hình.

Trong hướng dẫn này, chúng ta sẽ xem nhanh các tính năng này và thực hành với chúng.

Lớp học và đối tượng là gì?

Python, giống như mọi ngôn ngữ hướng đối tượng khác, cho phép bạn định nghĩa các lớp để tạo đối tượng. Các lớp Python dựng sẵn là các kiểu dữ liệu phổ biến nhất trong Python, chẳng hạn như chuỗi, danh sách, từ điển, v.v.

Một lớp là một tập hợp các biến thể hiện và các phương thức liên quan xác định một loại đối tượng cụ thể. Bạn có thể coi một lớp là bản thiết kế hoặc khuôn mẫu của một đối tượng. Thuộc tính là tên được đặt cho các biến tạo nên một lớp.

Một thể hiện của lớp với một tập hợp các thuộc tính được xác định được gọi là một đối tượng. Kết quả là, cùng một lớp có thể được sử dụng để xây dựng nhiều đối tượng nếu cần.

Hãy định nghĩa một lớp có tên Sách cho một phần mềm bán hàng của nhà sách.

class Book:
    def __init__(self, title, quantity, author, price):
        self.title = title
        self.quantity = quantity
        self.author = author
        self.price = price

Các __init__ phương pháp đặc biệt, còn được gọi là một Người xây dựngđược sử dụng để khởi tạo lớp Sách với các thuộc tính như tên sách, số lượng, tác giả và giá.

Trong Python, các lớp dựng sẵn được đặt tên bằng chữ thường, nhưng các lớp do người dùng định nghĩa được đặt tên bằng chữ Camel hoặc Snake, với chữ cái đầu tiên được viết hoa.

Lớp này có thể được khởi tạo cho bất kỳ số lượng đối tượng nào. Ba cuốn sách được khởi tạo trong mã ví dụ sau:

book1 = Book('Book 1', 12, 'Author 1', 120)
book2 = Book('Book 2', 18, 'Author 2', 220)
book3 = Book('Book 3', 28, 'Author 3', 320)

book1, book2 và book3 là các đối tượng riêng biệt của lớp Sách. thuật ngữ bản thân trong các thuộc tính đề cập đến các thể hiện (đối tượng) tương ứng.

print(book1)
print(book2)
print(book3)

Đầu ra:

<__main__.Book object at 0x00000156EE59A9D0>
<__main__.Book object at 0x00000156EE59A8B0>
<__main__.Book object at 0x00000156EE59ADF0>

Lớp và vị trí bộ nhớ của các đối tượng được in khi chúng được in. Chúng tôi không thể mong đợi họ cung cấp thông tin cụ thể về phẩm chất, chẳng hạn như tiêu đề, tên tác giả, v.v. Nhưng chúng ta có thể sử dụng một phương pháp cụ thể gọi là __repr__ để làm điều này.

Trong Python, một phương thức đặc biệt là một hàm được xác định bắt đầu và kết thúc bằng hai dấu gạch dưới và được gọi tự động khi đáp ứng một số điều kiện nhất định.

class Book:
    def __init__(self, title, quantity, author, price):
        self.title = title
        self.quantity = quantity
        self.author = author
        self.price = price

    def __repr__(self):
        return f"Book: {self.title}, Quantity: {self.quantity}, Author: {self.author}, Price: {self.price}"


book1 = Book('Book 1', 12, 'Author 1', 120)
book2 = Book('Book 2', 18, 'Author 2', 220)
book3 = Book('Book 3', 28, 'Author 3', 320)

print(book1)
print(book2)
print(book3)

Đầu ra:

Book: Book 1, Quantity: 12, Author: Author 1, Price: 120
Book: Book 2, Quantity: 18, Author: Author 2, Price: 220
Book: Book 3, Quantity: 28, Author: Author 3, Price: 320

Đóng gói là gì?

Đóng gói là quá trình ngăn không cho khách hàng truy cập vào một số thuộc tính nhất định, chỉ có thể truy cập được thông qua các phương thức cụ thể.

Đọc thêm  SyntaxError EOF không mong muốn trong khi phân tích lỗi Python [Solved]

Thuộc tính riêng tư là thuộc tính không thể truy cập được và ẩn thông tin là quá trình làm cho các thuộc tính cụ thể trở nên riêng tư. Bạn sử dụng hai dấu gạch dưới để khai báo các đặc điểm riêng tư.

Hãy giới thiệu một thuộc tính riêng gọi là __discount bên trong Sách lớp.

class Book:
    def __init__(self, title, quantity, author, price):
        self.title = title
        self.quantity = quantity
        self.author = author
        self.price = price
        self.__discount = 0.10

    def __repr__(self):
        return f"Book: {self.title}, Quantity: {self.quantity}, Author: {self.author}, Price: {self.price}"


book1 = Book('Book 1', 12, 'Author 1', 120)

print(book1.title)
print(book1.quantity)
print(book1.author)
print(book1.price)
print(book1.__discount)

Đầu ra:

Book 1
12
Author 1
120
Traceback (most recent call last):
  File "C:\Users\ashut\Desktop\Test\hello\test.py", line 19, in <module>
    print(book1.__discount)
AttributeError: 'Book' object has no attribute '__discount'

Chúng ta có thể thấy rằng tất cả các thuộc tính được in ngoại trừ thuộc tính riêng tư __discount. Bạn sử dụng các phương thức getter và setter để truy cập các thuộc tính riêng tư.

Chúng tôi đặt thuộc tính giá ở chế độ riêng tư trong ví dụ mã sau và chúng tôi sử dụng phương thức setter để gán thuộc tính giảm giá và hàm getter để lấy thuộc tính giá.

class Book:
    def __init__(self, title, quantity, author, price):
        self.title = title
        self.quantity = quantity
        self.author = author
        self.__price = price
        self.__discount = None

    def set_discount(self, discount):
        self.__discount = discount

    def get_price(self):
        if self.__discount:
            return self.__price * (1-self.__discount)
        return self.__price

    def __repr__(self):
        return f"Book: {self.title}, Quantity: {self.quantity}, Author: {self.author}, Price: {self.get_price()}"

Lần này chúng ta sẽ tạo hai đối tượng, một đối tượng để mua một cuốn sách và một đối tượng khác để mua sách với số lượng lớn. Trong khi mua sách với số lượng lớn, chúng tôi được giảm giá 20%, vì vậy chúng tôi sẽ sử dụng set_discount() phương pháp đặt chiết khấu thành 20% trong trường hợp đó.

single_book = Book('Two States', 1, 'Chetan Bhagat', 200)

bulk_books = Book('Two States', 25, 'Chetan Bhagat', 200)
bulk_books.set_discount(0.20)

print(single_book.get_price())
print(bulk_books.get_price())
print(single_book)
print(bulk_books)

Đầu ra:

200
160.0
Book: Two States, Quantity: 1, Author: Chetan Bhagat, Price: 200
Book: Two States, Quantity: 25, Author: Chetan Bhagat, Price: 160.0

Kế thừa là gì?

Kế thừa được coi là đặc điểm quan trọng nhất của OOP. Khả năng kế thừa các phương thức và/hoặc đặc điểm của một lớp từ một lớp khác được gọi là tính kế thừa.

Lớp con hoặc lớp con là lớp kế thừa. Lớp cha hoặc lớp cha là lớp mà các phương thức và/hoặc thuộc tính được kế thừa từ đó.

Hai lớp mới đã được thêm vào phần mềm bán sách của chúng tôi: một Cuốn tiểu thuyết lớp học và Thuộc về lý thuyết lớp.

Chúng ta có thể thấy rằng bất kể một cuốn sách được phân loại là tiểu thuyết hay học thuật, nó có thể có một số thuộc tính giống nhau như tiêu đề và tác giả, cũng như các phương pháp phổ biến như get_price()set_discount(). Viết lại tất cả mã đó cho mỗi lớp mới là một sự lãng phí thời gian, công sức và bộ nhớ.

class Book:
    def __init__(self, title, quantity, author, price):
        self.title = title
        self.quantity = quantity
        self.author = author
        self.__price = price
        self.__discount = None

    def set_discount(self, discount):
        self.__discount = discount

    def get_price(self):
        if self.__discount:
            return self.__price * (1-self.__discount)
        return self.__price

    def __repr__(self):
        return f"Book: {self.title}, Quantity: {self.quantity}, Author: {self.author}, Price: {self.get_price()}"


class Novel(Book):
    def __init__(self, title, quantity, author, price, pages):
        super().__init__(title, quantity, author, price)
        self.pages = pages


class Academic(Book):
    def __init__(self, title, quantity, author, price, branch):
        super().__init__(title, quantity, author, price)
        self.branch = branch

Hãy tạo các đối tượng cho các lớp này để trực quan hóa chúng.

novel1 = Novel('Two States', 20, 'Chetan Bhagat', 200, 187)
novel1.set_discount(0.20)

academic1 = Academic('Python Foundations', 12, 'PSF', 655, 'IT')

print(novel1)
print(academic1)

Đầu ra:

Book: Two States, Quantity: 20, Author: Chetan Bhagat, Price: 160.0
Book: Python Foundations, Quantity: 12, Author: PSF, Price: 655

Đa hình là gì?

Thuật ngữ ‘tính đa hình‘ xuất phát từ tiếng Hy Lạp và có nghĩa là ‘một cái gì đó có nhiều hình thức.

Đọc thêm  Hiểu từ điển trong Python – Giải thích bằng các ví dụ

Tính đa hình đề cập đến khả năng của một lớp con để điều chỉnh một phương thức đã tồn tại trong lớp cha của nó để đáp ứng nhu cầu của nó. Nói cách khác, một lớp con có thể sử dụng một phương thức từ lớp cha của nó hoặc sửa đổi nó khi cần.

class Academic(Book):
    def __init__(self, title, quantity, author, price, branch):
        super().__init__(title, quantity, author, price)
        self.branch = branch

    def __repr__(self):
        return f"Book: {self.title}, Branch: {self.branch}, Quantity: {self.quantity}, Author: {self.author}, Price: {self.get_price()}"

Các Sách siêu lớp có một phương pháp cụ thể được gọi là __repr__. Phương thức này có thể được sử dụng bởi lớp con Novel để nó được gọi bất cứ khi nào một đối tượng được in.

Các Thuộc về lý thuyết lớp con, mặt khác, được định nghĩa với chính nó __repr__ chức năng đặc biệt trong mã ví dụ ở trên. Các Thuộc về lý thuyết lớp con sẽ gọi phương thức riêng của nó bằng cách triệt tiêu phương thức tương tự có trong lớp cha của nó, nhờ tính đa hình.

novel1 = Novel('Two States', 20, 'Chetan Bhagat', 200, 187)
novel1.set_discount(0.20)

academic1 = Academic('Python Foundations', 12, 'PSF', 655, 'IT')

print(novel1)
print(academic1)

Đầu ra:

Book: Two States, Quantity: 20, Author: Chetan Bhagat, Price: 160.0
Book: Python Foundations, Branch: IT, Quantity: 12, Author: PSF, Price: 655

Trừu tượng là gì?

Tính trừu tượng không được hỗ trợ trực tiếp trong Python. Mặt khác, việc gọi một phương thức ma thuật cho phép trừu tượng hóa.

Nếu một phương thức trừu tượng được khai báo trong một lớp cha, thì các lớp con kế thừa từ lớp cha phải có cách triển khai phương thức của riêng chúng.

Phương thức trừu tượng của lớp cha sẽ không bao giờ được gọi bởi các lớp con của nó. Nhưng sự trừu tượng hỗ trợ trong việc duy trì một cấu trúc tương tự trên tất cả các lớp con.

Trong lớp cha mẹ của chúng tôi Sáchchúng tôi đã xác định __repr__ phương pháp. Hãy làm cho phương thức đó trở nên trừu tượng, buộc mọi lớp con bắt buộc phải có phương thức riêng __repr__ phương pháp.

from abc import ABC, abstractmethod


class Book(ABC):
    def __init__(self, title, quantity, author, price):
        self.title = title
        self.quantity = quantity
        self.author = author
        self.__price = price
        self.__discount = None

    def set_discount(self, discount):
        self.__discount = discount

    def get_price(self):
        if self.__discount:
            return self.__price * (1-self.__discount)
        return self.__price

    @abstractmethod
    def __repr__(self):
        return f"Book: {self.title}, Quantity: {self.quantity}, Author: {self.author}, Price: {self.get_price()}"


class Novel(Book):
    def __init__(self, title, quantity, author, price, pages):
        super().__init__(title, quantity, author, price)
        self.pages = pages


class Academic(Book):
    def __init__(self, title, quantity, author, price, branch):
        super().__init__(title, quantity, author, price)
        self.branch = branch

    def __repr__(self):
        return f"Book: {self.title}, Branch: {self.branch}, Quantity: {self.quantity}, Author: {self.author}, Price: {self.get_price()}"


novel1 = Novel('Two States', 20, 'Chetan Bhagat', 200, 187)
novel1.set_discount(0.20)

academic1 = Academic('Python Foundations', 12, 'PSF', 655, 'IT')

print(novel1)
print(academic1)

Trong đoạn mã trên, chúng ta đã kế thừa ABC lớp để tạo ra Sách lớp. chúng tôi đã thực hiện __repr__ phương thức trừu tượng bằng cách thêm @abstractmethod người trang trí.

Đọc thêm  Cách sử dụng Python để thu thập các đánh giá trên App Store

Trong khi tạo lớp Novel, chúng tôi đã cố tình bỏ qua việc triển khai __repr__ phương pháp để xem những gì xảy ra.

Đầu ra:

Traceback (most recent call last):
  File "C:\Users\ashut\Desktop\Test\hello\test.py", line 40, in <module>
    novel1 = Novel('Two States', 20, 'Chetan Bhagat', 200, 187)
TypeError: Can't instantiate abstract class Novel with abstract method __repr__

chúng tôi nhận được một LoạiLỗi nói rằng chúng ta không thể khởi tạo đối tượng của lớp Novel. Hãy thêm việc thực hiện của __repr__ phương pháp và xem những gì xảy ra bây giờ.

class Novel(Book):
    def __init__(self, title, quantity, author, price, pages):
        super().__init__(title, quantity, author, price)
        self.pages = pages

    def __repr__(self):
        return f"Book: {self.title}, Quantity: {self.quantity}, Author: {self.author}, Price: {self.get_price()}"

Đầu ra:

Book: Two States, Quantity: 20, Author: Chetan Bhagat, Price: 160.0
Book: Python Foundations, Branch: IT, Quantity: 12, Author: PSF, Price: 655

Bây giờ nó hoạt động tốt.

Quá tải phương thức

Khái niệm nạp chồng phương thức được tìm thấy trong hầu hết mọi ngôn ngữ lập trình nổi tiếng tuân theo các khái niệm lập trình hướng đối tượng. Nó chỉ đơn giản đề cập đến việc sử dụng nhiều phương thức có cùng tên, nhận nhiều đối số khác nhau trong một lớp.

Bây giờ chúng ta hãy hiểu quá tải phương thức với sự trợ giúp của đoạn mã sau:

class OverloadingDemo:
    def add(self, x, y):
        print(x+y)

    def add(self, x, y, z):
        print(x+y+z)


obj = OverloadingDemo()
obj.add(2, 3)

Đầu ra:

Traceback (most recent call last):
  File "C:\Users\ashut\Desktop\Test\hello\setup.py", line 10, in <module>
    obj.add(2, 3)
TypeError: add() missing 1 required positional argument: 'z'

Bạn có thể tự hỏi tại sao điều này xảy ra. Kết quả là, lỗi được hiển thị vì Python chỉ nhớ định nghĩa gần đây nhất của add(self, x, y, z), định nghĩa này có thêm ba tham số ngoài self. Kết quả là, ba đối số phải được chuyển đến add() phương thức khi nó được gọi. Nói cách khác, nó bỏ qua định nghĩa trước đó của add().

Như vậy, Trăn không hỗ trợ Quá tải phương thức theo mặc định.

Ghi đè phương thức

Khi một phương thức có cùng tên và đối số được sử dụng trong cả lớp dẫn xuất và lớp cơ sở hoặc siêu lớp, chúng ta nói rằng phương thức lớp dẫn xuất “ghi đè” phương thức được cung cấp trong lớp cơ sở.

Khi phương thức ghi đè được gọi, phương thức của lớp dẫn xuất luôn được gọi. Phương thức được sử dụng trong lớp cơ sở hiện đã bị ẩn.

class ParentClass:
    def call_me(self):
        print("I am parent class")


class ChildClass(ParentClass):
    def call_me(self):
        print("I am child class")

pobj = ParentClass()
pobj.call_me()

cobj = ChildClass()
cobj.call_me()

Đầu ra:

I am parent class
I am child class

Trong đoạn mã trên, khi call_me() phương thức được gọi trên đối tượng con, call_me() từ lớp con đã được gọi. Chúng ta có thể gọi lớp cha của call_me() phương thức từ lớp con bằng cách sử dụng super()như thế này:

class ParentClass:
    def call_me(self):
        print("I am parent class")


class ChildClass(ParentClass):
    def call_me(self):
        print("I am child class")
        super().call_me()

pobj = ParentClass()
pobj.call_me()

cobj = ChildClass()
cobj.call_me()

Đầu ra:

I am parent class
I am child class
I am parent class

kết thúc

Trong bài viết này, chúng tôi đã đề cập đến ý nghĩa của các lớp và đối tượng. Chúng tôi cũng đề cập đến bốn trụ cột của Lập trình hướng đối tượng.

Ngoài ra, chúng tôi cũng đã đề cập đến hai chủ đề quan trọng – Nạp chồng phương thức và Ghi đè phương thức.

Cảm ơn vì đã đọc!

Đăng ký nhận bản tin của tôi



Zik.vn – Biên dịch & Biên soạn Lại

spot_img

Create a website from scratch

Just drag and drop elements in a page to get started with Newspaper Theme.

Buy Now ⟶

Bài viết liên quang

DMCA.com Protection Status