1. Trang chủ
  2. » Công Nghệ Thông Tin

Giáo trình Lập trình thiết bị di động 1 (Nghề Quản trị mạng Trình độ Cao đẳng)

58 2 0

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 58
Dung lượng 1,3 MB

Nội dung

QTM-CĐ-MĐ20-LTTBDD1 TUYÊN BỐ BẢN QUYỀN Tài liệu thuộc loại sách giáo trình nên nguồn thơng tin phép dùng nguyên trích dùng cho mục đích đào tạo tham khảo Mọi mục đích khác mang tính lệch lạc sử dụng với mục đích kinh doanh thiếu lành mạnh bị nghiêm cấm LỜI GIỚI THIỆU Yêu cầu có tài liệu tham khảo cho sinh viên khoa Công nghệ Thông tin Trường Cao đẳng Nghề ngày trở nên cấp thiết Việc biên soạn tài liệu nằm kế hoạch xây dựng hệ thống giáo trình mơn học Khoa Đề cương giáo trình thông qua Hội đồng Khoa học Khoa Trường Mục tiêu giáo trình nhằm cung cấp cho sinh viên tài liệu tham khảo mơn học Mạng máy tính, giới thiệu khái niệm hệ thống mạng máy tính, đồng thời trang bị kiến thức số kỹ chủ yếu cho việc bảo trì quản trị hệ thống mạng Đây coi kiến thức ban đầu tảng cho kỹ thuật viên, quản trị viên hệ thống mạng Mặc dù có cố gắng để hồn thành giáo trình theo kế hoạch, hạn chế thời gian kinh nghiệm soạn thảo giáo trình, nên tài liệu chắn khiếm khuyết Rất mong nhận đóng góp ý kiến thầy Khoa bạn sinh viên sử dụng tài liệu Các góp ý xin gửi Khoa Công nghệ thông tin - Trường Cao đẳng nghề Cần Thơ Xin chân thành cảm ơn Cần Thơ, ngày tháng năm 2021 Tham gia biên soạn Chủ biên Nguyễn Phát Minh MỤC LỤC TRANG LỜI GIỚI THIỆU MỤC LỤC TRANG GIÁO TRÌNH MƠN HỌC/MƠ ĐUN Tên mơn học/mơ đun: Lập trình thiết bị di động Mã môn học/mô đun: MĐ 20 BÀI 1: GIỚI THIỆU NGÔN NGỮ KOTLIN Mã chương: MĐ 20 - 01 Giới thiệu: Mơi trường lập trình Kotlin Ứng dụng 10 BÀI 2: BIẾN, KIỂU DỮ LIỆU VÀ NHẬP XUẤT VỚI KOTLIN 18 Mã chương: MĐ 20 - 02 18 Các kiểu liệu Kotlin 18 Khai báo biến ép kiểu 19 var tên_biến : Kiểu_Dữ_Liệu=Giá_Trị_Mặc_Định 19 Nhập liệu từ bàn phím 21 Xuất liệu 21 BÀI 3: LỆNH CÓ CẤU TRÚC 23 Mã chương: MĐ 20 - 03 23 Lệnh điều khiển If - Else 23 Lệnh điều khiển When 27 Lệnh vòng lặp 29 Lệnh xử lý ngoại lệ 33 BÀI 4: MẢNG, CHUỖI VÀ COLLECTION 35 Mã chương: MĐ 20 - 04 35 Mảng 35 Chuỗi 36 Collection 38 BÀI 5: HÀM 41 Mã chương: MĐ 20 - 05 41 Giá trị Kotlin 41 Hàm Kotlin 41 BÀI 6: LẬP TRÌNH HƯỚNG ĐỐI TƯỢNG 43 Mã chương: MĐ 20 - 06 43 Tạo lớp với Kotlin 43 Lớp & kế thừa 52 Singletons, enums, and sealed 55 TÀI LIỆU THAM KHẢO 58 GIÁO TRÌNH MƠN HỌC/MƠ ĐUN Tên mơn học/mơ đun: Lập trình thiết bị di động Mã mơn học/mơ đun: MĐ 20 Vị trí, tính chất, ý nghĩa vai trị mơn học/mơ đun:  Vị trí: Mơn học bố trí sau sinh viên học xong môn học chung, môn học sở chuyên ngành đào tạo chun mơn nghề  Tính chất: Là mơn học sở chuyên ngành bắt buộc  Ý nghĩa vai trị mơn học/mơ đun: Lập trình thiết bị di động môn học để sinh viên tìm hiểu ngơn ngữ lập trình Kotlin để làm tảng học Lập trình thiết bị di động sau Mục tiêu môn học/mô đun:  Về kiến thức: o Trình bày kiểu liệu Kotlin o Trình bày lệnh có cấu trúc Kotlin o Trình bày khai báo sử dụng mảng, chuỗi, collection o Trình bày khai báo sử dụng hàm Kotlin  Về kỹ năng: o Viết chương trình dùng Kotlin o Viết chương trình có dùng hàm Kotlin o Viết chương trình có sử dụng lớp với Kotlin  Về lực tự chủ trách nhiệm: o Nghiêm túc, tỉ mỉ trình tiếp cận với cơng cụ  Bố trí làm việc khoa học đảm bảo an toàn cho người phương tiện học tập.: Nội dung môn học/mô đun: Thời gian Số TT Tên chương, mục I Giới thiệu ngôn ngữ Kotlin Tổng số Lý thuyết Thực Kiểm tra* hành Bài (LT tập hoặcTH) 2 Biến, kiểu liệu nhập xuất với Kotlin 4 Giới thiệu Mơi trường lập trình Kotlin Ứng dụng II Các kiểu liệu Kotlin Khai báo biến ép kiểu Nhập liệu từ bàn phím Xuất liệu III Lệnh có cấu trúc 10 10 45 15 28 Lệnh điều khiển If - Else Lệnh điều khiển When Lệnh vòng lặp Lệnh xử lý ngoại lệ IV Mảng, chuỗi collection Mảng Chuỗi Collection V Hàm Giá trị Kotlin Hàm Kotlin VI Lập trình hướng đối tượng Tạo lớp với Kotlin Lớp & kế thừa Singletons, enums, and sealed Cộng BÀI 1: GIỚI THIỆU NGÔN NGỮ KOTLIN Mã chương: MĐ 20 - 01 Giới thiệu: Trong chương trình bày nội dung q trình lịch sử hình thành mạng máy tính khái niệm mạng máy tính Mục tiêu bài:  Trình bày khái niệm ngơn ngữ Kotlin  Cài đặt mơi trường lập trình Kotlin  Viết ứng dụng Kotlin  Thực thao tác an toàn với máy tính Nội dung chính: Giới thiệu: Kotlin ngơn ngữ lập trình Google lựa chọn làm ngơn ngữ thức cho phát triển ứng dụng Android Kotlin có nhiều ưu điểm Kotlin sử dụng 100% thư viện từ JVM, dễ dàng từ Kotlin triệu gọi Java từ Java triệu gọi Kotlin Giúp Lập trình viên khơng lo lắng việc chuyển đổi coding, tăng khả tương tác mạnh mẽ hệ thống Ngồi Kotlin cịn dễ dàng lập trình nhiều cơng cụ khác nhau: Website, Eclipse, Netbeans, Android Studio, JetBrains… Tài liệu lập trình phong phú, cộng đồng hỗ trợ Kotlin ngày khơng ngừng phát triển Mơi trường lập trình Kotlin Để lập trình Kotlin bạn sử dụng Website để thử nghiệm online https://try.kotlinlang.org/ Cũng cài đặt phần mềm IntelliJ IDEA, Eclipse Neon, Command Line Compiler, Build Tools (Ant, Maven, Gradle, Griffon (external support)) Tải Community IntelliJ IDEA link sau: http://www.jetbrains.com/idea/download/index.html Sau tiến hành cài đặt chương trình bình thường Sau cài đặt thành cơng, ta có giao diện thông báo Bấm Finish để hoàn tất việc cài đặt, muốn hoàn tất khởi động ln phần mềm checked vào “Run IntelliJ IDEA Commynity Edition”, ta quan sát ngồi hình Desktop có shortcut để chạy phần mềm Nếu lần đầu chạy phần mềm bạn gặp cửa sổ sau Chọn Do not import settings bấm OK, hình u cầu thiết lập Theme cho cơng cụ xuất hiện: Chọn được, tùy sở thích Dưới hình sau cấu hình xong IntelliJ IDEA, lần sau khởi động tương tự Ứng dụng Sau bấm Create New Project, New Project xuất hiện: 10 Tên lớp ta nên đặt theo quy tắc: Ký Tự Đầu Tiên Từ phải Viết Hoa, không chứa khoảng trắng… Kotlin hỗ trợ loại Constructors (những hàm đặc biệt, mặc định để khởi tạo giá trị ban đầu cho đối tượng cấp phát nhớ) primary constructor secondary constructors Khai báo primary constructor Kotlin: class SinhVien constructor(ma:Int,ten:String){ } Ở constructor từ khóa, bên có đối số, có nghĩa Lớp SinhVien có Primary construtor có đối số Nếu primary construtor khơng có chứa thích (annotations) modifiers(private, protected,public) loại bỏ từ khóa constructor khỏi khai báo, tức ta Khai báo ngắn gọi sau: class SinhVien (ma:Int,ten:String){ } Một lưu ý quan trọng primary constructor chứa đoạn mã nào, muốn khởi tạo giá trị mặc định cho biến dùng primary constructor ta phải dùng khối lệnh init{} , ví dụ: class SinhVien (ma:Int,ten:String){ init { println("Đây primary constructor") println("Mã=$ma ; Tên =$ten") } } Khi khai báo biến để sử dụng lớp SinhVien ta làm sau: fun main(args: Array) { var lanh=SinhVien(113,"Trần Thị Long Lanh") } Chạy chương trình, ta kết sau: 44 Đây primary constructor Mã=113 ; Tên =Trần Thị Long Lanh Khi khai báo var lanh=SinhVien(113,”Trần Thị Long Lanh”) tự động tìm tới primary constructor tự nhảy vào init block để thực Và ý khơng cần dùng từ khóa new để xin cấp phát nhớ C# hay java… Khai báo secondary constructor Kotlin: Ta dùng từ khóa constructor để khai báo secondary constructor kotlin, ví dụ: class SinhVien { constructor() { println("Đây secondary constructor đối số") } constructor(ma:Int,ten:String) { println("Đây secondary constructor đối số") println("Mã=$ma ; Tên =$ten") } } Khai báo sử dụng secondary constructor: fun main(args: Array) { var teo=SinhVien() var lanh=SinhVien(113,"Trần Thị Long Lanh") } Khi chạy phần mềm ta có thông báo sau: Đây secondary constructor đối số Đây secondary constructor đối số Mã=113 ; Tên =Trần Thị Long Lanh Khai báo thuộc tính Lớp Kotlin: 45 Thuộc tính thuộc đối tượng, ví dụ Sinh Viên có thơng tin: mã, tên, năm sinh… thơng tin thuộc tính đối tượng Sinh Viên Kotlin giống ngôn ngữ khác, cung cấp số Visibily Modifiers (private, protected, public, default) cho thuộc tính: Modifiers Lớp (Class) Gói (Package) Lớp (Subclass) Ngồi public Có Có Có Có protected Có Có Có Khơng Khơng có (no modifier – default) Có Có có Khơng private Có Khơng Khơng Khơng Ví dụ: class SinhVien { var ma:Int=0 var ten:String="" constructor() { println("Đây secondary constructor đối số") } constructor(ma:Int,ten:String) { println("Đây secondary constructor đối số") println("Mã=$ma ; Tên =$ten") } } Theo khai báo thuộc tính ma ten để default Modifier(khơng định rõ loại nào), package đối tượng truy suất tới thuộc tính này: 1fun main(args: Array) { 2var teo=SinhVien() 3teo.ma=114 4teo.ten="Nguyễn Thị Tèo" 5println("Thông tin Tèo:") 6println("Mã ="+teo.ma) 7println("Tên="+teo.ten) 46 8} Để đám bảo tính đóng gói thuộc tính nên khai báo private, thuộc tính khai báo private Lúc đối tượng truy suất trực tiếp vào thuộc tính mà phải thơng qua getter/setter: 1class SinhVien { 2private var ma:Int=0 3private var ten:String="" 4} Khi khai báo Modifier private ta khơng thể lấy tên đối tượng truy suất thuộc tính được, tức khai báo bị báo lỗi: 1fun main(args: Array) { 2var teo=SinhVien() 3teo.ma=114 4teo.ten="Nguyễn Thị Tèo" 5} Khai báo getter/setter Lớp Kotlin: Nếu thuộc tính lớp mà để default truy suất package thuộc tính để modifier public ta khơng cần khai báo getter/setter Cách khai báo getter/setter Kotlin có khác biệt so với Java, C# ngôn ngữ khác Cú pháp tổng quát để khai báo getter/setter: var [: ] [= ] [] [] Ví dụ: 1class SinhVien { 2private var ma:Int=0 3private var ten:String="" 4public var Ma:Int 5get() 6{ 7return ma 8} 9set(value) 10{ 11ma=value 47 12} 13public var Ten:String 14get() 15{ 16return ten 17} 18set(value) 19{ 20ten=value 21} 22constructor() 23{ 24println("Đây secondary constructor đối số") 25} 26constructor(ma:Int,ten:String) 27{ 28println("Đây secondary constructor đối số") 29println("Mã=$ma ; Tên =$ten") 30} 31} Theo cách viết ta có Getter/Setter Ma Ten Các đối tượng ngồi khơng truy suất vào thuộc tính ma ten mà truy suất thơng qua Getter/Setter Ma Ten (chú ý IN HOA- in thường) Các từ khóa get, set phần mềm IntelliJ IDEA gợi ý sẵn cho ta, cần gõ ký tự đầu gợi ý sau ta nhấn Enter tự xuất Với set bạn để ý có value parameter mặc định, parameter nhận giá trị input từ ngồi vào (là thay đổi thơng tin cho thuộc tính đối tượng) Ví dụ triệu gọi lớp SinhVien: 1fun main(args: Array) { 2var hanh=SinhVien() 3hanh.Ma=113 4hanh.Ten="Hồ Thị Hạnh" 5println("Thông tin Hạnh:") 6println("Mã:"+hanh.Ma) 7println("Tên:"+hanh.Ten) 8} Kết chạy đoạn lệnh trên: Đây secondary constructor đối số Thông tin Hạnh: 48 Mã:113 Tên:Hồ Thị Hạnh Có nhiều trường hợp để hiệu chỉnh cách viết get set trên, gặp trường hợp cụ thể bạn tìm hiểu thêm, Tui khơng có trình bày hết Khai báo Phương thức Lớp Kotlin: Phương thức hay gọi hành vi, xử lý nghiệp vụ đối tượng Đây tập hợp sức mạnh đối tượng Kotlin dùng từ khóa fun để khai báo phương thức Các phương thức có giá trị trả khơng Ví dụ bổ sung phương thức (trả giá trị String không trả giá trị cả): /** * 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 secondary constructor đối số") } constructor(ma:Int,ten:String) 49 { println("Đây secondary constructor đố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 } } xuatThongTin() phương thức không trả giá trị (cịn gọi thủ tục) thực nội bên Lớp chiTiet() phương thức trả giá trị, ngồi truy suất lưu lại kết hàm để sử dụng cho mục đích khác (rất thường xuyên sử dụng trường hợp này) Ví dụ minh hoạt cách thức sử dụng hàm trên: /** * 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 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) } Kết chạy ta thấy: 50 Đây secondary constructor đối số Thông tin 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 giống C# Java, hỗ trợ phương thức đặc biệt toString() dùng để tự động xuất thông tin đối tượng xuất hình/giao diện Để tạo phương thức đơn giản, lớp ta cần gõ từ khóa to phần mềm tự hiển thị hàm tostring cho ta: Nó tự động hàm sau: override fun toString(): String { return super.toString() } Ta muốn xuất thông tin return thơng tin này, ví dụ: 51 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 } Trong main, cần xuất đối tượng tự động triệu gọi hàm toString(), lợi hại Đối tượng chứa nhiều thơng tin mối quan hệ, cịn toString() giúp ta xuất vài thông tin cần thiết, giúp ta ẩn dấu nhiều thơng tin khác mà đảm bảo tính chất đối tượng: /** * 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) } Kết chạy ta thấy: Đây secondary constructor đố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 Lớp & kế thừa Kế thừa bạn hiểu nơm na Sự TÁI SỬ DỤNG lại mã nguồn cũ, mở rộng thêm mã lệnh từ thứ tồn tại, giúp nâng cao hiệu suất lập trình Thường đối tượng có chung số đặc điểm, hành vi nhóm lại với Ví dụ:    Xe đạp Xe máy Xe 52  Xe tải xe có số đặc điểm giống ko? Ta thường thấy mơ hình Lớp kế thừa người ta vẽ giống đây: Hay Một lớp lớp cha lớp khác: 53 Để làm tốt Kế Thừa ta cần biết khái niệm: Tổng quát hoá: Những đặc điểm chung mà lớp có==>là lớp Cha Chuyên biệt hóa: Những đặc điểm riêng có lớp có ==>là lớp Con Ví dụ: Cơng ty có loại nhân viên (Nhân Viên Chính Thức Nhân Viên Thời Vụ): Thì rõ ràng Nhân viên khơng kể Chính thức hay thời vụ người có mã, tên Nhưng Nhân viên thức nhân viên thời vụ khác cách tính lương Do Lớp Tổng qt Hốt lớp Nhân Viên có đặc điểm chung Chính Thức Thời Vụ, Cịn lớp chun biệt hóa là: Nhân VIên CHính Thức, Nhân VIên Thời Vụ: Cài đặt Kế thừa Kotlin nào? Ta viết ví dụ Nhân Viên theo hình Trong Kotlin, để viết Lớp cho phép kế thừa ta làm sau: Lớp Tổng quát hóa (lớp cha) Nhân Viên: open abstract class NhanVien { protected var ma:Int=0 protected var ten:String="" public abstract fun tinhLuong(ngayCong:Int):Double } Lớp cha NhanVien lớp trừu tượng, có phương thức trừu tượng tinhLuong Vấn đề biết nên khai báo phương thức trừu tượng? Ta hiểu nôm na sau: Mọi nhân viên điều tính lương, thời điểm khơng biết tính lương cho nhân viên nào, mà khơng biết tính cụ thể cho khai báo trừu tượng (tuy tinhLuong cho đối tượng chắn phả có tinhLuong) Với abstract hay interface hàm trừu tượng giống luật, mẫu đưa yêu cầu lớp kế thừa phải tuân thủ theo (override lại toàn bộ) Một điều cần lưu ý Nếu muốn lớp khác kế thừa từ lớp bắt buộc ta phải thêm từ khóa open đằng trước khai báo lớp mẫu code 54 Bây ta tạo lớp NhanVienChinhThuc kế thừa từ lớp NhanVien sau: Bạn thấy ta dùng dấu chấm (:) để kế thừa nhé, nhìn vào hình ta biết cách viết NhanVienChinhThuc kế thừa từ NhanVien phải viết Singletons, enums, and sealed Singleton object GoldColor : FishColor { override val color = "gold" } Bởi thể GoldColor làm điều tương tự, khai báo dạng object thay dạng a classđể làm cho trở thành singleton Chỉ có trường hợp Enum Kotlin hỗ trợ enums, cho phép bạn liệt kê gọi tên, giống ngôn ngữ khác Khai báo enum cách đặt tiền tố khai báo với từ khóa enum Một khai báo enum cần danh sách tên, bạn xác định nhiều trường liên kết với tên enum class Color(val rgb: Int) { RED(0xFF0000), GREEN(0x00FF00), BLUE(0x0000FF); } Enums giống tập nhỏ — có giá trị giá trị kiểu liệt kê Ví dụ, có Color.RED, Color.GREENvà Color.BLUE Trong ví dụ này, giá trị RGB gán cho thuộc rgbtính để đại diện cho thành phần màu Bạn lấy giá trị thứ tự enum cách sử dụng thuộc ordinaltính tên cách sử dụng thuộc nametính 55 Hãy thử ví dụ khác enum enum class Direction(val degrees: Int) { NORTH(0), SOUTH(180), EAST(90), WEST(270) } fun main() { println(Direction.EAST.name) println(Direction.EAST.ordinal) println(Direction.EAST.degrees) } ⇒ EAST 90 Sealed Lớp niêm phong lớp phân lớp, bên tệp mà khai báo Nếu bạn cố gắng phân lớp lớp tệp khác, bạn gặp lỗi Vì lớp lớp nằm tệp, Kotlin biết tất lớp cách tĩnh Có nghĩa là, thời điểm biên dịch, trình biên dịch nhìn thấy tất lớp lớp biết tất chúng, trình biên dịch kiểm tra thêm cho bạn Trong AquariumFish.kt , thử ví dụ lớp kín, phù hợp với chủ đề thủy sinh sealed class Seal class SeaLion : Seal() class Walrus : Seal() fun matchSeal(seal: Seal): String { return when(seal) { is Walrus -> "walrus" is SeaLion -> "sea lion" } } Các Seallớp học subclassed tập tin khác Nếu bạn muốn thêm nhiều Sealloại, bạn phải thêm chúng tệp Điều làm cho lớp niêm phong trở thành cách an toàn để đại diện cho số kiểu cố định Ví dụ: lớp niêm phong tốt để trả thành công lỗi từ API mạng Bài tập: Viết chương trình tạo lớp sinh viên có thơng tin họ tên, giới tính, ngày sinh, địa 56 Bài tập nâng cao: Sử dụng lớp sinh viên phía trên, Viết chương trình tạo mảng có sinh viên Nhập thơng tin cho sinh viên đó, in hình thơng tin sinh viên Những trọng tâm cần ý bài:  Trình bày cách khai báo lớp Kotlin  Trình bày khái niệm lớp kế thừa  Viết ứng dụng có sử dụng lớp Yêu cầu đánh giá kết học tập: Nội dung: + Về kiến thức: Trình bày cách khai báo lớp Kotlin + Về kỹ năng: Viết ứng dụng có sử dụng lớp + Năng lực tự chủ trách nhiệm: Tỉ mỉ, cẩn thận, xác, ngăn nắp công việc Phương pháp: + Về kiến thức: Được đánh giá hình thức kiểm tra viết, trắc nghiệm, vấn đáp + Về kỹ năng:Viết ứng dụng có sử dụng lớp + Năng lực tự chủ trách nhiệm: Tỉ mỉ, cẩn thận, xác, ngăn nắp công việc 57 TÀI LIỆU THAM KHẢO [1] Website https://developer.android.com/courses/kotlin-bootcamp/overview 58

Ngày đăng: 17/12/2023, 10:18

TÀI LIỆU CÙNG NGƯỜI DÙNG

TÀI LIỆU LIÊN QUAN