-
Design Pattern
- Singleton Design Pattern
- Factory Design Pattern
- Factory Method Design Pattern
- Abstract Factory Design Pattern
- Builder Design Pattern
- Prototype Design Pattern
- Object Pool Design Pattern
- Chain of Responsibility Design Pattern
- Command Design Pattern
- Interpreter Design Pattern
- Iterator Design Pattern
- Mediator Design Pattern
- Memento Design Pattern
- Observer Design Pattern
- Observer Design Pattern - Xử Lý Exception
- Strategy Design Pattern
- Template Method Design Pattern
- Visitor Design Pattern
- Null Object Design Pattern
- Adapter Design Pattern
- Bridge Design Pattern
- Composite Design Pattern
- Decorator Design Pattern
- Flyweight Design Pattern
- Proxy Design Pattern
- S.O.L.I.D
- Clean code
- Lập trình socket
- Java Core
- Multi-Thread
- Spring
- Java Web
- Memory Caching
- Message Queue
- DevOps
- Xây dựng một nền tảng
- MongoDB
- MySQL timestamp
- Properties vs yaml
- Kotlin
- Lập Trình Machine Learning với PyTorch
- Mã Nguồn Mở
- Ezy HTTP
- Free Chat
- Một số kinh nghiệm với Git
- Review cho đồng nghiệp!
- Setup Dev Environment
- Hello World
- Create a Server Project
- Handle Client Requests
- Using ezyfox-server-csharp-client
- Using ezyfox-es6-client
- Client React.js Interaction
- Build And Deploy In Local

Mở rộng quá dễ dàng!
Chúng ta đều biết rằng một lớp được khai báo là final
thì không thể nào extends được đúng không? Ví dụ chúng ta muốn thừa kế lớp Integer
để có thêm hàm toBigInteger()
chúng ta sẽ làm thế này:
class IntegerEx extends Integer {
public BigInteger toBigInteger() {
return BigInteger.valueOf(this);
}
}
Nhưng rất tiếc chúng ta không thể, vì lớp Integer
là một lớp final
, với Java thì hiện tại là bó tay, nhưng với Kotlin, mọi việc lại siêu dễ dàng.
Cú pháp
Để tạo được các hàm mở rộng chúng ta cần tạo ra một file .kt
và viết hàm mở rộng vào file đó với cú pháp như sau:
fun <tên class cần mở rộng>.<hàm cần mở rộng>(
[các tham số]
): [kiểu dữ liệu trả về] =
<Nội dung hàm>
hoặc với cú pháp dành cho hàm phức tạp chúng ta có thể dùng cú pháp này:
fun <tên class cần mở rộng>.<hàm cần mở rộng>(
[các tham số]
): [kiểu dữ liệu trả về] {
<Nội dung hàm>
}
Và khi sử dụng chúng ta sẽ gọi như bình thường:
<đối tượng>.<tên hàm>([các tham số])
Hãy lưu ý các mục trong ngoặc vuông là các mục không bắt buộc phải có, chúng ta có thể bỏ qua khi viết code.
Áp dụng
Nào bây giờ chúng ta hãy quay trở lại với ví dụ thêm hàm toBigInteger
trên nhé, chúng ta có thể viết kiểu ngắn:
fun Integer.toBigInteger(): BigInteger =
BigInteger.valueOf(this.toLong())
hoặc kiểu dài:
fun Integer.toBigInteger(): BigInteger {
return BigInteger.valueOf(this.toLong())
}
Và sử dụng không khác gì với việc gọi hàm thông thường:
val intValue = Integer.valueOf(10)
val bigIntegerValue = value.toBigInteger()
Giả mã bí ẩn
Những người lần đều tiếp xúc với kiểu extension này đều thấy nó thực sự bí ẩn, trong đó có cả mình, :D, đó là khi mình tiếp xúc với CSharp, lúc đó mình cần viết hàm để format Date
sang String
và lúc đó quả thực mình đã say nắng CSharp luôn. Sau một hồi sử dụng thì mình bắt đầu cảm thấy tò mò và thử đào sâu xem có đúng với suy nghĩ của mình không, và quả thật nó không khác. Về bản chất thì kotlin hay CSharp khi biên dịch đều có một bước chuyển đổi, và các hàm extension sẽ được chuyển đổi thành các hàm static.
Quay trở lại ví dụ hàm toBigInteger
, khi bạn đặt hàm này trong file IntegerExtension.kt
thì khi biên dịch, kotlin sẽ tạo ra lớp IntegerExtensionKt thế này:
public class IntegerExtensionKt {
private IntegerExtensionKt() {}
public static BigInteger toBigInteger(Integer original) {
return BigInteger.valueOf(original);
}
}
Và khi sử dụng nó sẽ gọi hàm thế này:
Integer intValue = Integer.valueOf(10);
BigInteger bigIntegerValue =. IntegerExtensionKt.toBigInteger(value);
Thật đơn giản đúng không mọi người? Hoá ra đây cũng chỉ là một cách viết khác mà thôi, không có gì là magic cả.
Kết luận
Bạn còn nhớ nguyên tắc Open/Close (đóng với việc thay đổi, mở với việc mở rộng) chứ? Với sự xuất hiện của Kotlin đã giúp chúng ta giải được một bài toán vô cùng nan giải, đây là một điểm rất mạnh của Kotlin với các hàm extenstion. Nếu bạn đang dùng kotlin hãy tận dụng triệt để sức mạnh này nhé.
-
Design Pattern
- Singleton Design Pattern
- Factory Design Pattern
- Factory Method Design Pattern
- Abstract Factory Design Pattern
- Builder Design Pattern
- Prototype Design Pattern
- Object Pool Design Pattern
- Chain of Responsibility Design Pattern
- Command Design Pattern
- Interpreter Design Pattern
- Iterator Design Pattern
- Mediator Design Pattern
- Memento Design Pattern
- Observer Design Pattern
- Observer Design Pattern - Xử Lý Exception
- Strategy Design Pattern
- Template Method Design Pattern
- Visitor Design Pattern
- Null Object Design Pattern
- Adapter Design Pattern
- Bridge Design Pattern
- Composite Design Pattern
- Decorator Design Pattern
- Flyweight Design Pattern
- Proxy Design Pattern
- S.O.L.I.D
- Clean code
- Lập trình socket
- Java Core
- Multi-Thread
- Spring
- Java Web
- Memory Caching
- Message Queue
- DevOps
- Xây dựng một nền tảng
- MongoDB
- MySQL timestamp
- Properties vs yaml
- Kotlin
- Lập Trình Machine Learning với PyTorch
- Mã Nguồn Mở
- Ezy HTTP
- Free Chat
- Một số kinh nghiệm với Git
- Review cho đồng nghiệp!
- Setup Dev Environment
- Hello World
- Create a Server Project
- Handle Client Requests
- Using ezyfox-server-csharp-client
- Using ezyfox-es6-client
- Client React.js Interaction
- Build And Deploy In Local