Sự khác biệt giữa các lớp trừu tượng, giao diện và khi nào sử dụng chúng


15

Gần đây tôi đã bắt đầu quấn đầu quanh OOP, và bây giờ tôi đến mức càng đọc về sự khác biệt giữa các lớp trừu tượng và giao diện, tôi càng trở nên bối rối. Cho đến nay, không thể được khởi tạo. Các giao diện là các bản thiết kế cấu trúc ít nhiều có cấu trúc xác định bộ xương và tóm tắt khác nhau bằng cách có thể thực hiện một phần mã.

Tôi muốn tìm hiểu thêm về những điều này thông qua tình huống cụ thể của tôi. Đây là một liên kết đến câu hỏi đầu tiên của tôi nếu bạn muốn biết thêm một chút thông tin cơ bản: mô hình thiết kế tốt cho lớp mới của tôi là gì?

Đây là hai lớp tôi đã tạo:

class Ad {
    $title;
    $description
    $price;

    function get_data($website){  }

    function validate_price(){  }
 }


class calendar_event {
    $title;
    $description

    $start_date;

    function get_data($website){ //guts }

    function validate_dates(){ //guts }
 }

Vì vậy, như bạn có thể thấy các lớp này gần như giống hệt nhau. Không được hiển thị ở đây, nhưng có những chức năng khác, like get_zip(), save_to_database()được phổ biến trên khắp các lớp học của tôi. Tôi cũng đã thêm các lớp khác Ô tô và Thú cưng có tất cả các phương thức phổ biến và tất nhiên các thuộc tính dành riêng cho các lớp đó (ví dụ như số dặm, trọng lượng).

Bây giờ tôi đã vi phạm nguyên tắc DRY và tôi đang quản lý và thay đổi cùng một mã trên nhiều tệp. Tôi dự định sẽ có nhiều lớp học hơn như thuyền, ngựa, hoặc bất cứ điều gì.

Vì vậy, đây là nơi tôi sẽ sử dụng một giao diện hoặc một lớp trừu tượng? Từ những gì tôi hiểu về các lớp trừu tượng, tôi sẽ sử dụng một siêu lớp làm mẫu với tất cả các phần tử phổ biến được xây dựng trong lớp trừu tượng, và sau đó chỉ thêm các mục cần thiết đặc biệt trong các lớp trong tương lai. Ví dụ:

abstract class content {
    $title;
    $description


    function get_data($website){  }

    function common_function2() { }
    function common_function3() { }
 }


class calendar_event extends content {

    $start_date;

    function validate_dates(){  }
 }

Hoặc tôi sẽ sử dụng một giao diện và, vì chúng rất giống nhau, tạo ra một cấu trúc mà mỗi lớp con bị buộc phải sử dụng vì lý do toàn vẹn và để cho nhà phát triển cuối cùng tìm ra lớp đó chịu trách nhiệm cho từng lớp chi tiết của các chức năng phổ biến. Tôi nghĩ rằng có một số chức năng 'phổ biến' có thể cần phải được điều chỉnh trong tương lai cho các nhu cầu của lớp cụ thể của chúng.

Bất chấp tất cả những điều trên, nếu bạn tin rằng tôi đang hiểu sai về lý do và lý do của các lớp và giao diện trừu tượng hoàn toàn, bằng mọi cách hãy để một câu trả lời hợp lệ ngừng suy nghĩ theo hướng này và đề xuất cách thích hợp để tiến về phía trước!

Cảm ơn!


Có rất nhiều ví dụ hay trên mạng. Tôi nghĩ rằng đây là một trong số họ. javapapers.com/core-java/abstract-and-interface-core-java-2/...
Siva

Câu trả lời:


26

Trong điều khoản của Giáo dân:

Các giao diện dành cho loại mối quan hệ "có thể làm / có thể được coi là" .

Các lớp trừu tượng (cũng như cụ thể) dành cho "là một loại " mối quan hệ.

Hãy xem những ví dụ này:

class Bird extends Animal implements Flight;
class Plane extends Vehicle implements Flight, AccountableAsset;
class Mosquito extends Animal implements Flight;
class Horse extends Animal;
class RaceHorse extends Horse implements AccountableAsset;
class Pegasus extends Horse implements Flight;

Bird, MosquitoHorse Animals . Họ có liên quan tới nhau. Họ thừa hưởng các phương pháp phổ biến từ Động vật như thế nào eat(), metabolize() and reproduce(). Có thể họ ghi đè các phương thức này, thêm một chút vào chúng, nhưng chúng tận dụng hành vi mặc định được triển khai trong Animal nhưmetabolizeGlucose().

Planekhông liên quan đến Bird, Mosquitohoặc Horse.

Flightđược thực hiện bởi các lớp không giống nhau, không liên quan, như BirdPlane.

AccountableAssetcũng được thực hiện bởi các lớp không giống nhau, không liên quan, như PlaneRaceHorse.

Horse không thực hiện chuyến bay.

Như bạn có thể thấy các lớp (trừu tượng hoặc cụ thể) giúp bạn xây dựng một hệ thống phân cấp , cho phép bạn hít mã từ các cấp cao hơn đến các cấp thấp hơn của hệ thống phân cấp. Về lý thuyết, bạn càng thấp trong hệ thống phân cấp, hành vi của bạn càng chuyên sâu, nhưng bạn không phải lo lắng về rất nhiều điều đã được quan tâm.

Mặt khác, các giao diện không tạo ra hệ thống phân cấp, nhưng chúng có thể giúp đồng nhất hóa các hành vi nhất định trên các hệ thống phân cấp để bạn có thể trừu tượng chúng khỏi hệ thống phân cấp trong các ngữ cảnh nhất định.

Ví dụ, bạn có thể có một chương trình tổng giá trị của một nhóm AccountableAssetsbất kể chúng là RaceHorseshay Planes.


Kinh ngạc. Giao diện cung cấp một phần chức năng nhất định trong đó áp đặt can do/can be treated ascác lớp trừu tượng đóng vai trò nền tảng!
Abhiroj Panwar

13

Bạn có thể suy luận câu trả lời một cách logic vì dường như bạn nhận thức được sự khác biệt giữa hai điều này.

Giao diện xác định một hợp đồng chung. Chẳng hạn như một giao diện được gọi là IAnimal, trong đó tất cả các động vật chia sẻ các chức năng như Eat (), Move (), Attack (), v.v. nó

Các lớp trừu tượng định nghĩa một triển khai chung và các hợp đồng chung tùy chọn. Ví dụ, một Máy tính đơn giản có thể đủ điều kiện là một lớp trừu tượng thực hiện tất cả các toán tử logic và bitwise cơ bản và sau đó được mở rộng bởi ScienceCalculator, GraphicalCalculator, v.v.

Nếu bạn có triển khai chung thì bằng mọi cách, hãy gói gọn chức năng trong một lớp trừu tượng để mở rộng từ đó. Tôi có gần 0 kinh nghiệm PHP, nhưng tôi không nghĩ bạn có thể tạo giao diện với các trường không đổi. Nếu các trường là phổ biến giữa các lớp cá thể của bạn thì bạn buộc phải sử dụng một lớp Trừu tượng, trừ khi bạn xác định quyền truy cập vào chúng thông qua getters và setters.

Ngoài ra, dường như không thiếu kết quả trong Google.


3

Mẩu chuyện dài. Các lớp trừu tượng rất giống Giao diện ở chỗ cả hai đều cung cấp một khuôn mẫu về các phương thức nên có trong lớp kế thừa, nhưng có những khác biệt lớn: - Các giao diện chỉ xác định tên / loại phương thức cần tồn tại trong một lớp kế thừa, trong khi abs- các lớp có thể có mã phương thức mặc định hoàn chỉnh và chỉ các chi tiết có thể cần phải được sử dụng quá mức. - Giao diện không thể có sửa đổi truy cập. - Giao diện không thể có các trường. - Các lớp không thể có nhiều kế thừa của các lớp, trong khi chúng có thể kế thừa nhiều giao diện. - Ngoài ra, các lớp cung cấp một cấu trúc phân cấp để chỉ các lớp xuất phát từ một lớp cụ thể cần tuân theo các hướng dẫn của lớp trừu tượng: object-> object object-> object rất cụ thể. Mặt khác, giao diện có thể được kế thừa bởi bất cứ ai.

Theo tôi, các lớp trừu tượng phổ biến hơn ở chỗ chúng có thể cung cấp triển khai mã mặc định ngay lập tức, nhưng trong các dự án quy mô lớn, nơi bạn cần chuẩn hóa một số lớp nhất định, các giao diện có thể có ích.

Hy vọng điều đó có ích, nhưng có rất nhiều thông tin trên mạng này, Leo


2
Classes cannot have multiple inheritance- Đúng với các ngôn ngữ như Java và C #, không đúng với C ++.
Robert Harvey

3

Trước hết, bạn nên hiểu rằng bạn sẽ thường cung cấp cả giao diện và lớp trừu tượng. Lý do cho điều này, và sự khác biệt cốt lõi giữa hai điều này là vì chúng cho phép bạn sử dụng lại mã khác nhau và do đó giải quyết các vấn đề khác nhau.

Các giao diện cho phép bạn sử dụng lại mã máy khách với các cài đặt khác nhau. Một khách hàng của lớp get_data ($ website) của bạn không quan tâm đến các mục $ title hoặc $ mô tả. Nó chỉ muốn hướng dẫn nội dung của bạn để tải dữ liệu. Nếu bạn có các loại nội dung khác nhau, một số trong đó cần mô tả $ và một số không có, bạn có thể cung cấp lớp ContentInterface chỉ xác định chữ ký của các lớp con của bạn. Bây giờ khách hàng có thể có bất kỳ số lượng Nội dung khác nhau mà không cần biết chính xác cách họ làm việc. Các Liskov Substitution Nguyên tắc là một điều tốt để đọc về để nghiên cứu ý tưởng này. Tôi cũng thích bài viết của chú Bob về chủ đề này. Các giao diện rất quan trọng đối với thử nghiệm đơn vị và tạo giao diện là một thói quen tốt để tìm hiểu.

Các lớp trừu tượng cho phép bạn sử dụng lại các chi tiết triển khai chung trên một tập hợp các lớp có chung một tổ tiên chung. Trong câu hỏi của bạn, bạn dường như có một xử lý tốt về lý do tại sao bạn sẽ kế thừa việc thực hiện từ một lớp trừu tượng. Vẫn còn nguy hiểm khi phụ thuộc vào nội bộ của lớp cơ sở - rất dễ vi phạm đóng gói và tạo ra những đứa trẻ phụ thuộc vào chi tiết thực hiện cụ thể của lớp cơ sở. Các mẫu Template Method cung cấp một ví dụ phổ biến và khỏe mạnh về cách sử dụng các lớp cơ sở mà không vi phạm đóng gói.

Vì vậy, như tôi hy vọng tôi đã trình bày, bạn sẽ thường cung cấp giao diện cho các máy khách của hệ thống phân cấp lớp của bạn, để bạn có thể thay đổi việc triển khai của mình một cách an toàn mà không ảnh hưởng đến mã máy khách. Điều này cho phép khách hàng viết các bài kiểm tra đơn vị bằng cách sử dụng Mock Object kế thừa giao diện của bạn. Và bạn cũng sẽ cung cấp các lớp trừu tượng cho phép sử dụng lại logic thông thường hoặc thực thi ngữ nghĩa cho các lớp con.


3

Sự khác biệt là tinh tế nhưng là một rõ ràng. Giao diện là về hành vi đa hình. Lớp trừu tượng là về tái sử dụng và hành vi đa hình.

Nếu bạn muốn nhấn mạnh vào hành vi tái sử dụng và đa hình, hãy chọn lớp trừu tượng. Ví dụ, các loại nhân viên khác nhau có các quy định khác nhau nhưng tất cả đều nhận được một vài điểm chung. Vì vậy, lớp trừu tượng phù hợp để đại diện cho nó bởi vì sự tương đồng có thể được thể hiện trong một lớp trừu tượng cơ sở Employeevà sự khác biệt có thể được thực hiện trong các lớp dẫn xuất như Managerhoặc Workerv.v.

Nếu bạn muốn nhấn mạnh chỉ hành vi đa hình, chọn giao diện. Giao diện là nhiều hơn về hợp đồng, tức là một đối tượng hoặc hệ thống phân cấp nói rằng nó phù hợp với hành vi nhất định. Ví dụ, tất cả nhân viên đã nghỉ việc nhưng các loại nhân viên khác nhau có các loại điều khoản khác nhau. Vì vậy, mỗi loại nhân viên khác nhau đòi hỏi một máy tính nghỉ phép khác nhau. Ở đây giao diện là một lựa chọn tốt vì tất cả các loại nhân viên có thể thực hiện một LeaveCalculatorgiao diện với Calculate()hành vi khác nhau.


-3
  1. Sự khác biệt chính là các phương thức của một 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. Các 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. 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ư riêng tư, được bảo vệ, v.v.
  4. Giao diện Java nên được triển khai bằng cách sử dụng từ khóa mà 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 có thể mở rộng một giao diện Java khác, chỉ 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. Giao diện hoàn toàn trừu tượng và không thể khởi tạo được; 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.
  9. Giao diện và lớp trừu tượng trong Java là bạn không thể tạo phương thức không trừu tượng trong giao diện, mọi phương thức trong giao diện theo mặc định là trừu tượng, nhưng bạn có thể tạo phương thức không trừu tượng trong lớp trừu tượng.
  10. Lớp trừu tượng so với giao diện trong Java là, các giao diện phù hợp hơn với khai báo Kiểu và lớp trừu tượng phù hợp hơn cho việc tái sử dụng mã và phối cảnh tiến hóa.
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.