C# - C Sharp: Từ khóa base


Khóa học qua video:
Lập trình Python All Lập trình C# All SQL Server All Lập trình C All Java PHP HTML5-CSS3-JavaScript
Đăng ký Hội viên
Tất cả các video dành cho hội viên

1. Truy cập phương thức bị ghi đè của lớp cha

Nếu phương thức của lớp con ghi đè phương thức của lớp cha thì ta có thể gọi phương thức bị ghi đè đó của lớp cha bằng cách sử dụng từ khóa base. Ta cũng có thể sử dụng từ khóa base để tham chiếu tới một trường ẩn nào đó (mặc dù trường ẩn là không khuyến khích) của lớp cha.

Ví dụ ta có lớp Animal như sau:

//tạo lớp Animal2:
public class Animal2
{
  //khai báo các thuộc tính:
  int id; //mã nhận diện
  string name; //tên
  float age; //tuổi

  public void InputInfo()
  {//dùng để nhập liệu
    Console.Write("Input id: ");
    id = int.Parse(Console.ReadLine());
    Console.Write("Input name: ");
    name = Console.ReadLine();
    Console.Write("Input age: ");
    age = float.Parse(Console.ReadLine());
  }

  public void ShowInfo()
  {//dùng để hiển thị
    Console.WriteLine("ID: " + id);
    Console.WriteLine("Name: " + name);
    Console.WriteLine("Age: " + age);
  }
}

Bây giờ ta cần xây dựng lớp Cat thừa kế từ lớp Animal ở trên:

class Cat : Animal{
  string color; //màu lông
}

Thì lớp Cat sẽ được thừa kế các trường id, name, age, và thừa kế các phương thức InputInfo() và ShowInfo().

Tuy nhiên, phương thức InputInfo() của lớp cha chỉ nhập liệu được cho 3 trường id, name và age, không thể nhập liệu được cho trường color.

Để giải quyết điều này thì ta làm như sau:

class Cat2 : Animal2
{
  string color;

  public new void InputInfo() {
    base.InputInfo();//dùng từ khóa base để gọi phương thức bị ghi đè của lớp cha
    Console.Write("Input color: ");
    color = Console.ReadLine();
  }
}

Ở đoạn code trên, từ khóa base được dùng để gọi phương thức bị ghi đè của lớp cha là InputInfo().

Tương tự, phương thức ShowInfo() của lớp cha Animal2 cũng không hiển thị được thông tin trường color của lớp con Cat.

Trong trường hợp này ta cũng định nghĩa phương thức ShowInfo() cho lớp Cat và dùng từ khóa base để gọi phương thức ShowInfo() của lớp cha Animal như sau:

class Cat2 : Animal2
{
  string color;

  public new void InputInfo() {
    base.InputInfo();//dùng từ khóa base để gọi phương thức bị ghi đè của lớp cha
    Console.Write("Input color: ");
    color = Console.ReadLine();
  }

  public new void ShowInfo()
  {
    base.ShowInfo();//dùng từ khóa base để gọi phương thức ShowInfo của lớp cha
    Console.WriteLine("Color: " + color);
  }
}

Dưới đây là chương trình hoàn chỉnh, bạn có thể copy và chạy thử:

namespace Demo1
{
  //tạo lớp Animal2:
  public class Animal2
  {
    //khai báo các thuộc tính:
    int id; //mã nhận diện
    string name; //tên
    float age; //tuổi

    public void InputInfo()
    {//dùng để nhập liệu
      Console.Write("Input id: ");
      id = int.Parse(Console.ReadLine());
      Console.Write("Input name: ");
      name = Console.ReadLine();
      Console.Write("Input age: ");
      age = float.Parse(Console.ReadLine());
    }

    public void ShowInfo()
    {//dùng để hiển thị
      Console.WriteLine("ID: " + id);
      Console.WriteLine("Name: " + name);
      Console.WriteLine("Age: " + age);
    }
  }

  class Cat2 : Animal2
  {
    string color;

    public new void InputInfo() {
      base.InputInfo();//dùng từ khóa base để gọi phương thức bị ghi đè của lớp cha
      Console.Write("Input color: ");
      color = Console.ReadLine();
    }

    public new void ShowInfo()
    {
      base.ShowInfo();//dùng từ khóa base để gọi phương thức ShowInfo của lớp cha
      Console.WriteLine("Color: " + color);
    }
  }

  internal class Program
  {
    static void Main()
    {
      Cat2 cat = new Cat2();
      cat.InputInfo();
      cat.ShowInfo();
    }
  }
}

Kết quả thử nghiệm:

Input id: 1234
Input name: Moon
Input age: 1.5
Input color: White
ID: 1234
Name: Moon
Age: 1.5
Color: White

2. Truy cập hàm tạo của lớp cha từ lớp con

Bây giờ, lớp cha Animal2 ở trên được thêm vào hai hàm tạo không tham số và ba tham số như sau:

//tạo lớp Animal2:
public class Animal2
{
  //khai báo các thuộc tính:
  int id; //mã nhận diện
  string name; //tên
  float age; //tuổi

  //hàm tạo không tham số
  public Animal2()
  {
    id = 1234;
    name = "Moon";
    age = 1;
  }

  //hàm tạo 3 tham số
  public Animal2(int id, string name, float age)
  {
    this.id = id;
    this.name = name;
    this.age = age;
  }

  public void InputInfo()
  {//dùng để nhập liệu
    Console.Write("Input id: ");
    id = int.Parse(Console.ReadLine());
    Console.Write("Input name: ");
    name = Console.ReadLine();
    Console.Write("Input age: ");
    age = float.Parse(Console.ReadLine());
  }

  public void ShowInfo()
  {//dùng để hiển thị
    Console.WriteLine("ID: " + id);
    Console.WriteLine("Name: " + name);
    Console.WriteLine("Age: " + age);
  }
}

Và lớp Cat2 vẫn thừa kế từ lớp Animal2, nhưng lưu ý rằng lớp con không được thừa kế các hàm tạo từ lớp cha.

Thì khi ta tạo một đối tượng từ lớp Cat2 và đối tượng này gọi tới hàm tạo không tham số nhưng ta không xây dựng hàm tạo không tham số của Cat2 thì hệ thống sẽ tự tạo hàm tạo không tham số Cat2() và đồng thời cũng gọi đến hàm tạo không tham số Animal2() của lớp Animal2.

Lúc này ở lớp chứa hàm Main() ta làm như sau:

internal class Program
{
  static void Main()
  {
    Cat2 cat = new Cat2();
    //cat.InputInfo();
    cat.ShowInfo();
  }
}

Thì khi chạy ta sẽ được kết quả:

ID: 1234
Name: Moon
Age: 1
Color:

Khi này ta thấy rằng id, name và age của đối tượng cat sẽ vẫn nhận được giá trị khởi tạo ban đầu từ hàm tạo không tham số Animal2() của lớp cha Animal2. Nhưng trường color chỉ nhận được chuỗi rỗng.

Nếu như ta muốn trường color cũng nhận được giá trị khởi tạo ban đầu thì ta cần định nghĩa hàm tạo không tham số Cat2() cho lớp Cat2 như sau:

class Cat2 : Animal2
{
  string color;

  //hàm tạo không tham số của Cat2
  public Cat2()
  {
    color = "White";
  }

  public new void InputInfo()
  {
    base.InputInfo();//dùng từ khóa base để gọi phương thức bị ghi đè của lớp cha
    Console.Write("Input color: ");
    color = Console.ReadLine();
  }

  public new void ShowInfo()
  {
    base.ShowInfo();//dùng từ khóa base để gọi phương thức ShowInfo của lớp cha
    Console.WriteLine("Color: " + color);
  }
}

Khi này ta chạy lại chương trình ta được kết quả như sau:

ID: 1234
Name: Moon
Age: 1
Color: White

Và nếu muốn ta cũng phải xây dựng hàm tạo bốn tham số (ba tham số id, name, age thừa kế từ lớp cha Animal2 và một tham số color của Cat2) cho lớp con Cat2.

Tuy nhiên, nếu ta muốn tận dụng hàm tạo 3 tham số của lớp cha Animal2 thay vì phải xây dựng từ đầu, thì lúc này ta có thể làm như sau:

class Cat2 : Animal2
{
  string color;

  //hàm tạo không tham số của Cat2
  public Cat2()
  {
    color = "White";
  }

  //hàm tạo 4 tham số của Cat2
  public Cat2(int id, string name, float age, string color) : base(id, name, age)
  {
    this.color = color;
  }

  public new void InputInfo()
  {
    base.InputInfo();//dùng từ khóa base để gọi phương thức bị ghi đè của lớp cha
    Console.Write("Input color: ");
    color = Console.ReadLine();
  }

  public new void ShowInfo()
  {
    base.ShowInfo();//dùng từ khóa base để gọi phương thức ShowInfo của lớp cha
    Console.WriteLine("Color: " + color);
  }
}

Sau đây là ví dụ đầy đủ, bạn có thể copy và chạy thử:

namespace Demo1
{
  //tạo lớp Animal2:
  public class Animal2
  {
    //khai báo các thuộc tính:
    int id; //mã nhận diện
    string name; //tên
    float age; //tuổi

    //hàm tạo không tham số
    public Animal2()
    {
      id = 1234;
      name = "Moon";
      age = 1;
    }

    //hàm tạo 3 tham số
    public Animal2(int id, string name, float age)
    {
      this.id = id;
      this.name = name;
      this.age = age;
    }

    public void InputInfo()
    {//dùng để nhập liệu
      Console.Write("Input id: ");
      id = int.Parse(Console.ReadLine());
      Console.Write("Input name: ");
      name = Console.ReadLine();
      Console.Write("Input age: ");
      age = float.Parse(Console.ReadLine());
    }

    public void ShowInfo()
    {//dùng để hiển thị
      Console.WriteLine("ID: " + id);
      Console.WriteLine("Name: " + name);
      Console.WriteLine("Age: " + age);
    }
  }

  class Cat2 : Animal2
  {
    string color;

    //hàm tạo không tham số của Cat2
    public Cat2()
    {
      color = "White";
    }

    //hàm tạo 4 tham số của Cat2
    public Cat2(int id, string name, float age, string color) : base(id, name, age)
    {
      this.color = color;
    }

    public new void InputInfo()
    {
      base.InputInfo();//dùng từ khóa base để gọi phương thức bị ghi đè của lớp cha
      Console.Write("Input color: ");
      color = Console.ReadLine();
    }

    public new void ShowInfo()
    {
      base.ShowInfo();//dùng từ khóa base để gọi phương thức ShowInfo của lớp cha
      Console.WriteLine("Color: " + color);
    }
  }

  internal class Program
  {
    static void Main()
    {
      //dùng hàm tạo 0 tham số
      Cat2 cat = new Cat2();
      cat.ShowInfo(); //hiển thị thông tin
      //dùng hàm tạo 4 tham số
      cat = new Cat2(5678, "Bengal", 2.5f, "Spotted brown");
      cat.ShowInfo();//hiển thị thông tin
    }
  }
}

Kết quả:

ID: 1234
Name: Moon
Age: 1
Color: White
ID: 5678
Name: Bengal
Age: 2.5
Color: Spotted brown

Lưu ý: Nếu hàm tạo không gọi tường minh tới hàm tạo của lớp cha thì trình dịch C# sẽ tự động chèn một lời gọi tới hàm tạo không đối số của lớp cha. Lúc này, nếu lớp cha mà không có hàm tạo không tham số thì bạn sẽ nhận được một lỗi.

» Tiếp: Đa hình (Polymorphism)
« Trước: Abstract class & Interface
Khóa học qua video:
Lập trình Python All Lập trình C# All SQL Server All Lập trình C All Java PHP HTML5-CSS3-JavaScript
Đăng ký Hội viên
Tất cả các video dành cho hội viên
Copied !!!