So sánh interface và abstract class c năm 2024

Thì thuộc tính chung của chúng nó là tên loại động vật (chó, mèo,..), thuộc tính có chân, tiếng kêu …

Thay vì mỗi con vật ta phải khởi tạo mỗi class riêng thì ta sẽ tạo một class có thuộc tính loài chung có tên Animal.

So sánh interface và abstract class c năm 2024
abstract class Animal
{
    abstract public void NameAnimal(string name);
    abstract public void SoChan(int sochan);
    public void TiengKeu()
    {
        Console.WriteLine("Con nào cũng kêu.");
    }
}

Ta tạo ra một class dành riêng cho

class ConCho : Animal
{
    public override void NameAnimal(string name)
    {
        Console.WriteLine("Đây là con {0} nhé.", name);
    }
    public override void SoChan(int sochan)
    {
        Console.WriteLine("Số chân của nó là {0}", sochan);
    }
}

6 (miễn là chó và có rất nhiều loại chó sẽ khởi tạo từ class này).

Nó là loại chó và được kế thừa từ class Animal, vì nó có thuộc tính của class Animal.

class ConCho : Animal
{
    public override void NameAnimal(string name)
    {
        Console.WriteLine("Đây là con {0} nhé.", name);
    }
    public override void SoChan(int sochan)
    {
        Console.WriteLine("Số chân của nó là {0}", sochan);
    }
}

Tương tự

class ConCho : Animal
{
    public override void NameAnimal(string name)
    {
        Console.WriteLine("Đây là con {0} nhé.", name);
    }
    public override void SoChan(int sochan)
    {
        Console.WriteLine("Số chân của nó là {0}", sochan);
    }
}

6 thì ta cũng tạo ra một class dành cho loại gà ( và cũng có rất nhiều loại gà) và dĩ nhiên nó sẽ kế thừa thuộc tính của Animal.

class ConGa: Animal
{
    public override void NameAnimal(string name)
    {
        Console.WriteLine("Đây là con {0} nhé.", name);
    }
    public override void SoChan(int sochan)
    {
        Console.WriteLine("Số chân của nó là {0}", sochan);
    }
}

Và mỗi khi sử dụng thì ta lại khởi tạo đối tượng thôi.

Ah, tới đây thì các bạn sẽ nói:

“Ủa đơn giản thôi! Thì chỉ cần tạo riêng mỗi loại một class là xong mà?”

Ối bạn ới…..

Đúng là nếu đơn giản vậy thì chỉ cần tạo class con chó, class con gà mỗi thứ một class là xong.

Những thứ chúng ta cần ứng dụng là một cái gì đó to lớn hơn, vào các Project lớn.

Và khi một Project lớn, cái chúng ta cần khi lập trình, cũng như người khác kế thừa lại code của chúng ta là cái nhìn

class ConCho : Animal
{
    public override void NameAnimal(string name)
    {
        Console.WriteLine("Đây là con {0} nhé.", name);
    }
    public override void SoChan(int sochan)
    {
        Console.WriteLine("Số chân của nó là {0}", sochan);
    }
}

8

Bạn tưởng tượng bạn tạo hàng trăm, hàng ngàn đối tượng, mỗi đối tượng một tên, khi nhìn lại chúng ta khó có thể hình dung đối tượng này có kiểu dữ liệu như thế nào?

Nhưng khi áp dụng

class ConCho : Animal
{
    public override void NameAnimal(string name)
    {
        Console.WriteLine("Đây là con {0} nhé.", name);
    }
    public override void SoChan(int sochan)
    {
        Console.WriteLine("Số chân của nó là {0}", sochan);
    }
}

0 nó sẽ có thêm phần gọi phía trước khởi tạo (ví dụ vậy đó) giúp ta dễ hình dung hơn.

Bây giờ chúng ta nhìn vào chương trình chính nhé.

class Program
{
    static void Main(string[] args)
    {
        Animal choden = new ConCho();
        choden.NameAnimal("chó đen");
        choden.SoChan(4);       
        choden.TiengKeu();
        Console.WriteLine();
        Animal chotrang = new ConCho();
        chotrang.NameAnimal("chó trắng");
        chotrang.SoChan(4);
        chotrang.TiengKeu();
        Console.WriteLine();
        Animal gaden = new ConGa();
        gaden.NameAnimal("gà đen");
        gaden.SoChan(2);
        gaden.TiengKeu();
        Console.WriteLine();
        Animal gatrang = new ConGa();
        gatrang.NameAnimal("gà trắng");
        gatrang.SoChan(2);
        gatrang.TiengKeu();
    }
}

Ta thấy, trước khi khởi tạo đối tượng thì sẽ thấy đối tượng có kiểu Animal (động vật), được khởi tạo cho loài chó ( loài gà).

Nhìn rất trực quan, dễ hiểu code.

Kết quả chương trình:

Đây là con chó đen nhé.
Số chân của nó là 4
Con nào cũng kêu.
Đây là con chó trắng nhé.
Số chân của nó là 4
Con nào cũng kêu.
Đây là con gà đen nhé.
Số chân của nó là 2
Con nào cũng kêu.
Đây là con gà trắng nhé.
Số chân của nó là 2
Con nào cũng kêu.
Press any key to continue . . .

Tuy nhiên, ở method tiếng kêu thì cả 4 lần gọi nó hiện ra chung chung.

Con nào cũng kêu.

Giải pháp ở đây là

class ConGa: Animal
{
    public override void NameAnimal(string name)
    {
        Console.WriteLine("Đây là con {0} nhé.", name);
    }
    public override void SoChan(int sochan)
    {
        Console.WriteLine("Số chân của nó là {0}", sochan);
    }
}

0 bên trong

class ConCho : Animal
{
    public override void NameAnimal(string name)
    {
        Console.WriteLine("Đây là con {0} nhé.", name);
    }
    public override void SoChan(int sochan)
    {
        Console.WriteLine("Số chân của nó là {0}", sochan);
    }
}

0. Chúng ta sẽ chỉnh lại code của Class Animal như sau:

Thêm từ khóa

class ConGa: Animal
{
    public override void NameAnimal(string name)
    {
        Console.WriteLine("Đây là con {0} nhé.", name);
    }
    public override void SoChan(int sochan)
    {
        Console.WriteLine("Số chân của nó là {0}", sochan);
    }
}

2 vào method TiengKeu().

abstract class Animal
{
    abstract public void NameAnimal(string name);
    abstract public void SoChan(int sochan);
    public virtual void TiengKeu()
    {
        Console.WriteLine("Con nào cũng kêu.");
    }
}

Từ khóa

class ConGa: Animal
{
    public override void NameAnimal(string name)
    {
        Console.WriteLine("Đây là con {0} nhé.", name);
    }
    public override void SoChan(int sochan)
    {
        Console.WriteLine("Số chân của nó là {0}", sochan);
    }
}

2 cho phép chúng ta

class ConGa: Animal
{
    public override void NameAnimal(string name)
    {
        Console.WriteLine("Đây là con {0} nhé.", name);
    }
    public override void SoChan(int sochan)
    {
        Console.WriteLine("Số chân của nó là {0}", sochan);
    }
}

4 method của lớp cha (Animal), hoặc là

class ConGa: Animal
{
    public override void NameAnimal(string name)
    {
        Console.WriteLine("Đây là con {0} nhé.", name);
    }
    public override void SoChan(int sochan)
    {
        Console.WriteLine("Số chân của nó là {0}", sochan);
    }
}

5 (ghi đè) lại method mới ở class con (con chó, con gà).

Như class ConCho chúng ta đã

class ConGa: Animal
{
    public override void NameAnimal(string name)
    {
        Console.WriteLine("Đây là con {0} nhé.", name);
    }
    public override void SoChan(int sochan)
    {
        Console.WriteLine("Số chân của nó là {0}", sochan);
    }
}

5 method TiengKeu() của lớp Animal bằng tiếng kêu riêng của loài chó.

class ConCho : Animal
{
    public override void NameAnimal(string name)
    {
        Console.WriteLine("Đây là con {0} nhé.", name);
    }
    public override void SoChan(int sochan)
    {
        Console.WriteLine("Số chân của nó là {0}", sochan);
    }
    public override void TiengKeu()
    {
        Console.WriteLine("Con chó kêu: Woof..Woof.. ");
    }
}

Kết quả chương trình:

Đây là con chó đen nhé.
Số chân của nó là 4
Con chó kêu: Woof..Woof..
Đây là con chó trắng nhé.
Số chân của nó là 4
Con chó kêu: Woof..Woof..
Đây là con gà đen nhé.
Số chân của nó là 2
Con nào cũng kêu.
Đây là con gà trắng nhé.
Số chân của nó là 2
Con nào cũng kêu.
Press any key to continue . . .

Vậy là method TiengKeu() của class ConCho sau khi được

class ConGa: Animal
{
    public override void NameAnimal(string name)
    {
        Console.WriteLine("Đây là con {0} nhé.", name);
    }
    public override void SoChan(int sochan)
    {
        Console.WriteLine("Số chân của nó là {0}", sochan);
    }
}

5 lên lớp cha nó đã có tiếng kêu riêng.

Con chó kêu: Woof..Woof..

Bây giờ chúng ta qua Class ConGa, như đã nói ở trên khi method TiengKeu() của class Animal là thuộc tính

class ConGa: Animal
{
    public override void NameAnimal(string name)
    {
        Console.WriteLine("Đây là con {0} nhé.", name);
    }
    public override void SoChan(int sochan)
    {
        Console.WriteLine("Số chân của nó là {0}", sochan);
    }
}

2, thì các lớp kế thừa nó

class ConGa: Animal
{
    public override void NameAnimal(string name)
    {
        Console.WriteLine("Đây là con {0} nhé.", name);
    }
    public override void SoChan(int sochan)
    {
        Console.WriteLine("Số chân của nó là {0}", sochan);
    }
}

9 hoặc

class Program
{
    static void Main(string[] args)
    {
        Animal choden = new ConCho();
        choden.NameAnimal("chó đen");
        choden.SoChan(4);       
        choden.TiengKeu();
        Console.WriteLine();
        Animal chotrang = new ConCho();
        chotrang.NameAnimal("chó trắng");
        chotrang.SoChan(4);
        chotrang.TiengKeu();
        Console.WriteLine();
        Animal gaden = new ConGa();
        gaden.NameAnimal("gà đen");
        gaden.SoChan(2);
        gaden.TiengKeu();
        Console.WriteLine();
        Animal gatrang = new ConGa();
        gatrang.NameAnimal("gà trắng");
        gatrang.SoChan(2);
        gatrang.TiengKeu();
    }
}

0. Ở kết quả trên, do chúng ta không tiến hành

class ConGa: Animal
{
    public override void NameAnimal(string name)
    {
        Console.WriteLine("Đây là con {0} nhé.", name);
    }
    public override void SoChan(int sochan)
    {
        Console.WriteLine("Số chân của nó là {0}", sochan);
    }
}

5 cho method TiengKeu() của class ConGa nên nó vẫn sử dụng phương thức gọi của lớp cha “Con nào cũng kêu.”

Bây giờ, chúng ta chỉnh code một tí.

Vừa sử dụng lại method TiengKeu() của class cha Animal và thêm

class ConGa: Animal
{
    public override void NameAnimal(string name)
    {
        Console.WriteLine("Đây là con {0} nhé.", name);
    }
    public override void SoChan(int sochan)
    {
        Console.WriteLine("Số chân của nó là {0}", sochan);
    }
}

5 (ghi đè) thêm thuộc tính mới cho method TiengKeu() ở class con kế thừa là class ConGa.

class ConGa: Animal
{
    public override void NameAnimal(string name)
    {
        Console.WriteLine("Đây là con {0} nhé.", name);
    }
    public override void SoChan(int sochan)
    {
        Console.WriteLine("Số chân của nó là {0}", sochan);
    }
    public override void TiengKeu()
    {
        base.TiengKeu();
        Console.WriteLine("Con gà kêu: ò ó o... ");
    }
}

Và kết quả chương trình:

Đây là con chó đen nhé.
Số chân của nó là 4
Con chó kêu: Woof..Woof..
Đây là con chó trắng nhé.
Số chân của nó là 4
Con chó kêu: Woof..Woof..
Đây là con gà đen nhé.
Số chân của nó là 2
Con nào cũng kêu.
Con gà kêu: ò ó o...
Đây là con gà trắng nhé.
Số chân của nó là 2
Con nào cũng kêu.
Con gà kêu: ò ó o...
Press any key to continue . . .

Chúng ta thấy từ khóa

class Program
{
    static void Main(string[] args)
    {
        Animal choden = new ConCho();
        choden.NameAnimal("chó đen");
        choden.SoChan(4);       
        choden.TiengKeu();
        Console.WriteLine();
        Animal chotrang = new ConCho();
        chotrang.NameAnimal("chó trắng");
        chotrang.SoChan(4);
        chotrang.TiengKeu();
        Console.WriteLine();
        Animal gaden = new ConGa();
        gaden.NameAnimal("gà đen");
        gaden.SoChan(2);
        gaden.TiengKeu();
        Console.WriteLine();
        Animal gatrang = new ConGa();
        gatrang.NameAnimal("gà trắng");
        gatrang.SoChan(2);
        gatrang.TiengKeu();
    }
}

3, nó là từ khóa để cho phép gọi lại method của lớp cha class Animal.

Và kết quả là vừa in ra thuộc tính của class cha và in ra thuộc tính của lớp kế thừa.

Con nào cũng kêu. Con gà kêu: ò ó o…


Một số lưu ý với Abstract class:

Không thể tạo đối tượng cho Abstract class (nó sinh ra là để class khác kế thừa).

Một Abstract class phải có tối thiểu một Abstract method.

Một Abstract method không thể có nội dung bên trong (có thể có phần khai báo như ví dụ method abstract public void NameAnimal(string name);).