Hotline: 0909.141.661

Email: plpsoft.vn@gmail.com

Hotline: 0909.141.661 | Email: plpsoft.vn@gmail.com

Interface Trong C# - Lập trình OOP

Interface Trong C#

Interface Trong C#

Interface là 1 khái niệm thường được thấy trong các ngôn ngữ cấp cao như C#, Java, ... interface mang đến những ràng buộc về hành động cho các đối tượng, vừa mang lại kiến trúc tốt hơn cho hệ thống, tránh sơ sót và dễ dàng bảo trì.

Interface trong C# là gì?

Interface gần như là một lớp (class), nhưng chỉ định nghĩa các hành động, khả năng cần thiết như:

  • Khả năng bay: cần các hành động hỗ trợ như cất cánh, bay, hạ cánh.
  • Khả năng kết nối: cần mở kết nối, gửi nhận dữ liệu, xác nhận kết nối, đóng kết nối.
  • Khả năng đọc file: đọc header file, đọc dữ liệu, giải nén file.

Đặc điểm của 1 interface

Interface có các thành viên là methods, properties, indexers, events và không chứa fields.

interface IShape { 
  // methods 
  void Draw(); 
  // properties 
  double Side { get; set; } 
  // indexers 
  double this[int index] { get; set; }
  // event
  event EventHandler SideChanged;
  // field
  double m_side; // lỗi: error CS0525: Interfaces cannot contain fields
}

Interface có thể implement nhiều interface cơ sở (base interface), một class hoặc struct có thể implement nhiều interface.

interface IPath

{

  void setSize();

}
 

interface IColor

{

  void setBorderColor();

  void setFillColor();

}
 

interface IPoint

{

  void setPoint();

}

// interface có thể implement nhiều interface

interface IShape : IColor, IPath

{

  void Draw();

  double Side { get; set; }

}

 

// class hoặc struct có thể implement nhiều interface

class CSquare : IShape, IPoint

{

  private double m_side;

  public void setSize() { }

  public void setPoint() { }

  public void setBorderColor() { }

  public void setFillColor() { }

  public void Draw() { }

  public double Side {

    get { return m_side; }

    set { m_side = value; }

  }

}

Bất kỳ class hay struct nào implement một interface thì implement tất cả các thành viên và định nghĩa đầy đủ các thành viên của interface đó.

interface IColor

{

  void setBorderColor();

  void setFillColor();

}

 

class CRectangle : IColor

{

  public void setBorderColor(){ }

  // lỗi: error CS0535: 'CRectangle' does not implement interface member 'IColor.setFillColor()'

  // thiếu phương thức: setFillColor()

}

Các thành viên của interface không được phép định nghĩa (definition) mà chỉ được khai báo (declaration).

interface IShape

{

  double Side { get; set; }

  void Draw()

  {

    Console.WriteLine("drawing drawing.");

  }

  // lỗi:  error CS0531: 'IShape.Draw()': interface members cannot have a definition

}

Interface không có constructors.

interface IPath

{

  void setSize();

  public IPath()

  {

    Console.WriteLine("Size of path.");

  }

  // lỗi: error CS0526: Interfaces cannot contain constructors

}

Nếu một lớp implement từ nhiều interface có cùng tên thành viên thì trong lớp phải chỉ rõ thành viên đó thuộc interface nào (explicit interface).

interface IPath

{

  void setSize();

}

 

interface IBorder

{

  void setSize();

}

 

class CCircle : IPath, IBorder

{

  private int m_size;

 

  // Bỏ modifier public

  // nếu có sẽ gây lỗi: error CS0106: The modifier 'public' is not valid for this item

  // có lỗi vì khi ta sử dụng kiểu định nghĩa đầy đủ <kiểu-trả-về><tên-interface>.<phương-thức> thì compiler sẽ không cần khai báo từ khóa public

 

  // explicit interface  - tường minh

  void IPath.setSize()

  {

    m_size = 3;
    Console.WriteLine("path: {0}", m_size);

  }

 

  // explicit interface

  void IBorder.setSize()

  {

    m_size = 5;

    Console.WriteLine("border: {0}", m_size);

  }

}

// Chương trình chính

class Program

{

  static void Main(string[] args)

  {

    // Khai báo một thể hiện của lớp CCricle

    CCircle circle = new CCircle();

 

    // Khai báo một thể hiện của interface IPath

    IPath path = (IPath)circle;

 

    // Khai báo một thể hiện của interface IBorder

    IBorder border = (IBorder)circle;

 

    // circle.setSize();

   

    // đoạn code trên gây ra lỗi vì không thể truy cập thành viên explicit interface từ một thể hiện của lớp.

 

    // phương thức được gọi thành công từ một thể hiện interface.

    path.setSize();

    border.setSize();

 

    Console.ReadKey();

  }

}

Output:

path: 3
border: 5

Implement và inherits trong C#

Implement một interface

class derivedClass : IBaseInterface

Inherits một class

class derivedClass : public CBaseClass

Cú pháp định nghĩa interface trong C# 

Khai báo sử dụng từ khóa interface. Interface có modifier là public hoặc internal, nếu không ghi rõ mặc định là internal. 

[modifier] interface <interface-name> [: interface-base] {

  // interface member

}

Ví dụ: định nghĩa một interface thể hiện đối tượng cảnh trong game engine.

interface IScence

{

  string Title { get; set; }

  void process();

}

 

class CMainScence : IScence

{

  private string m_title;

  public CMainScence()

  {

    m_title = ":: Game Tank :: menu";

  }

 

  public string Title

  {

    get { return m_title; }

    set { m_title = value; }

  }

 

  public void process()

  {

    Console.WriteLine("process game");

  }

}

 

class Program

{

  static void Main(string[] args)

  {

    CMainScence mainScence = new CMainScence();

    mainScence.process();

    Console.WriteLine("{0}", mainScence.Title);

  }

}

Output:

Process game
:: Game Tank :: menu

Sử dụng interface trong C#

Thể hiện tính đa kế thừa, tính đa hình

Trong kỹ thuật lập trình hướng đối tượng với C++ có thể thực hiện kế thừa nhiều lớp (multiple-inheritance), có thể hiện thực:

class derivedClass : public baseClassA, public baseClassB, public baseClassC {

  // Code something

}

Nếu sử dụng C# không có điều tương tự, đa kế thừa không được hỗ trợ, trong 1 chừng mực nhất định có thể implement nhiều interfaces.

interface IShape

{

    double Area();

    double Height

    {

        get;

        set;

    }

    double Width

    {

        get;

        set;

    }

}

 

interface IShapeDisplay

{

    void Display();

}

 

// Lớp CSquare implement 2 interface IShape và IShapeDisplay

public class CSquare : IShape, IShapeDisplay

{

    private double m_size;

    public double Height

    {

        get

        {

            return m_size;

        }

        set

        {

            m_size = value;

        }

    }

    public double Width

    {

        get

        {

            return m_size;

        }

        set

        {

            m_size = value;

        }

    }

    public double Area()

    {

        return m_size * m_size;

    }

    public void Display()

    {

        Console.WriteLine("SQUARE-Size: {0}", this.m_size);

        Console.WriteLine("SQUARE-Area: {0}", this.Area());

    }

    public CSquare()

    {

        m_size = 7;

    }

}

 

// lớp CRectangle implement 2 interface IShape và IShapeDisplay

public class CRectangle : IShape, IShapeDisplay

{

    private double m_width;

    private double m_height;

    public double Height

    {

        get

        {

            return m_height;

        }

        set

        {

            m_height = value;

        }

    }

    public double Width

    {

        get

        {

            return m_width;

        }

        set

        {

            m_width = value;

        }

    }

    public double Area()

    {

        return m_width * m_height;

    }

    public void Display()

    {

        Console.WriteLine("REC-Width: {0}", this.m_width);

        Console.WriteLine("REC-Height: {0}", this.m_height);

        Console.WriteLine("REC-Area: {0}", this.Area());

    }

    public CRectangle()

    {

        m_width = 7;

        m_height = 3;

    }

}

 

class Program

{

    static void Main(string[] args)

    {

        CRectangle rec = new CRectangle();

        rec.Height = 8;

        rec.Display();

 

        // polymorphism

        Console.WriteLine("-- polymorphism --");

        IShapeDisplay[] shapeDisplay = { new CRectangle(), new CSquare() };

 

        for (int i = 0; i < 2; i++)

        {

            shapeDisplay[i].Display();

        }

    }

}

Output:

REC-Width: 7
REC-Height: 8
REC-Area: 56
-- polymorphism --
REC-Width: 7
REC-Height: 3
REC-Area: 21
SQUARE-Size: 7
SQUARE-Area: 49

Sử dụng interface có thể gọi phương thức giống nhau từ các lớp khác nhau, các lớp đó phải cùng implement một interface (polymorphism).

Quy định kiến trúc

Khi một lớp implement một interface phải định nghĩa đầy đủ các phương thức của interface đó, thế interface như định nghĩa ra các ràng buộc chặt chẽ khi cần thể hiện 1 khả năng của class.

Ví dụ: Xây dựng chương trình mã hóa các tập tin png, mp3; chương trình bao gồm nhiều công đoạn: mở tập tin, xử lý mã hóa, nén tập tin, lưu tập tin, để đảm bảo khi thực hiện việc mã hóa tập tin sẽ luôn có các công đọng trên thì các lớp mã hóa từng loại tập tin cần implement 1 interface được định nghĩa chuyên làm việc đó.

interface IReadFile

{

    bool OpenFile();

    void DecryptionFile();

    void DecompressionFile();

    void ClosedFile();

}

 

class CEnCryptionPng : IReadFile

{

       #region Open and entry file

       public bool OpenFile()

       {

              // đoạn code open file cho file png

              return true;

       }

       public void DecryptionFile()

       {

              // đoạn code decryption cho file png

       }

       public void DecompressionFile()

       {

              // đoạn code decompression cho file png

       }

       public void ClosedFile()

       {

       }

       #endregion

 

       #region Process Encryption

       #endregion

 

       #region Process Compression

       #endregion

 

       #region Dispose

       #endregion

}

 

class CEnCryptionMp3 : IReadFile

{

       #region Open and entry file

       public bool OpenFile()

       {

              // đoạn code open file cho file mp3

              return true;

       }

       public void DecryptionFile()

       {

              // đoạn code decryption cho file mp3

       }

       public void DecompressionFile()

       {

              // đoạn code decompression cho file mp3

       }

       public void ClosedFile()

       {

       }

       #endregion

 

       #region Process Encryption

       #endregion

      

       #region Process Compression

       #endregion

 

       #region Dispose

       #endregion

}

Việc xây dựng kiến trúc giữa các lớp rất quan trọng điều đó giúp cho chương trình thêm tính chặt chẽ, có logic và giúp cho lập trình viên dễ kiểm soát khi viết code.

 

Tin Khác