So sánh giữa Abstract Class và Interface trong C#.NET
Đây là một câu hỏi mà mình chắc chắn là có rất nhiều nhà tuyển dụng cũng như các bạn developer phân vân và chưa rõ ràng. Đây cũng là câu hỏi hay gặp khi đi phỏng vấn, và quan trọng hơn nó cũng là một trong những kiến thức cơ bản mà các bạn cần phải nắm chắc.
Nhằm giải đáp câu hỏi này, mình sẽ viết một bài tâm huyết để giúp các bạn trả lời một cách rành mạch khi đi phỏng vấn và áp dụng trong dự án của mình.
Để so sánh giữa Abstract class và Interface chúng ta cần bàn đến 2 điểm là giống nhau và khác nhau giữa chúng.
Giống nhau:
- Abstract class và interface đều không thể khởi tạo đối tượng bên trong được.
- Abstract class và interface đều có thể khai báo các phương thức nhưng không thực hiện chúng.
- Abstract class và interface đều bao gồm các phương thức abstract.
- Abstract class và interface đều được thực thi từ các class con hay còn gọi kế thừa, dẫn xuất.
- Abstract class và interface đều có thể kế thừa từ nhiều interface.
Khác nhau:
|
Abstract Class |
Interface |
|
Cho phép khai báo field |
Không cho phép |
|
Các phương thức có thể có thân hàm hoặc không có thân hàm. |
Chỉ khai báo không có thân hàm |
|
Class dẫn xuất chỉ kế thừa được từ 1 abstract class và nhiều interface. |
Class triển khai có thể triển khai nhiều interface. |
|
Có chứa constructor |
Không có |
|
Các phương thức có từ khóa access modifier |
Không có |
Đó chính là các điểm giống và khác nhau của Abstract class và interface ở góc độ ngôn ngữ và lập trình. Còn bản chất và mục đích sử dụng khác nhau mới là phần chính chúng ta phải hiểu.
Đối với Abstract class
Abstract class giống như 1 type, tức là 1 kiểu chúng cho các class dẫn xuất, các class dẫn xuất thuộc về 1 kiểu đó, nó sẽ cung cấp các thuộc tính và hành vi chung nhất cho kiểu đó.
Ví dụ:
abstract class Person
{
protected string _name;
protected DateTime _birthDate;
protected void Say()
{
Console.Write("Person is saying....");
}
protected abstract void Work();
}
class Employee : Person
{
private float _salary;
protected override void Work()
{
throw new NotImplementedException();
}
}
class Student : Person
{
private float _mark;
protected override void Work()
{
throw new NotImplementedException();
}
}
Chúng ta có abstract class Person chứa các thông tin chung cho người như tên hay ngày sinh nhật. Còn lại các class dẫn xuất như Employee hay Student sẽ có các tính chất riêng của nó thì khai báo thêm. Còn những gì có thể dùng chung sẽ được khai báo trong Person, như vậy sẽ giảm thiểu trùng lặp code, và dễ bảo trì hơn.
Vậy chúng ta hiểu rằng mối quan hệ giữa Abstract class và derived class là mối quan hệ is-a tức là mối quan hệ thuộc về tập cha con. Nên một con chỉ thuộc về 1 cha thôi, trong đó cha quy định các gen di truyền chung nhất cho các con, các con có quyền bổ sung thêm, có quyền thể hiện hoặc không thể hiện một đặc tính hay 1 hành động của cha.
Đối với Interface
Khác với Abstract class giống một bản thiết kế của toàn class thì interface chỉ là bản thiết kế của các chi tiết method. Mối quan hệ giữa lớp thực thi và interface là mối quan hệ can-do vì đơn thuần, class triển khai interface nó phải triển khai toàn bộ method của interface đã định nghĩa. Vậy là class đó có thể làm những gì interface quy định.
Như vậy hoàn toàn 1 class có thể can-do nhiều method ở nhiều interface khác nhau, ví dụ:
interface IRunable
{
void Run();
}
interface IWorkable
{
void Work();
}
interface IEatable
{
void Eat();
}
class Person : IRunable,IWorkable, IEatable
{
protected string _name;
protected DateTime _birthDate;
public void Run()
{
Console.Write("Person runing...");
}
public void Work()
{
Console.Write("Person working...");
}
public void Eat()
{
Console.Write("Person eating...");
}
}
Chúng ta thấy cùng là con người nhưng có thể can-do tức là có thể thực hiện nhiều hành động, các interface chỉ định nghĩa tên các hành động, để các class implement triển khai chi tiết, tức triển khai interface nào có thể can-do được các hành động của interface đó.
Vậy sự khác nhau chính giữa abstract class và interface ở đây chính là mối quan hệ giữa class dẫn xuất và chúng. Đồng thời khác nhau ở mục đích sử dụng của chúng.
Trích nguồn từ: TEDU
Bài viết liên quan
Sử dụng kiểu tập hợp (Enum)
Enum (viết tắt của Enumeration) trong C# là một kiểu dữ liệu đặc biệt cho phép bạn định nghĩa một tập hợp các hằng số có tên
Đọc thêmTính đóng gói (Encapsulation) và best practices trong OOP
(Tính đóng gói) là một trong những nguyên tắc cơ bản của lập trình hướng đối tượng (OOP).
Đọc thêmTính trừu tượng - Abstract classes and interfaces
Tính trừu tượng (Abstraction) trong OOP là kỹ thuật ẩn đi các chi tiết triển khai và chỉ hiển thị cho người dùng những chức năng cần thiết.
Đọc thêmTính chất kế thừa (Inheritance) và đa hình (polymorphism)
Kế thừa là cơ chế cho phép một lớp (class) kế thừa các thuộc tính và phương thức từ một lớp khác.
Đọc thêmCách debug ứng dụng C#
Hướng dẫn cách debug chương trình C# trong Visual Studio và Visual Studio Code
Đọc thêmTìm hiểu về các loại Collection trong C#
Trong C#, collections là các cấu trúc dữ liệu được sử dụng để lưu trữ và quản lý các nhóm đối tượng. C# cung cấp nhiều loại collections khác nhau để phù hợp với các yêu cầu cụ thể của lập trình viên
Đọc thêmTổng quan về Generic và Non-Generic Collection
Hiểu khái niệm Generic và Non-Generic Collection và phân biệt giữa Generic Collection và Non-Generic Collection.
Đọc thêmSử dụng mảng (Arrays)
Mảng trong C# là một cấu trúc dữ liệu lưu trữ một dãy các phần tử có bộ nhớ nằm liên tiếp nhau và có kích thước cố đinh.
Đọc thêmLập trình hướng đối tượng
Lập trình hướng đối tượng (Object Oriented Programing) hay còn gọi là OOP. Là một kỹ thuật lập trình cho phép các lập trình viên có thể ánh xạ các thực thể bên ngoài đời thực và trừu tượng hoá thành các class và object trong mã nguồn.
Đọc thêmVòng lặp (loop)
Trong thực tế khi bạn cần thực thi một khối lệnh nhiều lần. Vòng lặp cho phép chúng ta thực thi một câu lệnh hoặc một khối lệnh nhiều lần.
Đọc thêm