2010-09-23 41 views
5

Tôi sử dụng Scanner class để đọc nhiều tệp tương tự. Tôi muốn mở rộng nó để đảm bảo tất cả họ đều sử dụng cùng một dấu tách và tôi cũng có thể thêm các phương thức như skipUntilYouFind (String thisHere) tất cả đều hợp lệ cho tất cả.Tại sao lớp java.util.Scanner được khai báo là 'cuối cùng'?

Tôi có thể tạo lớp tiện ích có chứa chúng hoặc nhúng Lớp Máy quét dưới dạng biến trong lớp khác nhưng điều này phức tạp hơn.

Tôi đã tìm thấy some reasons để khai báo lớp học cuối cùng, nhưng tại sao nó lại được thực hiện ở đây?

+0

Nếu điều này liên quan đến hiệu suất, liệu lý thuyết có thể tạo Máy quét không hoạt động có thể mở rộng được không? Logic của tôi nói rằng nó nên được? – Roalt

Trả lời

4

Có lẽ vì việc mở rộng và ghi đè một số phương pháp của nó có thể sẽ phá vỡ nó. Và làm cho nó dễ dàng hơn để ghi đè lên các phương thức sẽ cho thấy nhiều hoạt động bên trong, vì vậy nếu trong tương lai họ quyết định thay đổi chúng (vì hiệu suất hoặc một số lý do khác), sẽ khó thay đổi lớp mà không phá vỡ tất cả các lớp mở rộng nó.

Ví dụ, hãy xem xét các phương pháp sau đây trong lớp:

public boolean nextBoolean() { 
    clearCaches(); 
    return Boolean.parseBoolean(next(boolPattern())); 
} 

Giả sử bạn muốn ghi đè lên điều này bởi vì bạn muốn chắc 'tuyệt vời' đánh giá để một boolean 'true' (vì lý do gì). Nếu bạn ghi đè lên nó, bạn không thể gọi super.nextBoolean(), vì điều đó sẽ tiêu thụ mã thông báo tiếp theo bằng cách sử dụng logic mặc định. Nhưng nếu bạn không gọi super.nextBoolean(), clearCaches() sẽ không được gọi, có thể phá vỡ các phương thức không ghi đè khác. Bạn không thể gọi clearCaches() vì nó là riêng tư. Nếu họ làm cho nó được bảo vệ, nhưng sau đó nhận ra rằng nó gây ra một vấn đề hiệu suất, và muốn có một thực hiện mới mà không xóa cache nữa, sau đó họ có thể phá vỡ thực hiện ghi đè của bạn mà vẫn sẽ được gọi đó. Vì vậy, về cơ bản nó là để họ có thể dễ dàng thay đổi các phần ẩn bên trong lớp, khá phức tạp và bảo vệ bạn khỏi việc tạo ra một lớp con bị hỏng (hoặc một lớp có thể dễ dàng bị phá vỡ).

+0

Điều đó sẽ giải thích tại sao hàm nextBoolean phải được định nghĩa là 'boolean công thức cuối cùng nextBoolean()', không phải toàn bộ lớp? – Roalt

+0

Vâng, nhưng bạn có thể có một phương thức không có clearCaches() trong đó, và nó không được khai báo cuối cùng, nhưng chúng nhận ra rằng chúng cần thêm clearCaches() ở đó, nhưng bây giờ chúng không thể khai báo nó (vì nó sẽ phá vỡ các lớp mở rộng nó).Và rất nhiều (nếu không phải tất cả các phương pháp) dựa nhiều vào việc thực hiện ẩn anyway (rất nhiều trong số họ sẽ phải được cuối cùng từ đầu). Nó dễ dàng hơn, và có ý nghĩa hơn để khai báo toàn bộ điều cuối cùng (vì các phần cần phải là cuối cùng có thể thay đổi khi thay đổi việc thực thi bên trong). –

+1

Bởi logic này, mọi thứ nên là một lớp cuối cùng. Tôi không thể tin rằng đây là lý do. – corsiKa

0

Tôi nghĩ rằng liên kết bạn cung cấp sẽ giải thích tất cả.

Trong trường hợp của bạn, có vẻ như bạn nên chọn bố cục thay vì thừa kế. Bạn đang tạo một tiện ích có một số hành vi được xác định trước và có thể ẩn một số (hoặc tất cả) chi tiết của lớp Trình quét.

Tôi đã thấy nhiều triển khai đã sử dụng thừa kế để thay đổi hành vi. Kết quả cuối cùng thường là thiết kế nguyên khối, và trong một số trường hợp, một hợp đồng bị hỏng và/hoặc hành vi bị hỏng.

+0

Làm cho nó một thành phần sẽ tăng kích thước của mã của tôi. Nó không phải là một tội lỗi, nhưng bạn sẽ nhận được my.scanner.next() (hoặc thậm chí my.getScanner(). Next() thay vì my.next(). Tôi nghĩ nó đẹp hơn, phải không? Và nó ít "thay thế cái này "bởi" rằng "... – Roalt

+0

Vâng, nếu bạn có yourObject.scanner.next() thì đó không phải là đóng gói phải không? Nhưng nếu bạn có một yourObject.process (đầu vào): returnVal thì bạn làm. –

1

Tôi cho rằng đó là vì lý do bảo mật. Lớp này đọc đầu vào của người dùng, để người nào đó có ý định xấu có thể mở rộng nó, sửa đổi hành vi của nó và bạn sẽ bị xáo trộn. Nếu nó là cuối cùng, nó không phải là dễ dàng cho các chàng xấu, bởi vì nếu anh ta làm cho riêng mình loại Scanner (không java.util.Scanner), các nguyên tắc của đa hình sẽ bị phá vỡ. Xem những kẻ xấu có thể đủ thông minh để viết một bot/script mà thực hiện điều này tự động trên các máy chủ từ xa ... Ông thậm chí có thể làm điều đó bằng cách nạp lớp năng động trong ứng dụng biên dịch.

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