Phân biệt Interface và Abstract trong lập trình c# và OOP

Thảo luận trong 'Lập trình phần mềm' bắt đầu bởi admin, 23/12/14.

  1. admin
    Tham gia ngày:
    22/5/13
    Bài viết:
    4,878
    Đã được thích:
    1,193
    Điểm thành tích:
    113
    Giới tính:
    Nam
    Để hiểu rõ được, bạn xem từng phần 1 về thế nào là Interface và Abstract sau đó sẽ rút ra được sự khác biệt của chúng là ở chỗ nào.

    1. Abstract class.

    1.1 Abstract class là gi?

    • Abstract class hay còn được gọi là lớp trừu tượng.
    • Abstract class được xem như một class cha cho tất cả các class con có cùng bản chất, và các lớp con(lớp dẫn xuất) sẽ chỉ kế thừa từ một lớp trừu trượng.
    • Lớp trừu tượng này không cho phép khởi tạo các tham số, chỉ được phép khai báo hay còn gọi là abstract không có cài đặt bên trong.
    • Trong các lớp Abstract không cho phép khơi tạo đối tượng(instance) của lớp ấy, có nghĩa không cho phép khởi tạo giá trị.
    1.2 Mục đích sử dụng Abstract class và quy tắc sử dụng.
    • Abstract được xem như một class không đây đủ, và khi ta sử dụng nó thì ta khai báo hoặc khai báo lại cho nó.
    • Abstract class như một lớp cha, mà khi các class con kế thừa sẽ phải phụ thuộc đầy đủ các phương thức đã được khai báo trong class cha abstract.
    • Các class kế thừa sẽ thực thi các phương thức giống nhau được khai báo từ class cha, ngoài ra ở các class kế thừa có thể khai báo thêm các phương thức khác mà class con đó muốn.
    • Một lớp adstract có một hoặc nhiều abstract method bên trong hoặc khai báo lại chính nó.
    • Các phương thức của lớp abstract class được thực thi và đem vào sử dụng thì ta khai báo thêm từ khóa override trước nó(Xem ví dụ dưới để rõ).
    VD1:

    Mã:
    
    public abstract class Hinh
    {
        public abstract float GetDienTich();//khai báo 1 abstract method
    }
    
    public class HinhTron:Hinh // lớp con HinhTron kế thừa từ lớp cha Hinh
    {
        private float fltBanKinh, fltPI;//có thể khai báo thêm biến trong các lớp con kế thừa
    
        public override float GetDienTich() // xử lý hàm từ lớp cha đã khai báo
        {
            return (fltPI * (fltBanKinh* 2));
        }
    }
    
    public class HinhChuNhat:Hinh
    {
        private float fltDai, fltRong;
    
        public override float GetDienTich(Hinh other)
        {
            return fltDai * fltRong;
        }
    }
    class Program
    {
       static void Main(string[] args)
       {
             HinhTron ojhinhtron=new HinhTron();
             ojhinhtron.fltBanKinh=30;
             ojhinhtron.fltPI=3.14;
             float fltdientich=ojhinhtron.GetDienTich();
             System.Console.WriteLine("Diện tích hình tròn là ': {0}",fltdientich);
             ......
             ......
        }
    }
    
    VD2:

    Mã:
    using System;
    using System.Collections.Generic;
    using System.Text;
    namespace Abstract_Class
    {
        abstract class ConNguoi //Định nghĩa 1 lớp trừu tượng
        {
            public string strHoTen;
            public bool blnGioiTinh;
            public int intTuoi;     
            public abstract void ViecLam(); //Khai báo 1 phương thức trừu tượng bằng từ khoá abstract
        }
        class NhanVien:ConNguoi //Định nghĩa lớp dẫn xuất hay gọi là kế thừa ConNguoi
        {
            public string strViTri;
            public override void ViecLam()
            {
                //Code về việc làm gõ ở đây tùy theo chức vụ của mỗi người.
            }
        }
        //Định nghĩa lớp Dẫn xuất KeToan
        class BaoVe:ConNguoi 
        {
            public string strViTri;
            public override void ViecLam()
            {
                //Code về việc làm gõ ở đây tùy theo chức vụ của mỗi người.
            }
        }
        class Program
        {
            static void Main(string[] args)//khao báo và chạy dữ liệu
            {
               // lớp nhân viên.
                NhanVien objNhanVien = new NhanVien();
                objNhanVien.strHoTen = "Phạm Huy Hùng";
                objNhanVien.intTuoi = 25;
                objNhanVien.blnGioiTinh = true;
                objNhanVien.strChucVu = "Nhân viên hành chánh";
                System.Console.WriteLine("Lớp Nhân Viên :{0},{1},{2},{3}",objNhanVien.strHoTen, objNhanVien.intTuoi, objNhanVien.blnGioiTinh, objNhanVien.strChucVu);
    
               //lớp người bảo vệ
                BaoVe objBaoVe = new BaoVe();
                objBaoVe.strHoTen = "Phạm Thế Hùng";
                objBaoVe.intTuoi = 23;
                objBaoVe.blnGioiTinh = true;
                objBaoVe.strChucVu = "Người bảo vệ trước cổng";
                 System.Console.WriteLine("Lớp Bảo Vệ  :{0},{1},{2},{3}",objBaoVe.strHoTen, objBaoVe.intTuoi, objBaoVe.blnGioiTinh, objBaoVe.strChucVu);
                System.Console.ReadLine();
            }
        }
    }
    
    

    2. Interface

    2.1. Interface là gì?

    • Interface hay còn gọi là lớp giao diện.
    • Lớp Interface được xem nư một mặt nạ cho các class cùng các thức hoạt động nhưng có thể cùng hoặc khác nhau về bản chất bên trong.
    • Các lớp dẫn xuất(lớp con) có thể kế thừa từ nhiều lớp interface khác nhau để bổ sung đầy đủ cách thức hoạt động cho nó. Hay còn được gọi là Multiple inheritance(đa kế thừa).
    2.2 Mục đích sử dụng Abstract class và quy tắc sử dụng.
    • Interface không thực thi bất kỳ phương thức nào.
    • Interface giống với abstract là không thể tạo mới một đối tượng.
    • Một interface có thể được thực thi duy nhất từ một class hoặc ở nhiều interface khác nhau.
    • Mặc định các phần từ trong interface sẽ được gán quyền public cho các khai báo bên trong.
    • Interface không bao gồm hằng, biến, số, destructer hay các thành phần static.
    • Khi khai báo một interface trong một class bạn phải chạy hay thực thi tất cả các thành phần trong interface đó.
    • Nếu một phần từ trong một interface khi khai báo không thực thi được thì chương trình sẽ báo lỗi.
    • Một class có thể kế thừa từ nhiều interface khác nhau nên bạn chỉ cần thêm dấu ',' giữa các interface.
    • Khác với abstract, một class khi thực thi nhiều interfae bắt buộc chúng phải thực hiện các phương thức được khai báo là abstract trong các interface đó và không phải khai báo từ khóa override giống lớp abstract.
    • Interface không phải là class(lớp). Các lớp dẫn xuất(kế thừa) từ 1 Interface đều phải định nghĩa đầy đủ các phương thức và thuộc tính kế thừa từ Interface.
    • Mục đích của một Interface là để định nghĩa những khả năng mà chúng ta muốn có trong một lớp.
    VD1: Một ví dụ khá hay của 1 bạn ở trên mạng mà mình đọc được như sau:
    • Giả sử ta có 2 lớp như sau : Lớp may bay và lớp Chim.
    • Cả 2 lớp này đều có khả năng là bay được trên trời.

    interface-khac-voi-abstract-class.jpg

    • Ta tạo interface cho 2 lớp này ở dạng 1 kế thừa như sau:
    Mã:
    using System;
    using System.Collections.Generic;
    using System.Text;
    namespace Interface
    {
        public interface itfBay //khai bao interface Bay
        {
            void KhaNangBay();
        }
        public class LopChim : itfBay  //Lớp Chim thừa kế interface IBay
        {
            public void KhaNangBay()
            {
                Console.WriteLine("Chim : Bay bằng 2 cánh");
            }
        }
        public class LopMayBay : itfBay  //Lớp LopMayBay thừa kế interface itfBay
        {
            public void KhaNangBay()
            {
                Console.WriteLine("Máy bay: Bay bằng động cơ");
            }
        }
        class Program
        {
            static void Main(string[] args)
            {
                LopChim objchim = new LopChim();
                objchim.KhaNangBay();
                LopMayBay objmaybay = new LopMayBay();
                objmaybay.KhaNangBay();
                System.Console.ReadLine();
            }
        }
    }
    

    • Ta tạo khai báo xử lý nhiều interface như sau:
    Mã:
    
    using System;
    using System.Collections.Generic;
    using System.Text;
    namespace Interface
    {
        public interface itfBay //khai báo interface cho việc bay
        {
            void KhaNangBay();
        }
        public interface itfChay //khai báo interface cho việc chạy
        {
            void KhaNangChay();
        }
        public class lopChim:itfBay,itfChay //Lớp LopChim được thừa kế 2 interfaces itfBay, itfChay
        {
            public void KhaNangBay()
            {
                Console.WriteLine("Chim bay: Bay bằng 2 cánh");
            }
            public void KhaNangChay()
            {
                Console.WriteLine("Chim chạy: Chạy bằng 2 chân");
            }
        }
        public class LopMayBay:itfBay,itfChay //Lớp lopMayBay thừa kế 2 interfaces itfBay, itfChay
        {
            public void KhaNangBay()
            {
                Console.WriteLine("Máy bay : Bay bằng động cơ");
            }
            public void KhaNangChay()
            {
                Console.WriteLine("Máy bay chạy : Chạy bằng 2 bánh");
            }
        }
        class Program
        {
            static void Main(string[] args)
            {
                lopChim objchim = new lopChim();
                objchim.KhaNangBay();
                objchim.KhaNangChay();
                LopMayBay objmaybay = new LopMayBay();
                objmaybay.KhaNangBay();
                objmaybay.KhaNangChay();
                System.Console.ReadLine();
            }
        }
    }
    
    

    3. So sánh giữa abstract lass và interface.

    3.1 Giống nhau.

    • abstract lass và interface đều không thể khởi tạo đối tượng bên trong được.
    • abstract lass và interface đều khai báo các phương thức nhưng không thực hiện chúng.
    • abstract lass và interface đều bao gồm các phương thức abstract.
    • abstract lass và interface đều được thực thi từ các class con hay còn gọi kế thừa, dẫn xuất.
    • Cabstract lass và interface đều có thể kế thừa từ nhiều interface.
    3.2 Khác nhau

    interface-khac-voi-abstract-class-1.png


    3.3 Sử dụng interface và abstract.

    VD1: sử dụng interface và abstract class

    Mã:
    public abstract class NhanVien// sử dụng Abstract class
    
        {
            public abstract String strMaNV //Khai báo Properties
            {
                get;
                set;
            }
            public abstract String Add(); //Khai báo Method
            public abstract String Update(); //Khai báo Method    
        }
    }
    public interface itfNhanVien // sử dụng Interface
        { 
            String strMaNV //Khai báo dữ liệu
            {
                get;
                set;
            }
            String Add(); //Khai báo Method
            String Update(); //Khai báo Method
        }
    }
    
    VD2: sử dụng interface và abstract class, trong ví dụ những Method và Properties trong Interface sẽ không cần phải khai báo Access modifier vì mặc định đã là Public. Abstract class thì phải bắt buộc khai báo là Public hay Protected ngoài ra bắt buộc có từ khóa abstract trong các Method và Properties được khai báo trừu tượng.

    Mã:
    public abstract class NhanVien //khai báo abstract class
        {
           
            public String strMaNV;  //Khai báo biến hằng (field and constant)
            public String strTenNV;  //Khai báo biến hằng (field and constant)
            public abstract String strMaNV //Khai báo Properties  trả về giá trị mã nhân viên
            {
                get;
                set;
            } 
            protected abstract String Add(); //Khai báo Method phải có abstract
            public String Update() //Method đã triển khai không dùng abstract ở trước khai báo.
            {
                return "Update Database";
            }
        }
    }
    public interface itfNhanVien //khai báo Interface cho nhân viên
        {
            String strMaNV //Khai báo Properties  trả về giá trị mã nhân viên
            {
                get;
                set;
            }
            String Add(); //Khai báo Method
            String Update(); //Khai báo Method
        }
    }
    
    VD3: thực hiện tiếp ở VD2. Các Interface của class kế thừa bắt buộc phải thực hiện toàn bộ những Method và Properties đã khai báo trong interface, ngược lại lớp dẫn xuất của Abstract class ta chir thực hiện những Method và Properties được khai báo trừu tượng(phải có từ khóa abstract).
    Mã:
    public class LopNhanVien:NhanVien 
    {
        //Không cần khai báo lại biến hằng.
        public override String strMaNV  //Triển khai Properties trả về giá mã NV với từ khóa override
        {
           get{ return strMaNV; }
           set{ strMaNV = value; }
        }
        protected override String Add() //Triển khai Method với access modifier như ở Abstract class.
        {
            return "Add";
        }
        //Không cần triển khai lại Update() mà chỉ việc sử dụng vì đã khai báo ở trên VD2
        // Phần triển khai của NhanVienPhong1 code thêm.
        //...
        //...
    }
    public class LopNhanVien:itfNhanVien // Lớp dẫn xuất Interface
    {
        // Biến hằng được định nghĩa ở đây.
        protected String strMaNV;
        protected String strName;
        String strMaNV // Properties trả về mã NV không cần từ khóa override
        {
           get{ return strMaNV; }
           set{ strMaNV = value; }
        }
        //Triển khai tất cả các Method có ở Interface
        public String Add()
        {
            return "Add";
        }
        public String Update()
        {
            return "Update";
        }
    
        // Phần triển khai thêm của LopNhanVien
        //...
        //...
    }
    

    • Với Sự phân biệt trên càng làm rõ ràng hơn với từ khóa implement cho Interface và extend cho Abstract class.
    • Lớp dẫn xuất của Abstract class chỉ là mở rộng(extend) còn Interface thì buộc là thực hiện (implement) tất cả trong giao thức.
    Bài viết được tổng hợp từ nhiều nguần, mong bài viết sẽ giúp ích nhiều bạn củng cố thêm kiến thức lập trình và các kiến thức khi xin việc hay hỏi.
     
    Cảm ơn đã xem bài:

    Phân biệt Interface và Abstract trong lập trình c# và OOP

    Last edited by a moderator: 12/1/16
  2. Đỗ Văn Toàn
    Tham gia ngày:
    11/9/15
    Bài viết:
    3
    Đã được thích:
    0
    Điểm thành tích:
    1
    Giới tính:
    Nam
    Bài viết của bạn rất hay
     
  3. duhoctoancau
    Tham gia ngày:
    25/1/18
    Bài viết:
    1
    Đã được thích:
    0
    Điểm thành tích:
    1
    Giới tính:
    Nam
    Up nội dung và làm mới
     
  4. Phạm Mai Liên
    Tham gia ngày:
    4/6/18
    Bài viết:
    8
    Đã được thích:
    0
    Điểm thành tích:
    1
    Giới tính:
    Nữ
    Bài viết của bạn rất hay
     
  5. tranthien0170
    Tham gia ngày:
    7/11/18
    Bài viết:
    20
    Đã được thích:
    0
    Điểm thành tích:
    1
    Giới tính:
    Nam
    cảm ơn đã chia sẽ bài viết hữu ích
     
  6. ngaydem1234
    Tham gia ngày:
    10/6/19
    Bài viết:
    7
    Đã được thích:
    0
    Điểm thành tích:
    1
    Giới tính:
    Nam
  7. Hoàng Phương An
    Tham gia ngày:
    12/6/19
    Bài viết:
    26
    Đã được thích:
    0
    Điểm thành tích:
    1
    Giới tính:
    Nữ
    hay quá, cảm ơn thớt đã chia sẻ
     
  8. Gạch Bông Gió Dana Tiles
    Tham gia ngày:
    11/9/19
    Bài viết:
    20
    Đã được thích:
    1
    Điểm thành tích:
    1
    Giới tính:
    Nam
    thông tin hữu ích cho nhiều người, cảm ơn đã chia sẻ
     
    mayxonghoidanang thích bài này.
  9. hochoiseo
    Tham gia ngày:
    26/9/19
    Bài viết:
    21
    Đã được thích:
    0
    Điểm thành tích:
    1
    Giới tính:
    Nữ
    Bài viết của bạn rất hay
     
  10. thientamthinh
    Tham gia ngày:
    11/6/19
    Bài viết:
    17
    Đã được thích:
    0
    Điểm thành tích:
    1
    Giới tính:
    Nam
    thông tin hữu ích cho nhiều người, cảm ơn đã chia sẻ
     
  11. noithatdungphat
    Tham gia ngày:
    27/9/19
    Bài viết:
    17
    Đã được thích:
    1
    Điểm thành tích:
    3
    Giới tính:
    Nam
    bài viết rất hay và bổ ích
     
  12. VO THI ANH
    Tham gia ngày:
    16/10/19
    Bài viết:
    20
    Đã được thích:
    0
    Điểm thành tích:
    1
    Giới tính:
    Nữ
    mấy này phức tạp thiệt. cảm ơn ad
     
  13. CUA CHONG MUOI VIET NHAT
    Tham gia ngày:
    26/10/19
    Bài viết:
    11
    Đã được thích:
    0
    Điểm thành tích:
    6
    Hay quá, cảm ơn ad nhiều
     
  14. Daniel Pham
    Tham gia ngày:
    1/1/20
    Bài viết:
    18
    Đã được thích:
    0
    Điểm thành tích:
    1
    Giới tính:
    Nam
    Bai viet rat bo ich, cam on tac gia
     
  15. htnhatrang
    Tham gia ngày:
    13/12/19
    Bài viết:
    68
    Đã được thích:
    0
    Điểm thành tích:
    8
    Giới tính:
    Nam
    Bài viết rất hay cảm ơn bạn nhé
     
  16. mayxonghoidanang
    Tham gia ngày:
    22/6/20
    Bài viết:
    7
    Đã được thích:
    0
    Điểm thành tích:
    1
    Giới tính:
    Nam
    cảm ơn thông tin chia sẻ của ad, học hỏi được nhiều điều thanks
     
  17. Nguyễn Tấn Long
    Tham gia ngày:
    30/1/16
    Bài viết:
    6
    Đã được thích:
    0
    Điểm thành tích:
    1
    Giới tính:
    Nam
    hay quá ad ơi! trong group có bác nào rành về python ko nhỉ
     
  18. cuatudongychi
    Tham gia ngày:
    5/5/21
    Bài viết:
    4
    Đã được thích:
    0
    Điểm thành tích:
    1
    Giới tính:
    Nam
    Hữu ích quá, tks bác