Bài 23-Lập trình hướng đối tượng trong Kotlin – phần 2

[polldaddy poll=9764234]

Trong bài 22 Tui đã điểm qua một số đặc điểm của OOP cùng với một ví dụ về tạo Lớp và sử dụng Lớp trong Kotlin. Trong bài này Tui sẽ đi vào giải thích chi tiết từng thành phần trong quá trình tạo Lớp.

Cấu trúc của một class thường có:

  • Tên Lớp
  • Các constructors
  • Các thuộc tính
  • Các getter/setter
  • Các phương thức

1) Khai báo Tên Lớp trong Kotlin:

Với Kotlin, để tạo một lớp ta dùng từ khóa class giống như các ngôn ngữ lập trình khác:

class SinhVien {
}

Không giống với các ngôn ngữ khác, Kotlin cho phép khai báo chỉ mỗi Tên Lớp mà không cần có bất kỳ thành phần nào khác, cách khai báo này như sau:

class SinhVien

Tên lớp ta nên đặt theo quy tắc: Ký Tự Đầu Tiên của các Từ phải Viết Hoa, không chứa khoảng trắng…

Kotlin hỗ trợ 2 loại Constructors (những hàm đặc biệt, mặc định để khởi tạo các giá trị ban đầu cho các đối tượng khi cấp phát bộ nhớ) đó là primary constructor  secondary constructors

2)Khai báo primary constructor trong Kotlin:

class SinhVien constructor(ma:Int,ten:String){
}

Ở trên constructor là từ khóa, bên trong nó có 2 đối số, có nghĩa là Lớp SinhVien này có 1 Primary construtor có 2 đối số.

Nếu như primary construtor không có chứa các chú thích (annotations) và các modifiers(private, protected,public) thì có thể loại bỏ từ khóa constructor khỏi khai báo, tức là ta có thể Khai báo ngắn gọi như sau:

class SinhVien (ma:Int,ten:String){
}

Một lưu ý quan trọng là primary constructor không thể chứa bất kỳ đoạn mã nào, nếu muốn khởi tạo các giá trị mặc định cho các biến khi dùng primary constructor thì ta phải dùng khối lệnh init{} , ví dụ:

[code language=”groovy”]
class SinhVien (ma:Int,ten:String){
init {
println(“Đây là primary constructor”)
println(“Mã=$ma ; Tên =$ten”)
}
}
[/code]

Khi khai báo biến để sử dụng lớp SinhVien ở trên ta sẽ làm như sau:

[code language=”groovy”]
fun main(args: Array) {
var lanh=SinhVien(113,”Trần Thị Long Lanh”)
}
[/code]

Chạy chương trình, ta được kết quả như sau:

Đây là primary constructor
Mã=113 ; Tên =Trần Thị Long Lanh

Khi khai báo var lanh=SinhVien(113,”Trần Thị Long Lanh”) nó sẽ tự động tìm tới primary constructor và tự nhảy vào init block để thực hiện.

Và chú ý là không cần dùng từ khóa new để xin cấp phát bộ nhớ như C# hay java…

3)Khai báo secondary constructor trong Kotlin:

Ta cũng dùng từ khóa constructor để khai báo secondary constructor trong kotlin, ví dụ:

[code language=”groovy”]

class SinhVien {
constructor()
{
println(“Đây là secondary constructor 0 đối số”)
}
constructor(ma:Int,ten:String)
{
println(“Đây là secondary constructor 2 đối số”)
println(“Mã=$ma ; Tên =$ten”)
}
}

[/code]

Khai báo sử dụng các secondary constructor:

[code language=”groovy”]

fun main(args: Array) {
var teo=SinhVien()
var lanh=SinhVien(113,”Trần Thị Long Lanh”)
}

[/code]

Khi chạy phần mềm ta có các thông báo sau:

Đây là secondary constructor 0 đối số
Đây là secondary constructor 2 đối số
Mã=113 ; Tên =Trần Thị Long Lanh

4) Khai báo các thuộc tính của Lớp trong Kotlin:

Thuộc tính là những gì thuộc về đối tượng, ví dụ như 1 Sinh Viên có các thông tin: mã, tên, năm sinh… thì các thông tin này là các thuộc tính của đối tượng Sinh Viên

Kotlin giống như các ngôn ngữ khác, cung cấp một số các Visibily Modifiers (private, protected, public, default) cho các thuộc tính:

 Modifiers Lớp (Class) Gói (Package) Lớp con (Subclass) Ngoài
public
protected Không
Không có (no modifier – default) Không
private Không Không Không

Ví dụ:

[code language=”groovy”]

class SinhVien {
var ma:Int=0
var ten:String=””
constructor()
{
println(“Đây là secondary constructor 0 đối số”)
}
constructor(ma:Int,ten:String)
{
println(“Đây là secondary constructor 2 đối số”)
println(“Mã=$ma ; Tên =$ten”)
}
}

[/code]

Theo khai báo ở trên thì 2 thuộc tính ma và ten để là default Modifier(không chỉ định rõ loại nào), thì trong cùng một package các đối tượng có thể truy suất tới các thuộc tính này:

[code language=”groovy”]

fun main(args: Array) {
var teo=SinhVien()
teo.ma=114
teo.ten=”Nguyễn Thị Tèo”
println(“Thông tin của Tèo:”)
println(“Mã =”+teo.ma)
println(“Tên=”+teo.ten)
}

[/code]

Để đám bảo tính đóng gói thì các thuộc tính nên khai báo private, khi thuộc tính khai báo là private. Lúc này các đối tượng không thể truy suất trực tiếp vào các thuộc tính được mà phải thông qua getter/setter:

[code language=”groovy”]

class SinhVien {
private var ma:Int=0
private var ten:String=””
}

[/code]

Khi khai báo Modifier là private thì ta không thể lấy tên đối tượng  truy suất các thuộc tính được, tức là khai báo như dưới đây sẽ bị báo lỗi:

[code language=”groovy”]

fun main(args: Array) {
var teo=SinhVien()
teo.ma=114
teo.ten=”Nguyễn Thị Tèo”
}

[/code]

5) Khai báo các getter/setter của Lớp trong Kotlin:

Nếu các thuộc tính trong lớp mà để default và truy suất trong cùng package hoặc các thuộc tính để modifier là public thì ta không cần khai báo getter/setter.

Cách khai báo getter/setter trong Kotlin có khác biệt so với Java, C# và các ngôn ngữ khác.

Cú pháp tổng quát để khai báo getter/setter:

var <propertyName>[: <PropertyType>] [= <property_initializer>]
[<getter>]
[<setter>]

Ví dụ:

[code language=”groovy”]

class SinhVien {
private var ma:Int=0
private var ten:String=””
public var Ma:Int
get()
{
return ma
}
set(value)
{
ma=value
}
public var Ten:String
get()
{
return ten
}
set(value)
{
ten=value
}
constructor()
{
println(“Đây là secondary constructor 0 đối số”)
}
constructor(ma:Int,ten:String)
{
println(“Đây là secondary constructor 2 đối số”)
println(“Mã=$ma ; Tên =$ten”)
}
}

[/code]

Theo cách viết ở trên ta có 2 Getter/Setter Ma và Ten. Các đối tượng ở ngoài sẽ không truy suất được vào 2 thuộc tính maten mà chỉ được truy suất thông qua 2 Getter/Setter MaTen (chú ý IN HOA- in thường)

Các từ khóa get, set ở trên thì phần mềm IntelliJ IDEA cũng gợi ý sẵn cho ta, chỉ cần gõ ký tự đầu là nó gợi ý rồi sau đó ta nhấn Enter tự nó xuất hiện. Với set bạn để ý có value là parameter mặc định, đó là parameter nhận giá trị input từ ngoài vào (là thay đổi thông tin cho thuộc tính của đối tượng).

Ví dụ triệu gọi lớp SinhVien:

[code language=”groovy”]

fun main(args: Array) {
var hanh=SinhVien()
hanh.Ma=113
hanh.Ten=”Hồ Thị Hạnh”
println(“Thông tin của Hạnh:”)
println(“Mã:”+hanh.Ma)
println(“Tên:”+hanh.Ten)
}

[/code]

Kết quả khi chạy các đoạn lệnh ở trên:

Đây là secondary constructor 0 đối số
Thông tin của Hạnh:
Mã:113
Tên:Hồ Thị Hạnh

Có rất nhiều trường hợp để hiệu chỉnh cách viết get và set ở trên, khi nào gặp trường hợp cụ thể thì các bạn tìm hiểu thêm, Tui không có trình bày ra hết ở đây được.

6) Khai báo các Phương thức của Lớp trong Kotlin:

Phương thức hay còn gọi là hành vi, các xử lý nghiệp vụ trên đối tượng. Đây là tập hợp các sức mạnh của đối tượng. Kotlin dùng từ khóa fun để khai báo các phương thức. Các phương thức này có thể có giá trị trả về hoặc không.

Ví dụ dưới đây bổ sung 2 phương thức (trả về giá trị String và không trả về giá trị nào cả):

[code language=”groovy”]

/**
* Created by cafe on 01/06/2017.
*/
class SinhVien {
private var ma:Int=0
private var ten:String=””
public var Ma:Int
get()
{
return ma
}
set(value)
{
ma=value
}
public var Ten:String
get()
{
return ten
}
set(value)
{
ten=value
}
constructor()
{
println(“Đây là secondary constructor 0 đối số”)
}
constructor(ma:Int,ten:String)
{
println(“Đây là secondary constructor 2 đối số”)
println(“Mã=$ma ; Tên =$ten”)
}
fun xuatThongTin()
{
println(“Thông tin chi tiết:”)
println(“Mã = “+ma)
println(“Tên= “+ten)
}
fun chiTiet():String
{
var s=”Thông Tin Chi Tiết:”
s=s.plus(“\nMã=”+ma)
s=s.plus(“\n”)
s=s.plus(“Tên=”+ten)
return s
}
}

[/code]

xuatThongTin() là phương thức không trả về giá trị (còn gọi là các thủ tục) nó thực hiện nội tại bên trong Lớp. chiTiet() là phương thức trả về giá trị, ở ngoài khi truy suất có thể lưu lại kết quả của hàm này để sử dụng cho các mục đích khác (rất thường xuyên sử dụng trường hợp này).

Ví dụ dưới đây minh hoạt cách thức sử dụng 2 hàm trên:

[code language=”groovy”]

/**
* Created by cafe on 01/06/2017.
*/
fun main(args: Array) {
var hanh=SinhVien()
hanh.Ma=113
hanh.Ten=”Hồ Thị Hạnh”
println(“Thông tin của Hạnh:”)
println(“Mã:”+hanh.Ma)
println(“Tên:”+hanh.Ten)

println(“——–Gọi phương thức xuatThongTin()———“)
hanh.xuatThongTin()
println(“——–Gọi phương thức chiTiet()———“)
var detail=hanh.chiTiet()
println(detail)
}

[/code]

Kết quả khi chạy ta thấy:

Đây là secondary constructor 0 đối số
Thông tin của Hạnh:
Mã:113
Tên:Hồ Thị Hạnh
——–Gọi phương thức xuatThongTin()———
Thông tin chi tiết:
Mã = 113
Tên= Hồ Thị Hạnh
——–Gọi phương thức chiTiet()———
Thông Tin Chi Tiết:
Mã=113
Tên=Hồ Thị Hạnh

Kotlin cũng giống như C# và Java, nó hỗ trợ một phương thức đặc biệt đó là toString() dùng để tự động xuất thông tin khi đối tượng được xuất ra màn hình/giao diện. Để tạo phương thức này rất đơn giản, trong lớp ta chỉ cần gõ từ khóa to thì phần mềm tự hiển thị hàm tostring cho ta:

Nó sẽ tự động ra hàm sau:

override fun toString(): String {
    return super.toString()
}

Ta muốn xuất thông tin gì thì cứ return đúng thông tin đó trong này, ví dụ:

[code language=”groovy”]

override fun toString(): String {
var s=”Thông Tin Chi Tiết:”
s=s.plus(“\nMã=”+ma)
s=s.plus(“\n”)
s=s.plus(“Tên=”+ten)
return s
}

[/code]

Trong main, chỉ cần xuất đối tượng là nó tự động triệu gọi hàm toString(), rất lợi hại. Đối tượng chứa rất nhiều thông tin và các mối quan hệ, còn toString() chỉ là giúp ta xuất một vài thông tin cần thiết, nó giúp ta ẩn dấu được nhiều thông tin khác mà vẫn đảm bảo được tính chất của đối tượng:

[code language=”groovy”]

/**
* Created by cafe on 01/06/2017.
*/
fun main(args: Array) {
var hanh = SinhVien()
hanh.Ma = 113
hanh.Ten = “Hồ Thị Hạnh”
println(“Xuất thông tin đối tượng->tự gọi toString()”)

println(hanh)
}

[/code]

Kết quả khi chạy ta thấy:

Đây là secondary constructor 0 đối số
Xuất thông tin đối tượng->tự gọi toString()
Thông Tin Chi Tiết:
Mã=113
Tên=Hồ Thị Hạnh

Như vậy tới đây Tui đã trình bày xong cách thức tạo cấu trúc của 1 Lớp trong Kotlin, bao gồm các quy tắc tạo:

  • Tên Lớp
  • Các constructors
  • Các thuộc tính
  • Các getter/setter
  • Các phương thức

Các bạn chú ý học kỹ, thực hành lại và có gắng hiểu được nó thông qua các ví dụ ở trên nhé. Các bài sau Tui sẽ tiếp tục trình bày về OOP trong Kotlin (các loại phương thức, overloading method, tham chiếu this), các bạn chú ý theo dõi

Các bạn có thể tải source code bài này ở đây: http://www.mediafire.com/file/eqs3538mpwoplm2/HocOOPPhan2.rar

Hẹn gặp các bạn ở những bài tiếp theo

Chúc các bạn thành công!

Trần Duy Thanh (http://communityuni.com/)

4 thoughts on “Bài 23-Lập trình hướng đối tượng trong Kotlin – phần 2”

  1. dùng set/get này luôn mà không dùng phương thức thủ công thì get set sẽ có chung phạm vi truy cập với biến đúng không thầy? ví du Private name thì set cũng private. Còn nếu viết thêm function setName như java sẽ cho phép đặt setter getter là public chẳng hạn

Leave a Reply