2008-11-27 40 views

Trả lời

20

Các lớp trừu tượng được sử dụng khi bạn không có ý định tạo ra một lớp bê tông, nhưng muốn chắc chắn rằng có một số chung nhà nước trong tất cả các lớp con hoặc có thể thực hiện chung đối với một số hoạt động.

Giao diện không được chứa.

+0

Tôi sẽ tiếp tục xác định giao diện, ngay cả khi xác định lớp trừu tượng. Nó làm cho mã của bạn thêm thử nghiệm thân thiện và ít kết hợp với một triển khai cụ thể. – tvanfosson

+0

Có, tất nhiên, tôi đồng ý 100%. Trong mã của tôi, tôi thường đưa ra giao diện cho giao diện (có vẻ ngớ ngẩn) và sử dụng lớp trừu tượng làm cơ sở cho việc triển khai và trạng thái chuẩn. – Uri

+0

Bạn đã nói: "và sử dụng lớp trừu tượng làm cơ sở để triển khai chuẩn và tiểu bang Bạn có thể là: " và sử dụng lớp trừu tượng làm cơ sở cho "triển khai chung" và trạng thái " – Shaw

4

Giao diện v/s lớp trừu tượng là một chủ đề tạo ra rất nhiều sự tò mò/quan tâm/nhầm lẫn đối với bất kỳ ai mới sử dụng Java và muốn đào sâu hơn.

This article cung cấp giải thích chi tiết về chủ đề.

+0

Liên kết bạn cung cấp rất hữu ích. Nó đã sử dụng rõ ràng cả giao diện trừu tượng lẫn giao diện. – Warrior

8

Có, có nơi dành cho cả lớp và giao diện trừu tượng.

Hãy cùng với một ví dụ cụ thể. Chúng tôi sẽ xem xét cách tạo một CheckingAccountSavingsAccount từ tóm tắt AbstractBankAccount và xem cách chúng tôi có thể sử dụng giao diện phân biệt hai loại tài khoản.

Để bắt đầu, đây là một lớp trừu tượng AbstractBankAccount:

abstract class AbstractBankAccount 
{ 
    int balance; 
    public abstract void deposit(int amount); 
    public abstract void withdraw(int amount); 
} 

Chúng tôi có số dư tài khoản như balance và hai phương pháp depositwithdraw đó phải được thực hiện bởi lớp con.

Như chúng ta có thể thấy, lớp trừu tượng tuyên bố cấu trúc về cách xác định tài khoản ngân hàng. Như @Uri đề cập đến trong phản hồi của mình, có một trạng thái cho lớp trừu tượng này, là trường balance. Điều này sẽ không thể với một giao diện.

Bây giờ, chúng ta hãy lớp con AbstractBankAccount để thực hiện một CheckingAccount

class CheckingAccount extends AbstractBankAccount 
{ 
    public void deposit(int amount) 
    { 
     balance += amount; 
    } 

    public void withdraw(int amount) 
    { 
     balance -= amount; 
    } 
} 

Trong lớp con này CheckingAccount, chúng tôi thực hiện hai lớp trừu tượng - không có gì quá thú vị ở đây.

Bây giờ, làm cách nào chúng tôi có thể triển khai SavingsAccount? Nó khác với CheckingAccount ở chỗ nó sẽ thu được sự quan tâm. Tiền lãi có thể được tăng lên bằng cách sử dụng phương thức deposit, nhưng sau đó một lần nữa, nó không giống như là khách hàng đang gửi tiền lãi cho họ. Do đó, có thể rõ ràng hơn nếu chúng tôi có một phương tiện khác để thêm tiền vào tài khoản, cụ thể là lãi suất, ví dụ: phương thức accrueInterest.

Chúng ta có thể trực tiếp thực hiện phương pháp này trong SavingsAccount, nhưng chúng ta có thể có nhiều loại tài khoản ngân hàng có thể cộng dồn lãi suất trong tương lai, vì vậy chúng tôi có thể muốn thực hiện một giao diện InterestBearing rằng có accrueInterest phương pháp:

interface InterestBearing 
{ 
    public void accrueInterest(int amount); 
} 

Vì vậy, bây giờ chúng ta có thể làm cho một lớp SavingsAccount rằng có thể đạt được lợi ích bằng cách thực hiện các giao diện InterestBearing:

class SavingsAccount extends AbstractBankAccount implements InterestBearing 
{ 
    public void deposit(int amount) 
    { 
     balance += amount; 
    } 

    public void withdraw(int amount) 
    { 
     balance -= amount; 
    } 

    public void accrueInterest(int amount) 
    { 
     balance += amount; 
    } 
} 

Bây giờ, nếu chúng ta muốn thực hiện anothe loại tài khoản, giả sử là PremiumSavingsAccount, chúng tôi có thể tạo một lớp con của AbstractBankAccount và triển khai giao diện InterestBearing để tạo một tài khoản mang lãi khác.

Giao diện InterestBearing có thể được xem là thêm tính năng phổ biến vào các lớp khác nhau. Nó sẽ không có ý nghĩa để có một tính năng để đối phó với lãi suất trong một tài khoản kiểm tra khi nó không tích lũy bất kỳ quan tâm.

Vì vậy, có những nơi thực sự cho cả lớp trừu tượng và giao diện cùng tồn tại và làm việc cùng nhau trong một tình huống.

0

Nhìn chung, giao diện mô tả các API công cộng mà code của bạn nên sử dụng, trong khi các lớp cơ sở trừu tượng được lưu giữ tốt nhất như là một chi tiết thực hiện, nơi mà mã hoặc trạng thái chung có thể được giữ lại, để giảm trùng lặp trong bất kỳ lớp thực hiện nào.

Bằng cách sử dụng giao diện trong API, mọi người (bao gồm cả bạn) viết mã thử nghiệm dễ dàng hơn đối với lớp học của bạn, vì bạn có thể sử dụng các lớp thử nghiệm, chẳng hạn, không phụ thuộc vào bất kỳ tài nguyên bên ngoài nào thể hiện các loại hành vi xấu nhưng khó mô phỏng trong cuộc sống thực.

Vì vậy, java cung cấp giao diện List, và các lớp cơ sở trừu tượng AbstractList để "giảm thiểu những nỗ lực cần thiết để thực hiện" giao diện ...

2

Có một vài lý do khiến bạn có thể thích một lớp trừu tượng thực hiện miễn phí qua giao diện:

  • Một số phôi và thao tác mẫu không thể nhất định có thể bị bắt tại thời gian biên dịch.
  • Bạn có tùy chọn thêm các phương thức cụ thể trong phiên bản sau.
  • Đã từng là một lợi ích hiệu suất đáng kể từ nhiều năm trước.
  • Từ góc độ bảo mật tối nghĩa, bạn không thể có được một lớp đã tồn tại trước đó để triển khai các phương thức bằng cách tạo một lớp con của lớp đã tồn tại từ trước và lớp trừu tượng.

Nhưng mặt khác, từ khóa Java giao diện cho phép nguồn sạch hơn.

+0

Cảm ơn bạn.Bạn đã cho tôi những ý tưởng có giá trị trong truy vấn của tôi. – Warrior

Các vấn đề liên quan