You are on page 1of 48

OOP

iOS Training – Phần lý thuyết


Mục lục
• Class và object
• Structure
• Enumeration
• Properties
• Methods
• Inheritance
• Initializers
• Extensions
• Access Controls
Class và Object
• Class là một tập hợp các đối tượng có cùng thuộc tính và phương thức
• Class định nghĩa ra các thuộc tính và các phương thức mà đối tượng sở hữu
• Object (đối tượng) là thể hiện (instance) của class

Bản vẽ Thực thể


Class và Object
• Cú pháp khai báo class:
class <ClassName>{
// class’s definition
}

• Cú pháp khởi tạo một instance:


var <instanceName> = <ClassName>()
Class và Object
• Ví dụ:

• Khai báo class Point có 2 thuộc


tính x và y
• Cấp giá trị mặc định cho x và y

• Khởi tạo đối tượng point là thể


hiện của class Point
• Truy cập và thay đổi giá trị của
x và y
Class và Object

Hiện thực Lập trình


• Tập hợp các đối tượng có cùng chung • Một lớp bao gồm các thuộc tính và
một hoặc 1 vài tính chất thì tạo thành tính chất. Các đối tượng là các thể
1 lớp hiện của các lớp
• Từ những thuộc tính và hành vi của • Các đối tượng cùng một lớp thì có
đối tượng mà mô tả nên các tính chất những thuộc tính và phương thức
của và đặc tính của một lớp giống nhau
• Lớp • Lớp
• Là 1 tập hợp • Là 1 khuôn mẫu
• Không đồng nhất về tất cả • Đồng nhất về tất cả
• Đối tượng là một thực thể xác định • Đối tượng là thể hiện của lớp
Structure
• Cú pháp khai báo structure:
struct <StructureName>{
// structure’s definition
}
• Cú pháp khởi tạo một instance:
var <instanceName> = <StructureName>()
• Tất cả structure đều tự động khởi tạo memberwise initializer, dùng để khởi tạo
tất cả giá trị ban đầu của structure.

Auto-generated memberwise initializer


đang được gọi
So sánh class và structure – Giống nhau
• Khai báo properties để chứa giá trị
• Khai báo methods để xử lý các chức năng
• Khai báo subscripts để truy cập vào giá trị thông qua cú pháp subscript
• Khai báo initializers để cài đặt trạng thái ban đầu
• Tương thích với protocol
So sánh class và structure – Khác nhau

Class Structure
• Có thể kế thừa từ class khác • Không có tính chất kế thừa
• Có thể ép kiểu (type casting) để kiểm • Không thể ép kiểu
tra và chuyển đổi kiểu của instance tại • Kiểu tham trị
runtime
•…
• Kiểu tham chiếu
•…
• Giá trị của kiểu dữ liệu tham trị được
• Giá trị của kiểu dữ liệu tham chiếu được copy khi nó được gán cho một biến /
tham chiếu tới cùng một instance khi nó hằng số, hoặc khi nó được truyền qua
được gán cho một biến / hằng số, hoặc một function
khi nó được truyền qua một function
Enumeration
• Khai báo một nhóm các giá trị liên quan với nhau, nhằm tạo sự tường minh trong
lập trình cũng như tính toán và xử lý.
• Là kiểu tham trị, không có tính thừa kế.
• Cú pháp:
• Khai báo enumeration bằng từ khoá enum
• Mỗi case trong enumeration được khai báo bằng từ khoá case

Có thể gộp các enum case trên một dòng

Cách sử dụng đầy đủ <EnumName>.<enumCaseName>

Cách sử dụng rút gọn .<enumCaseName>


Enumeration
• Enum cũng có các property và method tương tự như ở class và structure
• Sử dụng enum với switch:

Enumeration có
method và properties…
// Kết quả: “Hearts” cách sử dụng tương tự
như ở class và structure
Enumeration
• Enumeration case có thể chứa giá trị liên kết (associtated values) => Chứa thêm
thông tin của enum case.
• Những giá trị này có thể thuộc bất kỳ kiểu dữ liệu nào, và khác nhau trong mỗi
enum case nếu cần thiết.
Enumeration
• Raw value là giá trị mặc định được đưa ra của enumeration case, có cùng kiểu dữ
liệu với enumeration.
• Đối với kiểu string hoặc integer, Swift tự động gán giá trị raw value cho enum case
nếu case đó không được gán giá trị mặc định.

// Kết quả “Spades” // Kết quả “spades” // Kết quả 1


Nếu bỏ “= 1” thì kết quả 0

• Khởi tạo từ raw value -> optional


Tóm tắt phần trên
• Ở phía trên đã tìm hiểu 3 cấu trúc dữ liệu:
• Class
• Structure
• Enumeration
• Phía dưới đây sẽ tìm hiểu cấu trúc bên trong của chúng:
• Properties:
• Phân loại quan hệ đối với kiểu cấu trúc dữ liệu:
• Instance property
• Type property
• Phân loại đối với cách sử dụng:
• Stored property
• Computed property
• Methods
Properties
• Thuộc tính liên kết các giá trị với cấu trúc dữ liệu: class, structure và enumeration, và được mô
tả bên trong các cấu trúc dữ liệu đó.
• Phân loại:
• Instance properties: Các propeties làm việc cùng với instance, bao gồm
• Stored properties
• Computed properties
• Type properties: Các properties làm việc cùng với kiểu dữ liệu, bao gồm:
• Stored type properties
• Computed type properties
• Trong đó:
• Stored properties: chứa các giá trị hằng / biến
• Computed properties: tính toán ra các giá trị
• Instance của class và structure có stored properties và computed properties, trong khi đó
enumeration chỉ có computed properties.
• Ngoài ra, có thể khai báo property observers để theo dõi sự thay đổi giá trị của một property.
Stored properties
• Là biến / hằng được chứa trong instance của một class hoặc structure.
• Khai báo bằng: let cho hằng hoặc var cho biến.
• Có thể cung cấp giá trị khởi tạo khi khai báo.
• Có thể thiết lập hoặc sửa đổi giá trị của chúng trong hàm khởi tạo.
• Chú ý:
• Đối với structure, khi khai báo instance là một hằng, không thể thay đổi giá trị của các
properties bên trong, dù cho các properties đó là biến.

Stored properties
change 'let' to 'var' to make it mutable

Q: Điều này có đúng với khi


Rectange là một class hay không?
Stored properties with lazy keyword
• Là thuộc tính mà giá trị của nó sẽ được khởi tạo vào lần đầu tiên sử dụng
• Từ khoá: lazy
lazy var <varianceName>
• Chú ý:
• Các lazy stored properties bắt buộc phải khai báo là biến
• Hữu ích đối với những thuộc tính gây tốn tài nguyên, khi nào cần sử dụng thì giá trị của nó
mới được khởi tạo
• Việc sử dụng với nhiều luồng truy cập không đảm bảo việc khởi tạo giá trị đầu tiên cho nó là
duy nhất
Stored properties with lazy keyword
• Ví dụ:

Giá trị của importer vẫn chưa được khởi tạo


Giá trị của importer đã được khởi tạo
Computed properties
• Là thuộc tính không chứa giá trị.
• Thay vào đó nó cung cấp hàm getter và optional setter dùng để nhận
giá trị và thiết lập giá trị cho các properties khác một cách gián tiếp.
• Bắt buộc có hàm getter
• Hàm setter có thể có hoặc không
• Nếu không có hàm setter -> read-only computed property

Hàm getter
Sử dụng từ khoá get

Hàm setter
Sử dụng từ khoá set

Nếu hàm setter không khai báo tên parameter


thì tên default là newValue
Read-only computed properties
• Khi computed property chỉ có hàm getter thì được hiểu là một read-only
computed property.
• Không thể gán giá trị cho những properties này.
• Ví dụ:

Lược bỏ cú pháp get{}


Type properties
• Từ khoá:
• static
• class (cho phép các lớp con có thể override)
• Các properties này được truy cập thông qua tên kiểu dữ liệu
• Tùy thuộc vào khai báo let hoặc var mà giá trị của chúng có thể thay đổi được
hay không
Property observers
• Là các hàm được bổ sung vào trong property, nhằm theo dõi và phản hồi sự thay
đổi giá trị của chúng.
• Được gọi bất kỳ khi nào giá trị của thuộc tính bị thay đổi, bao gồm việc thay đổi
giá trị mới giống như giá trị hiện tại của nó.
• Bao gồm:
• willSet: được gọi trước khi các giá trị mới được lưu trữ vào thuộc tính
• didSet: được gọi khi hoàn tất việc thay đổi giá trị của thuộc tính
Property observers
• Ví dụ:

Nếu hàm willSet không khai báo tên parameter


thì tên default là newValue
Global and local variables
• Giống nhau:
• Có khả năng chứa giá trị như stored properties
• Có khả năng tính toán như computed properties
• Có khả năng theo dõi và phản hồi sự thay đổi giá trị như observer properties
• Khác nhau:

Global variables Local variables


• Khai báo bên ngoài của bất cứ một function, • Khai báo bên trong function, method, hoặc
method, closure, hoặc kiểu dữ liệu. closure.
Methods
• Method là function có liên quan đến một kiểu dữ liệu nhất định nào đó. (Class,
structure, enumeration)
• Phân loại:
• Instance method: bao đóng những công việc và chức năng dùng để làm việc với một instance
của một kiểu dữ liệu nhất định.
• Type method: bao đóng những công việc và chức năng dùng để làm việc trực tiếp tới kiểu dữ
liệu của chính nó.

Instance method Type method

Gọi thông qua instance của kiểu dữ liệu. Gọi thông qua kiểu dữ liệu.
Instance method
• Thuộc tính self: Mọi instance của một kiểu dữ liệu đều sở hữu thuộc tính được
đặt tên là seft, mà giá trị của nó tương đương với chính instance đó.
• Sử dụng thuộc tính self trong instance method mục đích để trỏ tới chính
instance hiện tại đang làm việc.
• Nhằm tạo ra sự tường mình khi các biến local của các hàm trùng với tên của các
property.
• Ví dụ:
Instance method
• Thuộc tính của kiểu tham trị (như structure hoặc enumeration) mặc định không
được thay đổi từ bên trong của instance method
• Muốn thay đổi thì instance method đó phải được khai báo bằng từ khoá
mutating
• Ví dụ:
Type method
• Khai báo bằng từ khoá static hoặc class trước từ khoá func.
• static func: Không cho phép các lớp con override lại func
• class func: Cho phép lớp con override lại func
• Ví dụ:

• Trong Objective-C, chỉ có class có thể khai báo type method.


• Với Swift, class, struct và enum đều có thể khai báo type method.
Tóm tắt phần tiếp theo
• Ôn một số tính chất của OOP như:
• Abstract
• Encapsulate
• Inheritance
• Polymorphism
• Thông qua:
• Initializers
• Extension
• Access control
Inheritance
• Thông qua việc kế thừa, một class có thể sử dụng các
properties, methods, subscripts của 1 class khác và có thể
override lại chúng.
• Cú pháp:
<SubclassName>: <SuperclassName>
• Trong đó:
• Superclass: Class cha được kế thừa
• Subclass: Class con kế thừa properties, methods, subcripts của
class cha
• Kế thừa trong swift là đơn kế thừa.
• Ví dụ:
Base class
• Là class không kế thừa từ bất kỳ class nào
• Các class của swift mà kế thừa từ NSObject
• Tương tự như các class của Objective-C
• Để gọi các method sử dụng: objc_msgSend()
• Các metadata sẽ được cung cấp lúc runtime
• Các class của swift mà không kế thừ từ NSObject
• Là các class của Objective-C, chỉ implement một số ít các phương thức để tương thích
• Không sử dụng objc_msgSend()
• không đc cung cấp các metadata lúc runtime
• Để cải thiện hiệu suất trong swift thì khuyến cáo không nên kế thừa từ NSObject
Overriding
• Subclass kế thừa những tính chất từ superclass, bên cạnh đó subclass có thể thay
đổi những tính chất đó hoặc thêm những tính chất mới.
• Subclass có thể custom những instance method, type method, instance property,
type property hay subscript mà nó thừa kế từ superclass thành của riêng nó. Việc
này được xem là overriding.
• Overriding được tuỳ chỉnh sao cho phù hợp với ý đồ sử dụng trong subclass.
• Sử dụng từ khoá:
• override phía trước tính chất cần overriding. Ví dụ:
override func someMethod() { … }
• super để trỏ tới tính chất của lớp cha. Ví dụ:
super.someMethod()
super.someProperty
Overriding
• Ví dụ:

Inheritance

Polymorphism
Prevent overriding
• Để tránh việc lớp con override các tính chất của lớp cha, sử dụng từ khoá final
• Ví dụ:
final var someVariance = 0
final func someFunction() { … }
• Sử dụng từ khoá final trước khai báo class => Class không thể được thừa kế
• Ví dụ:

Error: Inheritance from a


final class 'SomeClass'
Initialization
• Là quá trình chuẩn bị sử dụng một instance của một class, structure hoặc
enumeration.
• Quá trình này bao gồm:
• Cài đặt những giá trị ban đầu cho mỗi một thuộc tính của instance
• Thực hiện những setup hay những initialization khác mà cần thiết phải làm trước khi instance
được sử dụng.
• Quá trình này được khai báo bởi initializer, là một method đặc biệt, dùng để khởi
tạo một instance mới của một kiểu dữ liệu nhất định.
• Không có giá trị trả về như ở Objective-C
Initialization
• Tương tự như function trong swift, initializer cũng có argument label và parameter name. Ví dụ:
init(argumentLabel parameterName: Int) {
// Initialization’s body
}

• Class và structure phải set tất cả các giá trị mặc định thích hợp cho các thuộc tính trước khi
instance của class hay structure được khởi tạo.

• Đối với những thuộc tính có kiểu optional, có thể không khởi tạo giá trị cho nó.

• Đối với những class hoặc structure mà đã cung cấp giá trị ban đầu cho tất cả các thuộc tính và
không có hàm khởi tạo, Swift sẽ cung cấp hàm init() mặc định cho những class và structure trên.

• Đặc biệt ở structure có auto-generated memberwise initializer.


Initialization
• Ví dụ:
class 'Person' has no initializers

stored property 'name' without initial value prevents


synthesized initializers

• Xuất hiện lỗi vì:


• Thuộc tính name không có giá trị mặc định lúc khai báo
• Không có hàm khởi tạo để set giá trị mặc định cho thuộc tính name
Initialization
• Ví dụ: Cách xử lý

• Với các thuộc tính optional, không cần thiết phải


gán giá trị mặc định cho nó.

• Hàm khởi tạo với từ khoá init set giá trị mặc định
thích hợp cho các thuộc tính.
• Vì class Person là lớp cơ sở, cho nên không xuất
hiện từ khoá super trong hàm khởi tạo.
Initialization
• Ví dụ:

• Class “User” với các thuộc tính:


• First name
• Last name
• Bio
• Khi khởi tạo đối tượng bắt buộc phải có first name và last name cho đối tượng (đứng về mặt
ý nghĩa của class)
Initialization
• Ví dụ: Set giá trị mặc định
cho tham số bio
là “I ♡ Swift”

Khi gọi hàm, có thể lượt bỏ bớt


các tham số có giá trị ngầm định

• Ngoài ra
• Có thể viết nhiều hàm khởi tạo của một class khác nhau về tham số truyền vào
Class Inheritance and Initialization
• Trong class có hai loại initializer:
• Designated initializers: • Convenience initializers:
• Hàm khởi tạo cơ sở của class. • Hàm khởi tạo phụ trợ của class.
• Khởi tạo đầy đủ các thuộc tính của • Gọi hàm designated initializer trong
class. cùng class.
• Gọi hàm khởi tạo thích hợp của lớp • Thường được dùng để khởi tạo
cha để tiếp tục chuỗi khởi tạo instance đối với một use case phổ
• Mỗi class có ít nhất một designated biến hoặc với giá trị đầu vào đặc
initializer biệt…
• Không bắt buộc phải có convenience
initializer trong class
Class Inheritance and Initialization

Designated initializer phải Designated initializer phải gọi


đảm bảo tất cả properties designated initializer của class
phải được set giá trị trước cha gần nhất với nó
khi instance được khởi tạo Convenience initializer phụ trợ cho designated
initializer
Convenience initializer phải gọi initializer của
cùng một class và phải gọi designated initializer
Initialization
• Tại sao trời sinh class có designated init và convenience init?
• Structure hay enumeration không có tính kế thừa => việc khởi tạo khá đơn giản
• Sử dụng hàm init do chúng tự cung cấp
• Nếu có thì chỉ cần gọi hàm init lồng trong hàm init
• Class có tính kế thừa => việc khởi tạo phức tạp hơn, trước khi instance được khởi tạo:
• Các thuộc tính của lớp con đều có giá trị => Designated init phải đảm bảo
• Các thuộc tính của lớp cha đều có giá trị => Gọi designated init của lớp cha gần nhất
• Phụ trợ lớp cha cho việc khởi tạo những pattern phổ biến => Sử dụng convenience init
Extension
• Thêm các chức năng mới cho một class, structure, enumeration hoặc protocol.
• Tương tự như Category trong Objective-C
• Extension có thể:
• Thêm các properties và methods
• Khai báo initializers, subscripts mới
• Làm cho kiểu dữ liệu phù hợp với protocol
• Cú pháp:
extension SomeType {
// new functionality to add to SomeType goes here
}
extension SomeType: SomeProtocol, AnotherProtocol {
// implementation of protocol requirements goes here
}
Extensions
• Hữu ích khi:
• Nhóm các function hay implement các function của các protocol cần đường định nghĩa lại
trong file class
• Thêm các function khi muốn can thiệp các class của hệ thống
• Ví dụ:
Access control
• 5 cấp độ truy cập trong swift
• open
• Có thể truy cập từ bên ngoài, cho sử dụng ngoài module hay project
• Có thể kế thừa và sử dụng lại toàn bộ các thuộc tính cũng như phương thức
• public
• Tương tự như open nhưng việc kế thừa và override lại bị giới hạn
• Chỉ có các thành viên cùng module thì mới có thể kế thừa
• Internal
• Cho phép sử dụng bất kì các file source code....trong cùng module
• Đây là mực truy cập mặc định
• fileprivate
• Chỉ cho phép sử dụng bên trong file source code
• Có thể sử dụng từ các extension
• private
• Hạn chế tất cả các quyền truy cập
Access control
• Final
• Ngăn chặn việc override các phương thức cũng như kế thừa class
• Có thể truy cập các phương thức và thuộc tính với khai báo (public và open). Tuy nhiên
không thể kế thừa lại chúng
• Khuyến cáo nên sử dụng để tăng tốc độ biên dịch của swift

• Tham khảo:
• https://useyourloaf.com/blog/swift-3-access-controls/
Tài liệu tham khảo
• The Swift Programming Language (Swift 4)

You might also like