Lua - Hướng đối tượng
Giới thiệu về OOP
Lập trình hướng đối tượng (OOP), là một kỹ thuật lập trình được sử dụng nhiều nhất trong thời đại lập trình hiện đại. Có một số ngôn ngữ lập trình hỗ trợ OOP bao gồm,
- C++
- Java
- Objective-C
- Smalltalk
- C#
- Ruby
Đặc điểm của OOP
Class - Một lớp là một khuôn mẫu có thể mở rộng để tạo các đối tượng, cung cấp các giá trị ban đầu cho trạng thái (các biến thành viên) và triển khai các hành vi.
Objects - Nó là một thể hiện của lớp và có bộ nhớ riêng được cấp phát cho chính nó.
Inheritance - Là một khái niệm mà các biến và hàm của một lớp này được kế thừa bởi một lớp khác.
Encapsulation- Là quá trình kết hợp dữ liệu và các hàm bên trong một lớp. Dữ liệu có thể được truy cập bên ngoài lớp với sự trợ giúp của các hàm. Nó còn được gọi là trừu tượng hóa dữ liệu.
OOP trong Lua
Bạn có thể triển khai hướng đối tượng trong Lua với sự trợ giúp của bảng và các hàm lớp đầu tiên của Lua. Bằng cách đặt các chức năng và dữ liệu liên quan vào một bảng, một đối tượng được hình thành. Kế thừa có thể được thực hiện với sự trợ giúp của các bảng đo lường, cung cấp cơ chế tra cứu các hàm (phương thức) và trường không tồn tại trong (các) đối tượng mẹ.
Các bảng trong Lua có các tính năng của đối tượng như trạng thái và danh tính độc lập với các giá trị của nó. Hai đối tượng (bảng) có cùng giá trị là các đối tượng khác nhau, ngược lại một đối tượng có thể có giá trị khác nhau tại các thời điểm khác nhau, nhưng nó luôn là cùng một đối tượng. Giống như các đối tượng, các bảng có vòng đời độc lập với việc ai tạo ra chúng hoặc nơi chúng được tạo ra.
Một ví dụ về thế giới thực
Khái niệm hướng đối tượng được sử dụng rộng rãi nhưng bạn cần hiểu rõ về nó để đạt được lợi ích tối đa và phù hợp.
Chúng ta hãy xem xét một ví dụ toán học đơn giản. Chúng ta thường gặp những trường hợp chúng ta làm việc trên các hình dạng khác nhau như hình tròn, hình chữ nhật và hình vuông.
Các hình dạng có thể có một Khu vực thuộc tính chung. Vì vậy, chúng ta có thể mở rộng các hình dạng khác từ hình dạng đối tượng cơ sở với vùng thuộc tính chung. Mỗi hình dạng có thể có các thuộc tính và chức năng riêng của nó như một hình chữ nhật có thể có các thuộc tính chiều dài, chiều rộng, diện tích là thuộc tính của nó và printArea và mathArea là các chức năng của nó.
Tạo một lớp đơn giản
Một lớp đơn giản triển khai cho một hình chữ nhật với ba thuộc tính diện tích, chiều dài và chiều rộng được hiển thị bên dưới. Nó cũng có chức năng printArea để in diện tích được tính toán.
-- Meta class
Rectangle = {area = 0, length = 0, breadth = 0}
-- Derived class method new
function Rectangle:new (o,length,breadth)
o = o or {}
setmetatable(o, self)
self.__index = self
self.length = length or 0
self.breadth = breadth or 0
self.area = length*breadth;
return o
end
-- Derived class method printArea
function Rectangle:printArea ()
print("The area of Rectangle is ",self.area)
end
Tạo một đối tượng
Tạo một đối tượng là quá trình cấp phát bộ nhớ cho cá thể lớp. Mỗi đối tượng có bộ nhớ riêng và chia sẻ dữ liệu lớp chung.
r = Rectangle:new(nil,10,20)
Truy cập thuộc tính
Chúng ta có thể truy cập các thuộc tính trong lớp bằng toán tử dấu chấm như hình dưới đây:
print(r.length)
Truy cập chức năng thành viên
Bạn có thể truy cập một hàm thành viên bằng cách sử dụng toán tử dấu hai chấm với đối tượng như hình dưới đây:
r:printArea()
Bộ nhớ được cấp phát và các giá trị ban đầu được đặt. Quá trình khởi tạo có thể được so sánh với các hàm tạo trong các ngôn ngữ hướng đối tượng khác. Nó không là gì ngoài một chức năng cho phép thiết lập các giá trị như hình trên.
Hoàn thành ví dụ
Hãy xem một ví dụ hoàn chỉnh bằng cách sử dụng hướng đối tượng trong Lua.
-- Meta class
Shape = {area = 0}
-- Base class method new
function Shape:new (o,side)
o = o or {}
setmetatable(o, self)
self.__index = self
side = side or 0
self.area = side*side;
return o
end
-- Base class method printArea
function Shape:printArea ()
print("The area is ",self.area)
end
-- Creating an object
myshape = Shape:new(nil,10)
myshape:printArea()
Khi bạn chạy chương trình trên, bạn sẽ nhận được kết quả sau.
The area is 100
Thừa kế trong Lua
Kế thừa là quá trình mở rộng các đối tượng cơ sở đơn giản như hình dạng thành hình chữ nhật, hình vuông, v.v. Nó thường được sử dụng trong thế giới thực để chia sẻ và mở rộng các thuộc tính và chức năng cơ bản.
Hãy để chúng tôi xem một phần mở rộng lớp đơn giản. Chúng tôi có một lớp như hình dưới đây.
-- Meta class
Shape = {area = 0}
-- Base class method new
function Shape:new (o,side)
o = o or {}
setmetatable(o, self)
self.__index = self
side = side or 0
self.area = side*side;
return o
end
-- Base class method printArea
function Shape:printArea ()
print("The area is ",self.area)
end
Chúng ta có thể mở rộng hình dạng thành một lớp vuông như hình dưới đây.
Square = Shape:new()
-- Derived class method new
function Square:new (o,side)
o = o or Shape:new(o,side)
setmetatable(o, self)
self.__index = self
return o
end
Các chức năng cơ sở vượt trội
Chúng ta có thể ghi đè các hàm của lớp cơ sở thay vì sử dụng hàm trong lớp cơ sở, lớp dẫn xuất có thể có triển khai riêng của nó như được hiển thị bên dưới:
-- Derived class method printArea
function Square:printArea ()
print("The area of square is ",self.area)
end
Ví dụ hoàn chỉnh về thừa kế
Chúng ta có thể mở rộng triển khai lớp đơn giản trong Lua như được hiển thị ở trên với sự trợ giúp của một phương thức mới khác với sự trợ giúp của các bảng đo lường. Tất cả các biến thành viên và hàm của lớp cơ sở được giữ lại trong lớp dẫn xuất.
-- Meta class
Shape = {area = 0}
-- Base class method new
function Shape:new (o,side)
o = o or {}
setmetatable(o, self)
self.__index = self
side = side or 0
self.area = side*side;
return o
end
-- Base class method printArea
function Shape:printArea ()
print("The area is ",self.area)
end
-- Creating an object
myshape = Shape:new(nil,10)
myshape:printArea()
Square = Shape:new()
-- Derived class method new
function Square:new (o,side)
o = o or Shape:new(o,side)
setmetatable(o, self)
self.__index = self
return o
end
-- Derived class method printArea
function Square:printArea ()
print("The area of square is ",self.area)
end
-- Creating an object
mysquare = Square:new(nil,10)
mysquare:printArea()
Rectangle = Shape:new()
-- Derived class method new
function Rectangle:new (o,length,breadth)
o = o or Shape:new(o)
setmetatable(o, self)
self.__index = self
self.area = length * breadth
return o
end
-- Derived class method printArea
function Rectangle:printArea ()
print("The area of Rectangle is ",self.area)
end
-- Creating an object
myrectangle = Rectangle:new(nil,10,20)
myrectangle:printArea()
Khi chúng tôi chạy chương trình trên, chúng tôi sẽ nhận được kết quả sau:
The area is 100
The area of square is 100
The area of Rectangle is 200
Trong ví dụ trên, chúng ta đã tạo hai lớp dẫn xuất - Hình chữ nhật và Hình vuông từ Square của lớp cơ sở. Có thể ghi đè các chức năng của lớp cơ sở trong lớp dẫn xuất. Trong ví dụ này, lớp dẫn xuất ghi đè hàm printArea.