Chính xác thì sự khác biệt giữa một giao diện và lớp trừu tượng là gì?
Chính xác thì sự khác biệt giữa một giao diện và lớp trừu tượng là gì?
Câu trả lời:
Giao diện là một hợp đồng : Người viết giao diện nói: "này , tôi chấp nhận mọi thứ theo cách đó " và người sử dụng giao diện nói " OK, lớp tôi viết trông giống như vậy ".
Một giao diện là một vỏ trống . Chỉ có chữ ký của các phương thức, ngụ ý rằng các phương thức không có cơ thể. Giao diện không thể làm bất cứ điều gì. Nó chỉ là một mô hình.
Ví dụ (mã giả):
// I say all motor vehicles should look like this:
interface MotorVehicle
{
void run();
int getFuel();
}
// My team mate complies and writes vehicle looking that way
class Car implements MotorVehicle
{
int fuel;
void run()
{
print("Wrroooooooom");
}
int getFuel()
{
return this.fuel;
}
}
Việc thực hiện một giao diện tiêu tốn rất ít CPU, bởi vì nó không phải là một lớp, chỉ là một loạt các tên, và do đó không có bất kỳ tra cứu đắt tiền nào để làm. Thật tuyệt khi nó quan trọng, chẳng hạn như trong các thiết bị nhúng.
Các lớp trừu tượng, không giống như các giao diện, là các lớp. Chúng đắt hơn để sử dụng, bởi vì có một cái nhìn để làm khi bạn thừa kế từ chúng.
Các lớp trừu tượng trông rất giống các giao diện, nhưng chúng có một cái gì đó nhiều hơn: Bạn có thể định nghĩa một hành vi cho chúng. Đó là nhiều hơn về một người nói, " các lớp này sẽ trông như thế, và họ có điểm chung, vì vậy hãy điền vào chỗ trống! ".
Ví dụ:
// I say all motor vehicles should look like this:
abstract class MotorVehicle
{
int fuel;
// They ALL have fuel, so lets implement this for everybody.
int getFuel()
{
return this.fuel;
}
// That can be very different, force them to provide their
// own implementation.
abstract void run();
}
// My teammate complies and writes vehicle looking that way
class Car extends MotorVehicle
{
void run()
{
print("Wrroooooooom");
}
}
Trong khi các lớp và giao diện trừu tượng được coi là các khái niệm khác nhau, việc triển khai làm cho tuyên bố đó đôi khi không đúng sự thật. Đôi khi, chúng thậm chí không phải là những gì bạn nghĩ.
Trong Java, quy tắc này được thi hành mạnh mẽ, trong khi trong PHP, các giao diện là các lớp trừu tượng không có phương thức nào được khai báo.
Trong Python, các lớp trừu tượng là một thủ thuật lập trình nhiều hơn mà bạn có thể nhận được từ mô-đun ABC và thực sự đang sử dụng siêu dữ liệu, và do đó các lớp. Và các giao diện có liên quan nhiều hơn đến việc gõ vịt trong ngôn ngữ này và đó là sự pha trộn giữa các quy ước và các phương thức đặc biệt gọi các mô tả (các phương thức __method__).
Như thường lệ với lập trình, có lý thuyết, thực hành và thực hành bằng ngôn ngữ khác :-)
interface
và class
từ đó Head First Java
thật sinh độngA class defines who you are, and an interface tells what roles you could play
Sự khác biệt kỹ thuật chính giữa một lớp trừu tượng và giao diện là:
Các lớp trừu tượng có thể có các hằng, thành viên, sơ khai phương thức (các phương thức không có phần thân) và các phương thức được xác định , trong khi các giao diện chỉ có thể có các hằng và các sơ đồ phương thức .
Các phương thức và thành viên của một lớp trừu tượng có thể được định nghĩa với bất kỳ mức độ hiển thị nào , trong khi tất cả các phương thức của một giao diện phải được định nghĩa là public
(chúng được định nghĩa công khai theo mặc định).
Khi kế thừa một lớp trừu tượng, một lớp con cụ thể phải định nghĩa các phương thức trừu tượng , trong khi đó một lớp trừu tượng có thể mở rộng một lớp trừu tượng khác và các phương thức trừu tượng từ lớp cha không cần phải được định nghĩa.
Tương tự, một giao diện mở rộng giao diện khác không chịu trách nhiệm thực hiện các phương thức từ giao diện cha. Điều này là do các giao diện không thể xác định bất kỳ thực hiện.
Một lớp con chỉ có thể mở rộng một lớp duy nhất (trừu tượng hoặc cụ thể), trong khi một giao diện có thể mở rộng hoặc một lớp có thể thực hiện nhiều giao diện khác .
Một lớp con có thể định nghĩa các phương thức trừu tượng có cùng tầm nhìn hoặc ít hạn chế hơn , trong khi đó một lớp thực hiện giao diện phải xác định các phương thức có cùng mức độ hiển thị (công khai).
CANNOT
được khởi tạo.
Giao diện chỉ chứa định nghĩa / chữ ký của chức năng và nếu chúng ta có một số chức năng chung cũng như chữ ký chung, thì chúng ta cần sử dụng một lớp trừu tượng. Bằng cách sử dụng một lớp trừu tượng, chúng ta có thể cung cấp hành vi cũng như chức năng cả hai cùng một lúc. Một nhà phát triển khác kế thừa lớp trừu tượng có thể sử dụng chức năng này một cách dễ dàng, vì họ chỉ cần điền vào chỗ trống.
http://www.dotnetbull.com/2011/11/difference-b between-abab- class-and.html
http://www.dotnetbull.com/2011/11/what-is-abauge- class-in-c-net.html http://www.dotnetbull.com/2011/11/what-is-interface-in -c-net.html
Một lời giải thích có thể được tìm thấy ở đây: http://www.developer.com/lang/php/article.php/3604111/PHP-5-OOP-Interfaces- Ab.
Một lớp trừu tượng là một lớp chỉ được lập trình viên thực hiện một phần. Nó có thể chứa một hoặc nhiều phương thức trừu tượng. Một phương thức trừu tượng chỉ đơn giản là một định nghĩa hàm phục vụ cho người lập trình biết rằng phương thức đó phải được thực hiện trong một lớp con.
Một giao diện tương tự như một lớp trừu tượng; thực sự các giao diện chiếm không gian tên giống như các lớp và các lớp trừu tượng. Vì lý do đó, bạn không thể định nghĩa một giao diện có cùng tên với một lớp. Một giao diện là một lớp hoàn toàn trừu tượng; không có phương thức nào của nó được thực hiện và thay vì một lớp con phân lớp từ nó, nó được cho là thực hiện giao diện đó.
Dù sao tôi thấy giải thích về giao diện này hơi khó hiểu. Một định nghĩa phổ biến hơn là: Một giao diện định nghĩa một hợp đồng mà các lớp thực hiện phải đáp ứng. Một định nghĩa giao diện bao gồm chữ ký của các thành viên công cộng, không có bất kỳ mã triển khai nào.
Tôi không muốn làm nổi bật sự khác biệt, điều đã được nói trong nhiều câu trả lời (liên quan đến công cụ sửa đổi tĩnh công khai cho các biến trong giao diện & hỗ trợ cho các phương thức riêng tư, được bảo vệ trong các lớp trừu tượng)
Nói một cách đơn giản, tôi muốn nói:
giao diện: Để thực hiện hợp đồng bởi nhiều đối tượng không liên quan
lớp trừu tượng: Để thực hiện cùng một hành vi hoặc khác nhau giữa nhiều đối tượng liên quan
Từ tài liệu của Oracle
Cân nhắc sử dụng các lớp trừu tượng nếu:
Cân nhắc sử dụng các giao diện nếu:
Serializable
giao diện.lớp trừu tượng thiết lập "là một" quan hệ với các lớp cụ thể. giao diện cung cấp khả năng "có" cho các lớp.
Nếu bạn đang tìm kiếm Java
như ngôn ngữ lập trình, đây là một vài cập nhật nữa:
Java 8 đã giảm khoảng cách giữa interface
và abstract
các lớp đến một mức độ nào đó bằng cách cung cấp một default
tính năng phương thức. Một giao diện không có triển khai cho một phương thức hiện không còn hiệu lực.
Tham khảo trang tài liệu này để biết thêm chi tiết.
Hãy xem câu hỏi SE này để biết ví dụ mã để hiểu rõ hơn.
Làm thế nào tôi có thể giải thích sự khác biệt giữa một lớp Giao diện và lớp Trừu tượng?
Một số khác biệt quan trọng:
Ở dạng bảng:
Như Joe đã nêu từ javapapers :
1. Khác biệt chính là các phương thức của giao diện Java hoàn toàn trừu tượng và không thể có các triển khai. Một lớp trừu tượng Java có thể có các phương thức cá thể thực hiện một hành vi mặc định.
2. Biến được khai báo trong giao diện Java theo mặc định là cuối cùng. Một lớp trừu tượng có thể chứa các biến không phải là cuối cùng.
3.Members của một giao diện Java được công khai theo mặc định. Một lớp trừu tượng Java có thể có các hương vị thông thường của các thành viên lớp như private, được bảo vệ, v.v.
Giao diện 4.Java nên được thực hiện bằng cách sử dụng từ khóa. Một lớp trừu tượng Java nên được mở rộng bằng cách sử dụng từ khóa.
5. Một giao diện chỉ có thể mở rộng một giao diện Java khác, một lớp trừu tượng có thể mở rộng một lớp Java khác và thực hiện nhiều giao diện Java.
6.Một lớp Java có thể thực hiện nhiều giao diện nhưng nó chỉ có thể mở rộng một lớp trừu tượng.
7.Interface hoàn toàn trừu tượng và không thể được khởi tạo; Một lớp trừu tượng Java cũng không thể được khởi tạo, nhưng có thể được gọi nếu tồn tại hàm main ().
8. So với các lớp trừu tượng java, các giao diện java chậm vì nó đòi hỏi thêm sự gián tiếp.
Điểm chính là:
Khi bạn muốn cung cấp hành vi đa hình trong hệ thống phân cấp thừa kế, hãy sử dụng các lớp trừu tượng.
Khi bạn muốn hành vi đa hình cho các lớp hoàn toàn không liên quan, hãy sử dụng một giao diện.
Tôi đang xây dựng một tòa nhà 300 tầng
Giao diện kế hoạch chi tiết của tòa nhà
Tòa nhà được xây dựng lên tới 200 tầng - hoàn thành một phần --- trừu tượng
Xây dựng hoàn thiện - bê tông
Giao diện
trừu tượng
Lấy từ trang web DurgaJobs
Hãy làm việc với câu hỏi này một lần nữa:
Điều đầu tiên để cho bạn biết là kết quả 1/1 và 1 * 1 giống nhau, nhưng điều đó không có nghĩa là phép nhân và phép chia giống nhau. Rõ ràng, họ giữ một số mối quan hệ tốt, nhưng tâm trí cả hai bạn đều khác nhau.
Tôi sẽ chỉ ra những khác biệt chính và phần còn lại đã được giải thích:
Các lớp trừu tượng rất hữu ích để mô hình hóa một hệ thống phân cấp lớp. Thoạt nhìn về bất kỳ yêu cầu nào, chúng tôi rõ ràng một phần về chính xác những gì sẽ được xây dựng, nhưng chúng tôi biết những gì cần xây dựng. Và vì vậy các lớp trừu tượng của bạn là các lớp cơ sở của bạn.
Các giao diện rất hữu ích để cho các hệ thống phân cấp hoặc các lớp khác biết rằng những gì tôi có khả năng làm. Và khi bạn nói tôi có khả năng gì đó, bạn phải có khả năng đó. Các giao diện sẽ đánh dấu nó là bắt buộc đối với một lớp để thực hiện các chức năng tương tự.
Thật ra nó khá đơn giản.
Bạn có thể nghĩ về một giao diện là một lớp chỉ được phép có các phương thức trừu tượng và không có gì khác.
Vì vậy, một giao diện chỉ có thể "khai báo" và không xác định hành vi bạn muốn lớp có.
Một lớp trừu tượng cho phép bạn thực hiện cả khai báo (sử dụng các phương thức trừu tượng) cũng như định nghĩa (sử dụng các triển khai phương thức đầy đủ) hành vi mà bạn muốn lớp có.
Và một lớp thông thường chỉ cho phép bạn xác định, không khai báo, hành vi / hành động bạn muốn lớp có.
Một điều cuối cùng,
Trong Java, bạn có thể triển khai nhiều giao diện, nhưng bạn chỉ có thể mở rộng một (Lớp trừu tượng hoặc Lớp) ...
Điều này có nghĩa là sự kế thừa của hành vi được xác định bị hạn chế chỉ cho phép một lớp cho mỗi lớp ... tức là nếu bạn muốn một lớp đóng gói hành vi từ Lớp A, B & C, bạn sẽ cần phải làm như sau: Lớp A mở rộng B, Lớp C mở rộng A .. đó là một chút về cách để có nhiều di sản ...
Mặt khác, các giao diện có thể làm đơn giản: giao diện C thực hiện A, B
Vì vậy, trong thực tế, Java chỉ hỗ trợ nhiều kế thừa trong "các hành vi được khai báo" tức là các giao diện và chỉ một kế thừa duy nhất có hành vi được xác định .. trừ khi bạn thực hiện theo cách tôi đã mô tả ...
Hy vọng rằng có ý nghĩa.
Việc so sánh giao diện với lớp trừu tượng là sai. Thay vào đó nên có hai so sánh khác: 1) giao diện so với lớp và 2) trừu tượng so với lớp cuối cùng .
Giao diện là một hợp đồng giữa hai đối tượng. Ví dụ: Tôi là Người đưa thư và bạn là Gói hàng cần giao. Tôi hy vọng bạn biết địa chỉ giao hàng của bạn. Khi ai đó đưa cho tôi Gói hàng, nó phải biết địa chỉ giao hàng của nó:
interface Package {
String address();
}
Lớp là một nhóm các đối tượng tuân theo hợp đồng. Ví dụ, tôi là một hộp từ nhóm "Hộp" và tôi tuân theo hợp đồng mà Người đưa thư yêu cầu. Đồng thời tôi tuân theo các hợp đồng khác:
class Box implements Package, Property {
@Override
String address() {
return "5th Street, New York, NY";
}
@Override
Human owner() {
// this method is part of another contract
}
}
Lớp trừu tượng là một nhóm các đối tượng không đầy đủ. Chúng không thể được sử dụng, vì chúng bỏ lỡ một số phần. Ví dụ: Tôi là một hộp nhận biết GPS trừu tượng - Tôi biết cách kiểm tra vị trí của mình trên bản đồ:
abstract class GpsBox implements Package {
@Override
public abstract String address();
protected Coordinates whereAmI() {
// connect to GPS and return my current position
}
}
Lớp này, nếu được kế thừa / mở rộng bởi một lớp khác, có thể rất hữu ích. Nhưng tự nó - nó là vô dụng, vì nó không thể có đối tượng. Các lớp trừu tượng có thể được xây dựng các yếu tố của các lớp cuối cùng.
Lớp cuối cùng là một nhóm các đối tượng hoàn chỉnh, có thể được sử dụng, nhưng không thể sửa đổi. Họ biết chính xác làm thế nào để làm việc và phải làm gì. Ví dụ: Tôi là Hộp luôn đi đến địa chỉ được chỉ định trong quá trình xây dựng:
final class DirectBox implements Package {
private final String to;
public DirectBox(String addr) {
this.to = addr;
}
@Override
public String address() {
return this.to;
}
}
Trong hầu hết các ngôn ngữ, như Java hoặc C ++, có thể chỉ có một lớp , không trừu tượng cũng không phải cuối cùng. Một lớp như vậy có thể được kế thừa và có thể được khởi tạo. Tuy nhiên, tôi không nghĩ rằng điều này hoàn toàn phù hợp với mô hình hướng đối tượng.
Một lần nữa, so sánh các giao diện với các lớp trừu tượng là không chính xác.
Trong ngắn hạn, sự khác biệt là như sau:
Sự khác biệt về cú pháp giữa Giao diện và Lớp trừu tượng :
Trong Giao diện bây giờ:
public static
- được hỗ trợ
public abstract
- được hỗ trợ
public default
- được hỗ trợ
private static
- được hỗ trợ
private abstract
- biên dịch lỗi
private default
- lỗi biên dịch
private
- được hỗ trợ
Sự khác biệt duy nhất là người ta có thể tham gia vào nhiều kế thừa và không thể khác.
Định nghĩa của một giao diện đã thay đổi theo thời gian. Bạn có nghĩ rằng một giao diện chỉ có khai báo phương thức và chỉ là hợp đồng không? Còn các biến cuối cùng tĩnh và các định nghĩa mặc định sau Java 8 thì sao?
Các giao diện được giới thiệu với Java vì vấn đề kim cương với nhiều sự kế thừa và đó là những gì họ thực sự có ý định làm.
Các giao diện là các cấu trúc được tạo ra để thoát khỏi vấn đề đa kế thừa và có thể có các phương thức trừu tượng, định nghĩa mặc định và các biến cuối cùng tĩnh.
Nếu bạn có một số phương thức phổ biến có thể được sử dụng bởi nhiều lớp, hãy dùng các lớp trừu tượng. Khác nếu bạn muốn các lớp theo một số kế hoạch chi tiết xác định đi cho giao diện.
Các ví dụ sau đây chứng minh điều này.
Lớp trừu tượng trong Java:
abstract class animals
{
// They all love to eat. So let's implement them for everybody
void eat()
{
System.out.println("Eating...");
}
// The make different sounds. They will provide their own implementation.
abstract void sound();
}
class dog extends animals
{
void sound()
{
System.out.println("Woof Woof");
}
}
class cat extends animals
{
void sound()
{
System.out.println("Meoww");
}
}
Sau đây là triển khai giao diện trong Java:
interface Shape
{
void display();
double area();
}
class Rectangle implements Shape
{
int length, width;
Rectangle(int length, int width)
{
this.length = length;
this.width = width;
}
@Override
public void display()
{
System.out.println("****\n* *\n* *\n****");
}
@Override
public double area()
{
return (double)(length*width);
}
}
class Circle implements Shape
{
double pi = 3.14;
int radius;
Circle(int radius)
{
this.radius = radius;
}
@Override
public void display()
{
System.out.println("O"); // :P
}
@Override
public double area()
{
return (double)((pi*radius*radius)/2);
}
}
Một số điểm quan trọng trong một tóm tắt:
Các biến được khai báo trong giao diện Java theo mặc định là cuối cùng. Các lớp trừu tượng có thể có các biến không cuối cùng.
Các biến được khai báo trong giao diện Java theo mặc định là tĩnh. Các lớp trừu tượng có thể có các biến không tĩnh.
Các thành viên của giao diện Java được công khai theo mặc định. Một lớp trừu tượng Java có thể có các hương vị thông thường của các thành viên lớp như private, được bảo vệ, v.v.
Nhiều nhà phát triển cơ sở mắc sai lầm khi nghĩ về giao diện, các lớp trừu tượng và cụ thể là các biến thể nhỏ của cùng một thứ và chọn một trong số chúng hoàn toàn dựa trên cơ sở kỹ thuật: Tôi có cần nhiều kế thừa không? Tôi có cần một số nơi để đặt phương pháp phổ biến? Tôi có cần phải bận tâm với một cái gì đó ngoài một lớp học cụ thể không? Điều này là sai, và ẩn trong những câu hỏi này là vấn đề chính: "Tôi" . Khi bạn tự viết mã cho chính mình, bạn hiếm khi nghĩ đến các nhà phát triển hiện tại hoặc tương lai khác đang làm việc hoặc với mã của bạn.
Các giao diện và các lớp trừu tượng, mặc dù rõ ràng tương tự từ quan điểm kỹ thuật, có ý nghĩa và mục đích hoàn toàn khác nhau.
Một giao diện xác định một hợp đồng mà một số thực hiện sẽ thực hiện cho bạn .
Một lớp trừu tượng cung cấp một hành vi mặc định mà việc triển khai của bạn có thể sử dụng lại.
Một lớp cụ thể thực hiện công việc thực tế, theo một cách rất cụ thể. Ví dụ, một ArrayList
sử dụng một vùng bộ nhớ liền kề để lưu trữ một danh sách các đối tượng một cách gọn nhẹ, cho phép truy cập ngẫu nhiên, lặp lại và thay đổi tại chỗ nhanh chóng, nhưng rất tệ khi chèn, xóa và đôi khi cả bổ sung; trong khi đó, a LinkedList
sử dụng các nút được liên kết đôi để lưu trữ danh sách các đối tượng, thay vào đó cung cấp phép lặp nhanh, thay đổi tại chỗ và chèn / xóa / bổ sung, nhưng rất tệ khi truy cập ngẫu nhiên. Hai loại danh sách này được tối ưu hóa cho các trường hợp sử dụng khác nhau và vấn đề là bạn sẽ sử dụng chúng như thế nào. Khi bạn đang cố gắng loại bỏ hiệu suất khỏi danh sách mà bạn đang tương tác nhiều và khi chọn loại danh sách tùy thuộc vào bạn, bạn nên cẩn thận chọn danh sách nào bạn đang bắt đầu.
Mặt khác, những người dùng cấp cao của danh sách không thực sự quan tâm đến cách nó được thực hiện và họ nên được cách ly khỏi những chi tiết này. Chúng ta hãy tưởng tượng rằng Java đã không làm lộ List
giao diện, nhưng chỉ có một List
lớp cụ thể thực sự LinkedList
là ngay bây giờ. Tất cả các nhà phát triển Java sẽ điều chỉnh mã của họ để phù hợp với các chi tiết triển khai: tránh truy cập ngẫu nhiên, thêm bộ đệm để tăng tốc truy cập hoặc chỉ tự thực hiện lại ArrayList
, mặc dù nó không tương thích với tất cả các mã khác chỉ thực sự hoạt động List
. Điều đó thật tồi tệ ... Nhưng bây giờ hãy tưởng tượng rằng các bậc thầy Java thực sự nhận ra rằng một danh sách được liên kết là khủng khiếp đối với hầu hết các trường hợp sử dụng thực tế và đã quyết định chuyển sang một danh sách mảng cho riêng họList
lớp có sẵn. Điều này sẽ ảnh hưởng đến hiệu suất của mọi chương trình Java trên thế giới và mọi người sẽ không hài lòng về nó. Và thủ phạm chính là các chi tiết triển khai đã có sẵn và các nhà phát triển cho rằng những chi tiết đó là một hợp đồng vĩnh viễn mà họ có thể dựa vào. Đây là lý do tại sao việc ẩn các chi tiết triển khai và chỉ xác định một hợp đồng trừu tượng là rất quan trọng. Đây là mục đích của giao diện: xác định loại đầu vào mà phương thức chấp nhận và loại đầu ra nào được mong đợi, mà không để lộ tất cả các can đảm sẽ lập trình viên điều chỉnh mã của họ để phù hợp với các chi tiết bên trong có thể thay đổi với bất kỳ cập nhật nào trong tương lai .
Một lớp trừu tượng nằm ở giữa giữa các giao diện và các lớp cụ thể. Nó được cho là để giúp triển khai chia sẻ mã phổ biến hoặc nhàm chán. Ví dụ, AbstractCollection
cung cấp các triển khai cơ bản cho isEmpty
dựa trên kích thước là 0, contains
khi lặp và so sánh, addAll
như được lặp lại add
, v.v. Điều này cho phép triển khai tập trung vào các phần quan trọng phân biệt giữa chúng: cách thực sự lưu trữ và truy xuất dữ liệu.
Các giao diện là các cổng kết nối thấp giữa các phần khác nhau của mã. Chúng cho phép các thư viện tồn tại và phát triển mà không phá vỡ mọi người dùng thư viện khi có gì đó thay đổi bên trong. Nó được gọi là Giao diện lập trình ứng dụng , không phải các lớp lập trình ứng dụng. Ở quy mô nhỏ hơn, họ cũng cho phép nhiều nhà phát triển cộng tác thành công trên các dự án quy mô lớn, bằng cách tách các mô-đun khác nhau thông qua các giao diện được ghi chép tốt.
Các lớp trừu tượng là các trình trợ giúp gắn kết cao sẽ được sử dụng khi triển khai một giao diện, giả sử một số mức độ chi tiết thực hiện. Ngoài ra, các lớp trừu tượng được sử dụng để xác định SPI, Giao diện nhà cung cấp dịch vụ.
Sự khác biệt giữa API và SPI là tinh tế, nhưng quan trọng: đối với API, trọng tâm là người sử dụng nó và đối với SPI, trọng tâm là người thực hiện nó.
Việc thêm các phương thức vào API rất dễ dàng, tất cả người dùng API hiện tại vẫn sẽ biên dịch. Việc thêm các phương thức vào SPI rất khó, vì mọi nhà cung cấp dịch vụ (triển khai cụ thể) sẽ phải thực hiện các phương thức mới. Nếu các giao diện được sử dụng để xác định SPI, nhà cung cấp sẽ phải phát hành phiên bản mới bất cứ khi nào hợp đồng SPI thay đổi. Nếu các lớp trừu tượng được sử dụng thay thế, các phương thức mới có thể được định nghĩa theo các phương thức trừu tượng hiện có hoặc dưới dạng sơ throw not implemented exception
khai trống , ít nhất sẽ cho phép một phiên bản cũ hơn của việc triển khai dịch vụ vẫn biên dịch và chạy.
Mặc dù Java 8 đã giới thiệu các phương thức mặc định cho các giao diện, làm cho ranh giới giữa các giao diện và các lớp trừu tượng trở nên mờ hơn, nhưng điều này không phải để các triển khai có thể sử dụng lại mã, nhưng để dễ dàng thay đổi các giao diện phục vụ cả dưới dạng API và SPI (hoặc được sử dụng sai để xác định SPI thay vì các lớp trừu tượng).
Một hệ quả tất yếu: cách khác xung quanh thường được thực hiện sai: khi sử dụng một thứ , luôn cố gắng sử dụng lớp / giao diện chung nhất mà bạn thực sự cần. Nói cách khác, đừng khai báo các biến của bạn ArrayList theList = new ArrayList()
, trừ khi bạn thực sự có một sự phụ thuộc rất lớn vào nó là một danh sách mảng và không có loại danh sách nào khác sẽ cắt nó cho bạn. Sử dụng List theList = new ArrayList
thay thế, hoặc thậm chí Collection theCollection = new ArrayList
nếu thực tế đó là một danh sách, và không phải bất kỳ loại bộ sưu tập nào khác không thực sự quan trọng.
Không thực sự là câu trả lời cho câu hỏi ban đầu, nhưng một khi bạn có câu trả lời cho sự khác biệt giữa chúng, bạn sẽ nhập vào tình huống khó xử khi sử dụng mỗi khi : Khi nào nên sử dụng giao diện hoặc các lớp trừu tượng? Khi nào sử dụng cả hai?
Tôi đã giới hạn kiến thức về OOP, nhưng xem các giao diện tương đương với tính từ trong ngữ pháp đã có hiệu quả với tôi cho đến bây giờ (sửa cho tôi nếu phương pháp này không có thật!). Ví dụ: tên giao diện giống như các thuộc tính hoặc khả năng bạn có thể cung cấp cho một lớp và một lớp có thể có nhiều trong số chúng: ISerializable, ICountable, IList, ICachizable, IHappy, ...
Kế thừa được sử dụng cho hai mục đích:
Để cho phép một đối tượng coi các thành viên dữ liệu kiểu cha mẹ và các cài đặt phương thức là của chính nó.
Để cho phép tham chiếu đến một đối tượng thuộc một loại được sử dụng bởi mã, dự kiến tham chiếu đến đối tượng siêu kiểu.
Trong các ngôn ngữ / khung hỗ trợ đa kế thừa, thường không cần phải phân loại một loại là "giao diện" hoặc "lớp trừu tượng". Tuy nhiên, các ngôn ngữ và khung phổ biến sẽ cho phép một loại coi các thành viên dữ liệu của một loại khác hoặc việc triển khai phương thức là chính nó mặc dù chúng cho phép một loại có thể thay thế cho một số loại khác tùy ý.
Các lớp trừu tượng có thể có các thành viên dữ liệu và triển khai phương thức, nhưng chỉ có thể được kế thừa bởi các lớp không kế thừa từ bất kỳ lớp nào khác. Các giao diện đặt hầu như không có hạn chế nào đối với các kiểu triển khai chúng, nhưng không thể bao gồm bất kỳ thành viên dữ liệu hoặc triển khai phương thức nào.
Có những lúc nó hữu ích cho các loại có thể thay thế cho nhiều thứ khác nhau; có những lúc khác, nó hữu ích cho các đối tượng coi các thành viên dữ liệu kiểu cha mẹ và việc triển khai phương thức là của riêng họ. Việc phân biệt giữa các giao diện và các lớp trừu tượng cho phép mỗi khả năng đó được sử dụng trong trường hợp có liên quan nhất.
Những điểm chính:
Lợi thế:
tìm thông tin chi tiết tại đây ... http://pradeepatkari.wordpress.com/2014/11/20/interface-and-abauge- class-in-c-oops /
Cách ngắn nhất để tóm tắt interface
là:
default
và static
phương pháp; trong khi nó có định nghĩa (chữ ký phương thức + triển khai) cho default
và static
phương thức, nó chỉ có khai báo (chữ ký phương thức) cho các phương thức khác.interface
s và một interface
có thể kế thừa từ nhiều interface
s). Tất cả các biến là ngầm định, cho dù được chỉ định là public static final
hay không. Tất cả các thành viên đều mặc nhiên public
, cho dù được chỉ định như vậy hay không.Trong khi đó, một abstract
lớp học là:
abstract
phương pháp. Có thể chứa cả khai báo và định nghĩa, với khai báo được đánh dấu là abstract
.protected
, private
hoặc gói tin (không xác định).Hoặc, nếu chúng ta muốn đun sôi tất cả thành một câu duy nhất: An interface
là thứ mà lớp triển khai có , nhưng một abstract
lớp là lớp con là gì .
Tôi muốn thêm một sự khác biệt có ý nghĩa. Ví dụ, bạn có một khung với hàng ngàn dòng mã. Bây giờ nếu bạn muốn thêm một tính năng mới trong toàn bộ mã bằng cách sử dụng phương thức boostUI (), thì tốt hơn là thêm phương thức đó vào lớp trừu tượng thay vì trong giao diện. Bởi vì, nếu bạn thêm phương thức này trong một giao diện thì bạn nên triển khai nó trong tất cả các lớp đã triển khai nhưng không phải là trường hợp nếu bạn thêm phương thức trong lớp trừu tượng.
Để đưa ra một câu trả lời đơn giản nhưng rõ ràng, nó giúp đặt bối cảnh: bạn sử dụng cả hai khi bạn không muốn cung cấp các triển khai đầy đủ.
Sự khác biệt chính sau đó là một giao diện hoàn toàn không có triển khai (chỉ có các phương thức không có phần thân) trong khi các lớp trừu tượng cũng có thể có các thành viên và các phương thức với phần thân, tức là có thể được thực hiện một phần.
default
từ khóa trong Java 8 mà bạn có thể định nghĩa các phương thức cụ thể trong các giao diện.
Sự khác biệt giữa lớp trừu tượng và giao diện thay mặt cho việc thực hiện thực sự.
Giao diện : Nó là một từ khóa và nó được sử dụng để xác định mẫu hoặc bản in màu xanh của một đối tượng và nó buộc tất cả các lớp con sẽ tuân theo cùng một nguyên mẫu, như đối với việc triển khai, tất cả các lớp con đều được tự do thực hiện chức năng theo đó là yêu cầu.
Một số trường hợp sử dụng khác mà chúng ta nên sử dụng giao diện.
Giao tiếp giữa hai đối tượng bên ngoài (Tích hợp bên thứ ba trong ứng dụng của chúng tôi) được thực hiện thông qua Giao diện tại đây Giao diện hoạt động như Hợp đồng.
Lớp trừu tượng: Tóm tắt, đó là một từ khóa và khi chúng ta sử dụng từ khóa này trước bất kỳ lớp nào thì nó sẽ trở thành lớp trừu tượng. Nó chủ yếu được sử dụng khi chúng ta cần xác định mẫu cũng như một số chức năng mặc định của một đối tượng được theo sau bởi tất cả các lớp con và theo cách này nó loại bỏ mã dự phòng và thêm một trường hợp sử dụng mà chúng ta có thể sử dụng lớp trừu tượng , như chúng ta muốn không có lớp nào khác có thể trực tiếp khởi tạo một đối tượng của lớp, chỉ các lớp dẫn xuất mới có thể sử dụng chức năng.
Ví dụ về lớp trừu tượng:
public abstract class DesireCar
{
//It is an abstract method that defines the prototype.
public abstract void Color();
// It is a default implementation of a Wheel method as all the desire cars have the same no. of wheels.
// and hence no need to define this in all the sub classes in this way it saves the code duplicasy
public void Wheel() {
Console.WriteLine("Car has four wheel");
}
}
**Here is the sub classes:**
public class DesireCar1 : DesireCar
{
public override void Color()
{
Console.WriteLine("This is a red color Desire car");
}
}
public class DesireCar2 : DesireCar
{
public override void Color()
{
Console.WriteLine("This is a red white Desire car");
}
}
Ví dụ về giao diện:
public interface IShape
{
// Defines the prototype(template)
void Draw();
}
// All the sub classes follow the same template but implementation can be different.
public class Circle : IShape
{
public void Draw()
{
Console.WriteLine("This is a Circle");
}
}
public class Rectangle : IShape
{
public void Draw()
{
Console.WriteLine("This is a Rectangle");
}
}
Bạn có thể tìm thấy sự khác biệt rõ ràng giữa giao diện và lớp trừu tượng.
Giao diện
Lớp trừu tượng
Lớp trừu tượng chứa các phương thức trừu tượng và không trừu tượng.
Không bắt buộc người dùng phải thực hiện tất cả các phương thức khi kế thừa lớp trừu tượng.
Chứa tất cả các loại biến bao gồm nguyên thủy và không nguyên thủy
Khai báo sử dụng từ khóa trừu tượng.
Các phương thức và thành viên của một lớp trừu tượng có thể được định nghĩa với bất kỳ khả năng hiển thị nào.
Một lớp con chỉ có thể mở rộng một lớp duy nhất (trừu tượng hoặc cụ thể).
Một lớp trừu tượng là một lớp mà đối tượng không thể được tạo hoặc một lớp không thể khởi tạo được. Một phương thức trừu tượng làm cho một lớp trừu tượng. Một lớp trừu tượng cần được kế thừa để ghi đè các phương thức được khai báo trong lớp trừu tượng. Không có giới hạn về chỉ định truy cập. Một lớp trừu tượng có thể có hàm tạo và các phương thức cụ thể (không phải phương thức abstarct) trong chúng nhưng giao diện không thể có.
Giao diện là một bản thiết kế / mẫu của các phương thức (ví dụ: Một ngôi nhà trên một tờ giấy được đưa ra (nhà giao diện) và các kiến trúc sư khác nhau sẽ sử dụng ý tưởng của họ để xây dựng nó (các lớp kiến trúc sư thực hiện giao diện ngôi nhà). Các phương thức trừu tượng, phương thức mặc định, phương thức tĩnh, biến cuối cùng và các lớp lồng nhau. Tất cả các thành viên sẽ là các chỉ định truy cập cuối cùng hoặc công khai, được bảo vệ và riêng tư không được phép. Không được phép tạo đối tượng. Giao diện triển khai và cũng để ghi đè phương thức trừu tượng được khai báo trong giao diện. Giao diện là một ví dụ điển hình về khớp nối lỏng lẻo (đa hình động / liên kết động) Một giao diện thực hiện đa hình và trừu tượng. Nó cho biết phải làm gì nhưng cách làm được xác định bởi lớp thực hiện. Ví dụ: Có 'Một công ty xe hơi và họ muốn một số tính năng giống với tất cả các xe mà nó đang sản xuất để công ty sẽ chế tạo một chiếc xe giao diện có các tính năng đó và các loại xe khác nhau (như Maruti Suzkhi, Maruti 800) sẽ ghi đè những tính năng (chức năng).
Tại sao giao diện khi chúng ta đã có lớp trừu tượng? Java chỉ hỗ trợ kế thừa đa cấp và phân cấp nhưng với sự trợ giúp của giao diện, chúng ta có thể thực hiện nhiều kế thừa.
Về mặt thực tiễn (JAVA), sự khác biệt chính giữa lớp trừu tượng và giao diện là lớp Trừu tượng có thể giữ trạng thái. Ngoài trạng thái giữ, chúng ta có thể đạt được các thao tác nghỉ với Giao diện.
Trong một giao diện, tất cả các phương thức phải chỉ là các định nghĩa, không nên thực hiện một phương thức duy nhất.
Nhưng trong một lớp trừu tượng phải có một phương thức trừu tượng chỉ có định nghĩa, nhưng các phương thức khác cũng có thể nằm trong lớp trừu tượng có triển khai ...
Chúng tôi có sự khác biệt về cấu trúc / cú pháp giữa giao diện và lớp trừu tượng. Một số khác biệt nữa là
[1] Sự khác biệt dựa trên kịch bản :
Các lớp trừu tượng được sử dụng trong các kịch bản khi chúng tôi muốn hạn chế người dùng tạo đối tượng của lớp cha VÀ chúng tôi tin rằng sẽ có nhiều phương thức trừu tượng hơn sẽ được thêm vào trong tương lai.
Giao diện phải được sử dụng khi chúng tôi chắc chắn không thể cung cấp thêm phương thức trừu tượng nào nữa. Sau đó, chỉ có một giao diện được công bố.
[2] Sự khác biệt về khái niệm :
"Chúng ta có cần cung cấp các phương thức trừu tượng hơn trong tương lai không" nếu CÓ làm cho nó trở thành lớp trừu tượng và nếu KHÔNG làm cho nó Giao diện.
(Thích hợp nhất và hợp lệ cho đến java 1.7)
thường lớp Trừu tượng được sử dụng cho cốt lõi của một cái gì đó nhưng giao diện được sử dụng để nối thêm thiết bị ngoại vi.
Khi bạn muốn tạo loại cơ sở cho phương tiện, bạn nên sử dụng lớp trừu tượng nhưng nếu bạn muốn thêm một số chức năng hoặc thuộc tính không phải là một phần của khái niệm cơ sở về phương tiện, bạn nên sử dụng giao diện, ví dụ: bạn muốn thêm chức năng "ToJSON ()" .
Giao diện có phạm vi trừu tượng rộng hơn là lớp trừu tượng. bạn có thể thấy điều này khi truyền đối số. xem ví dụ này:
nếu bạn sử dụng phương tiện làm đối số, bạn chỉ có thể sử dụng một trong các loại dẫn xuất của nó (loại xe buýt hoặc xe cùng loại - chỉ loại xe). nhưng khi bạn sử dụng giao diện IMovizable làm đối số, bạn có nhiều lựa chọn hơn.