Lập trình C# – Quá tải toán tử phân số

Xây dựng class phân số và các phép toán phân số

Yêu cầu đặt ra là chúng ta phải xây dựng một class về phân số, sử dụng Operator overloading như đã giới thiệu ở trên để thực hiện các phép toán cộng trừ nhân chia phân số đơn giản. Xây dựng Class PhanSo

Bước 1: Xây dựng các thuộc tính

private int _TuSo, _MauSo;
  public PhanSo()
  {
      this._MauSo = 1;
  }
  public int TuSo
  {
      get
      {
          return this._TuSo;
      }
      set
      {
          this._TuSo = value;
      }
  }
  public int MauSo
  {
      get
      {
          return this._MauSo;
      }
      set
      {
          try
          {
              if (value == 0)
              {
                  Exception MauBangKhong = new Exception("Mau phai khac 0");
                  throw MauBangKhong;
              }
              else
              {
                  this._MauSo = value;
              }
          }
          catch (Exception e)
          {
              Console.WriteLine(e);
              throw e;
          }
      }
  }

Bước 2:  Xây dựng phương thức RutGon()

public void RutGon()
{
    int a = this.TuSo;
    int b = this.MauSo;
    int ucln;
    if (a < 0)
    {
        a = a * (-1);
    }
    if (b < 0)
    {
        b = b * (-1);
    }
    if (a == 0)
    {
        ucln = a + b;
    }
    while (a != b)
    {
        if (a > b)
        {
            a -= b;
        }
        else
        {
            b -= a;
        }
    }
    ucln = a;
    this.TuSo /= ucln;
    this.MauSo /= ucln;
}

Bước 3:  Quá tải các toán tử “+, -, *, /” và “>, <“.  Cú pháp tổng quát sẽ là:

public static <Kiểu dữ liệu trả về> operator <toán tử> (Các tham số truyền vào)
{
     // Code
     return ...
}

Mã nguồn của các toán tử

public static PhanSo operator +(PhanSo a, PhanSo b)
{
    PhanSo c = new PhanSo();
    c.MauSo = a.MauSo * b.MauSo;
    c.TuSo = a.TuSo * b.MauSo + b.TuSo * a.MauSo;
    c.RutGon();
    return c;
}
public static PhanSo operator -(PhanSo a, PhanSo b)
{
    PhanSo c = new PhanSo();
    c.MauSo = a.MauSo * b.MauSo;
    c.TuSo = a.TuSo * b.MauSo - b.TuSo * a.MauSo;
    c.RutGon();
    return c;
}
public static PhanSo operator *(PhanSo a, PhanSo b)
{
    PhanSo c = new PhanSo();
    c.MauSo = a.MauSo * b.MauSo;
    c.TuSo = a.TuSo * b.TuSo;
    c.RutGon();
    return c;
}
public static PhanSo operator /(PhanSo a, PhanSo b)
{
    PhanSo c = new PhanSo();
    try
    {
        if (b.TuSo == 0)
        {
            Exception ThuongBangKhong = new Exception("Thuong phai khac 0");
            throw ThuongBangKhong;
        }
        else
        {
            c.TuSo = a.TuSo * b.MauSo;
            c.MauSo = a.MauSo * b.TuSo;
            c.RutGon();
            return c;
        }
    }
    catch (Exception e)
    {
        Console.WriteLine(e);
        throw e;
    }
}
public double Giatri()
{
    return Convert.ToDouble(this.TuSo) / Convert.ToDouble(this.MauSo);
}

public bool SoSanh(PhanSo a) // so sanh 2 phan so. neu >  la true, nguoc lai < la false.
{
    float x;
    float y;
    if (MauSo != a.MauSo)
    {
        x = TuSo * a.MauSo;
        y = MauSo * a.TuSo;
    }
    else
    {
        y = TuSo;
        x = a.TuSo;
    }
    if (x > y)
        return true;
    return false;
}

Để xuất các phân số chúng ta overrite lại phương thức ToString():

public override string ToString()
{
    return Convert.ToString(this.TuSo) + "/" + Convert.ToString(this.MauSo);
}

Ví dụ với toán tử cộng hai phân số “+” như sau:

public static Phanso operator +(Phanso a, Phanso b)
{
      Phanso c = new Phanso();
      c.Mauso = a.Mauso * b.Mauso;
      c.Tuso = a.Tuso * b.Tauso + b.Tuso * a.Mauso;
      c.Rutgon();
      return c;
}

Bước 4: Công việc xây dựng class Phanso đã xong, giờ ta cùng quay xuống hàm Main để xem đoạn code kia chạy như nào nhé. Ở hàm Main ta thử một ví dụ sau đây:

static void Main(string[] args)
{
  int a, b;
  PhanSo phanso1 = new PhanSo { TuSo = 10, MauSo = 4 };
  PhanSo phanso2 = new PhanSo { TuSo = 3, MauSo = 7 };            
  Console.WriteLine("Phan so thu nhat = {0}", phanso1); 
  Console.WriteLine("Phan so thu hai = {0}", phanso2);

  int chon;
  do

  {

      Console.WriteLine("******************************************************");
      Console.WriteLine("                         MENU");
      Console.WriteLine("   1. Tong");
      Console.WriteLine("   2. Hieu");
      Console.WriteLine("   3. Tich");
      Console.WriteLine("   4. Thuong");
      Console.WriteLine("   5. Cong phan so hien hanh voi mot so nguyen");
      Console.WriteLine("   6. Cong phan so hien hanh voi mot phan so khac");
      Console.WriteLine("   7. Rut gon phan so");
      Console.WriteLine("   8. So sanh 2 phan so");
      Console.WriteLine("   9. Thoat");
      chon = Int32.Parse(Console.ReadLine());
      switch (chon)

      {

         case 1:
              {                    
                 Console.Write("Tong cua hai phan so : ");
                 Console.WriteLine(phanso1 + phanso2);
                 break;
              }

         case 2:
              {
                  Console.Write("Hieu cua hai phan so :");
                  Console.WriteLine(phanso1 - phanso2);
                  break;
              }

         case 3:
              {                           
                  Console.Write("Hieu cua hai phan so :");
                  Console.WriteLine(phanso1 * phanso2);
                  break;
              }

         case 4:
              {                        
                  Console.Write("Hieu cua hai phan so :");
                  Console.WriteLine(phanso1 / phanso2);
                  break;
              }

          case 5:
              {
                  Console.Write("Phan so hien hanh la: ");
                  Console.WriteLine(phanso1);
                  Console.Write("Nhap vao so nguyen a = ");
                  a = Int32.Parse(Console.ReadLine());
                  PhanSo phanso3 = new PhanSo { TuSo=a};
                  Console.Write("Tong cua so phan so hien hanh va so nguyen a =  " + a + " la:  ");
                  Console.WriteLine(phanso1 + phanso3);
                  break;
              }

          case 6:
              {
                  Console.Write("Phan so hien hanh la: {0} ", phanso1);                        
                  Console.WriteLine("Nhap mot phan so:");
                  Console.Write("Nhap vao tu so: ");
                  a = Int32.Parse(Console.ReadLine());
                  Console.Write("Nhap vao mau so: ");
                  b = Int32.Parse(Console.ReadLine());
                  PhanSo psk = new PhanSo { TuSo =a , MauSo = b };                        
                  Console.Write("Tong cua phan so hien hanh voi phan so " + a + "/" + b + " la:");
                  Console.WriteLine(phanso1 + psk); 
                  break;
              }

         case 7:
              {
                  Console.Write("Phan so can rut gon: ");
                  Console.WriteLine(phanso1);                   
                  Console.WriteLine();
                  Console.Write("Phan so sau khi rut gon: ");
                  phanso1.RutGon();
                  Console.WriteLine(phanso1);
                  break;

              }

          case 8:
              {
                  if(phanso1.SoSanh(phanso2))
                      Console.WriteLine("phan so" + phanso1+ " lon hon phan so " + phanso2);
                  else
                      Console.WriteLine("phan so" + phanso1 + " nho hon phan so " + phanso2);
                  break;
              }
          case 9: goto ketthuc;

      }

  }

  while (chon != 9);

  Console.ReadLine();

ketthuc:;           
}

Bước 5: Trong Program code test như sau:

using System;

namespace CSCoBan
{
    class Program
    {
        static void Main(string[] args)
        {
            int a, b;
            PhanSo phanso1 = new PhanSo { TuSo = 10, MauSo = 4 };
            PhanSo phanso2 = new PhanSo { TuSo = 3, MauSo = 7 };            
            Console.WriteLine("Phan so thu nhat = {0}", phanso1); 
            Console.WriteLine("Phan so thu hai = {0}", phanso2);
            
            int chon;
            do

            {

                Console.WriteLine("******************************************************");
                Console.WriteLine("                         MENU");
                Console.WriteLine("   1. Tong");
                Console.WriteLine("   2. Hieu");
                Console.WriteLine("   3. Tich");
                Console.WriteLine("   4. Thuong");
                Console.WriteLine("   5. Cong phan so hien hanh voi mot so nguyen");
                Console.WriteLine("   6. Cong phan so hien hanh voi mot phan so khac");
                Console.WriteLine("   7. Rut gon phan so");
                Console.WriteLine("   8. So sanh 2 phan so");
                Console.WriteLine("   9. Thoat");
                chon = Int32.Parse(Console.ReadLine());
                switch (chon)

                {

                   case 1:
                        {                    
                           Console.Write("Tong cua hai phan so : ");
                           Console.WriteLine(phanso1 + phanso2);
                           break;
                        }

                   case 2:
                        {
                            Console.Write("Hieu cua hai phan so :");
                            Console.WriteLine(phanso1 - phanso2);
                            break;
                        }

                   case 3:
                        {                           
                            Console.Write("Hieu cua hai phan so :");
                            Console.WriteLine(phanso1 * phanso2);
                            break;
                        }

                   case 4:
                        {                        
                            Console.Write("Hieu cua hai phan so :");
                            Console.WriteLine(phanso1 / phanso2);
                            break;
                        }

                    case 5:
                        {
                            Console.Write("Phan so hien hanh la: ");
                            Console.WriteLine(phanso1);
                            Console.Write("Nhap vao so nguyen a = ");
                            a = Int32.Parse(Console.ReadLine());
                            PhanSo phanso3 = new PhanSo { TuSo=a};
                            Console.Write("Tong cua so phan so hien hanh va so nguyen a =  " + a + " la:  ");
                            Console.WriteLine(phanso1 + phanso3);
                            break;
                        }

                    case 6:
                        {
                            Console.Write("Phan so hien hanh la: {0} ", phanso1);                        
                            Console.WriteLine("Nhap mot phan so:");
                            Console.Write("Nhap vao tu so: ");
                            a = Int32.Parse(Console.ReadLine());
                            Console.Write("Nhap vao mau so: ");
                            b = Int32.Parse(Console.ReadLine());
                            PhanSo psk = new PhanSo { TuSo =a , MauSo = b };                        
                            Console.Write("Tong cua phan so hien hanh voi phan so " + a + "/" + b + " la:");
                            Console.WriteLine(phanso1 + psk); 
                            break;
                        }

                   case 7:
                        {
                            Console.Write("Phan so can rut gon: ");
                            Console.WriteLine(phanso1);                   
                            Console.WriteLine();
                            Console.Write("Phan so sau khi rut gon: ");
                            phanso1.RutGon();
                            Console.WriteLine(phanso1);
                            break;

                        }

                    case 8:
                        {
                            if(phanso1.SoSanh(phanso2))
                                Console.WriteLine("phan so" + phanso1+ " lon hon phan so " + phanso2);
                            else
                                Console.WriteLine("phan so" + phanso1 + " nho hon phan so " + phanso2);
                            break;
                        }
                    case 9: goto ketthuc;

                }

            }

            while (chon != 9);

            Console.ReadLine();

        ketthuc:;           
        }
    }
    class PhanSo
    {
        private int _TuSo, _MauSo;
        public PhanSo()
        {
            this._MauSo = 1;
        }
        public int TuSo
        {
            get
            {
                return this._TuSo;
            }
            set
            {
                this._TuSo = value;
            }
        }
        public int MauSo
        {
            get
            {
                return this._MauSo;
            }
            set
            {
                try
                {
                    if (value == 0)
                    {
                        Exception MauBangKhong = new Exception("Mau phai khac 0");
                        throw MauBangKhong;
                    }
                    else
                    {
                        this._MauSo = value;
                    }
                }
                catch (Exception e)
                {
                    Console.WriteLine(e);
                    throw e;
                }
            }
        }
        public void RutGon()
        {
            int a = this.TuSo;
            int b = this.MauSo;
            int ucln;
            if (a < 0)
            {
                a = a * (-1);
            }
            if (b < 0)
            {
                b = b * (-1);
            }
            if (a == 0)
            {
                ucln = a + b;
            }
            while (a != b)
            {
                if (a > b)
                {
                    a -= b;
                }
                else
                {
                    b -= a;
                }
            }
            ucln = a;
            this.TuSo /= ucln;
            this.MauSo /= ucln;
        }
        public static PhanSo operator +(PhanSo a, PhanSo b)
        {
            PhanSo c = new PhanSo();
            c.MauSo = a.MauSo * b.MauSo;
            c.TuSo = a.TuSo * b.MauSo + b.TuSo * a.MauSo;
            c.RutGon();
            return c;
        }
        public static PhanSo operator -(PhanSo a, PhanSo b)
        {
            PhanSo c = new PhanSo();
            c.MauSo = a.MauSo * b.MauSo;
            c.TuSo = a.TuSo * b.MauSo - b.TuSo * a.MauSo;
            c.RutGon();
            return c;
        }
        public static PhanSo operator *(PhanSo a, PhanSo b)
        {
            PhanSo c = new PhanSo();
            c.MauSo = a.MauSo * b.MauSo;
            c.TuSo = a.TuSo * b.TuSo;
            c.RutGon();
            return c;
        }
        public static PhanSo operator /(PhanSo a, PhanSo b)
        {
            PhanSo c = new PhanSo();
            try
            {
                if (b.TuSo == 0)
                {
                    Exception ThuongBangKhong = new Exception("Thuong phai khac 0");
                    throw ThuongBangKhong;
                }
                else
                {
                    c.TuSo = a.TuSo * b.MauSo;
                    c.MauSo = a.MauSo * b.TuSo;
                    c.RutGon();
                    return c;
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
                throw e;
            }
        }
        public double Giatri()
        {
            return Convert.ToDouble(this.TuSo) / Convert.ToDouble(this.MauSo);
        }
        public override string ToString()
        {
            return Convert.ToString(this.TuSo) + "/" + Convert.ToString(this.MauSo);
        }
        public bool SoSanh(PhanSo a) // so sanh 2 phan so. neu >  la true, nguoc lai < la false.
        {
            float x;
            float y;
            if (MauSo != a.MauSo)
            {
                x = TuSo * a.MauSo;
                y = MauSo * a.TuSo;
            }
            else
            {
                y = TuSo;
                x = a.TuSo;
            }
            if (x > y)
                return true;
            return false;
        }
    }
}

Xem ví dụ

Bước 6: Nhấn Ctrl+F5 để chạy và xem kết quả

Class phân số đơn giản đã được mình xây dựng xong, với bốn phép toán cộng trừ nhân chia thông thường. Tất nhiên, các bạn có thể hoàn thiện thêm bằng cách thực hiện overloading các toán tử khác như toán tử so sánh, các toán tử một ngôi, thêm vào đó các hàm khác như hàm lũy thừa, phân số nghịch đảo, … để phục vụ việc tính toán trên phân số.

Kết luận

Như vậy, qua ví dụ trên, chúng ta có thể hiểu được phần nào cách hoạt động của Operator Overloading trong C#, cũng như những lợi ích mà nó đem lại. Operator overloading giúp cho code của người lập trình trở nên tường minh hơn, dễ đọc, dễ bảo trì, do vậy các bạn nên học và tập sử dụng chúng một cách thường xuyên hơn.