Tại sao các khung Windows Forms / Swing ưu tiên kế thừa thay vì Thành phần?


12

Hôm nay, một giáo sư của tôi nhận xét rằng ông thấy kỳ lạ rằng trong khi triết lý của SWT là một trong những điều khiển của riêng bạn theo thành phần, thì Swing dường như ủng hộ sự kế thừa.

Tôi gần như không có liên hệ với cả hai khung, nhưng từ những gì tôi nhớ trong Windows Forms của C #, người ta thường mở rộng các điều khiển, giống như Swing.

Vì mọi người thường có xu hướng thích sáng tác hơn thừa kế, tại sao mọi người không ủng hộ thành phần Swing / Windows Forms thay vì kế thừa?


2
Rất nhiều thứ đã thay đổi trong 15-20 năm những API đó đã xuất hiện! Các công cụ kết xuất không có keo XML ma thuật để liên kết các đối tượng màn hình với các trường hợp của bất kỳ lớp cụ thể tùy ý nào "quay lại trong ngày";)

1
Hầu hết mã Swing tôi thấy sử dụng phần mở rộng theo thành phần. Tôi không chắc chắn nơi prof của bạn nhận được dữ liệu của mình.

Bản thân tôi đã thấy rất nhiều sự thay đổi trên mạng với sự kế thừa thay vì sáng tác - mặc dù chủ yếu là hướng dẫn. nhưng các hình thức cửa sổ thực sự được sử dụng hầu như chỉ dựa trên sự kế thừa!
elysium nuốt chửng

Câu trả lời:


7

JComponentphơi bày rất nhiều chức năng . Nếu JComponentmột giao diện và các thành phần được triển khai với thành phần, các thành phần đơn giản sẽ cần phải có hàng tá các hàm bao phương thức tầm thường, ví dụ:

class MyComponent implements JComponent {
    JPanel panel;
    public boolean contains(int x, int y) {
        return panel.contains(x, y);
    }
    ...
}

Ngoài ra còn có một lý do hiệu quả để thích kế thừa hơn thành phần - không có chi phí nào cao hơn (giả sử không có super cuộc gọi), trong khi thành phần có chi phí thêm INVOKEVIRTUAL. Tôi không biết điều này có ảnh hưởng đến thiết kế của Swing không, nhưng nó là mối quan tâm lớn đối với các lớp sưu tập.


2

Khung xoay thực sự được thiết kế theo Mẫu thiết kế tổng hợp. Được cho rằng có rất nhiều sự kế thừa trong đó, nhưng bạn thường sẽ soạn các biểu mẫu của riêng bạn bằng cách sử dụng thành phần. Đó là, một hình thức là một thành phần của các container và điều khiển mức trung gian.


"Đó là, một hình thức là một thành phần của các thùng chứa và điều khiển ở cấp độ trung gian." Chắc chắn rồi. Nhưng điều tôi thường thấy là khi mọi người muốn tạo cửa sổ của riêng họ (hoặc bất cứ thứ gì được gọi trong Swing), họ sẽ thừa hưởng từ một lớp cửa sổ thay vì sử dụng bố cục.
nuốt chửng elysium

@devoured elysium Đó là sự thật. Nhưng để tạo ra hình thức họ sẽ sử dụng thành phần. Vì vậy, nó là một chút kế thừa và rất nhiều thành phần.

@devoured, tôi nghĩ đó là trường hợp mọi người không nhận ra rằng hướng dẫn họ sử dụng không tuân theo thực tiễn tốt nhất vì nó thiên về sự ngắn gọn.
Peter Taylor

1

Với Java, việc kết thúc sử dụng tính kế thừa sẽ dễ dàng hơn rất nhiều chỉ vì mọi thứ đều là ảo. Cần sửa một "tính năng" trong JTable / JFrame? Mở rộng nó, ghi đè các phương thức vấn đề và sau đó sử dụng Bảng / Khung của bạn ở mọi nơi thay thế.

Tôi nghĩ với những thứ như WPF, trong đó liên kết dữ liệu là một tính năng chính của thiết kế, làm cho việc tạo bố cục dễ dàng hơn nhiều so với kế thừa.


Bạn có ý nghĩa gì với "mọi thứ đều là ảo "?
Jonas

trong java, mọi phương thức đều là ảo (có thể được ghi đè). Trong C #, bạn phải khai báo rõ ràng một phương thức là virtualvà để ghi đè lên nó, bạn tuyên bố rõ ràng là một phương thức override. Trong java, bạn có thể ghi đè bất cứ thứ gì bạn có thể nhìn thấy và bạn có thể tăng khả năng hiển thị của nó trong một lớp con (bạn có thể công khai các phương thức được bảo vệ trong một lớp con!)
John Gardner

Lưu ý rằng bạn không thể ghi đè một finalphương thức trong Java, ngay cả khi bản thân lớp cơ sở không final.
perp

đó là sự thật @perp. nhưng trong java bạn phải đi theo cách của bạn (thêm cuối cùng) để ngăn chặn ảo. C # là cách ngược lại, bạn phải đi ra ngoài để trở thành ảo. Và một tỷ lệ rất nhỏ của thời gian chạy java tiêu chuẩn được đánh dấu cuối cùng.
John Gardner

1

Trong Java hiệu quả , Mục 17, Bloch đề cập rằng một lớp được thiết kế để kế thừa "phải ghi lại việc tự sử dụng các phương thức overridable của nó." Một dấu hiệu của điều này là cụm từ thực hiện này . Bạn sẽ thấy nó trong các lớp như JTableJInternalFrame. Đó là một biện pháp kế thừa theo thiết kế trong Swing.


-2

Từ C # 3.5, chúng ta có một khái niệm gọi là Phương thức mở rộng cho phép khái niệm thành phần hơn là kế thừa.

Trong quá trình này, chúng tôi triển khai một chức năng mở rộng cho một lớp hiện có chỉ bằng cách thêm một lớp mở rộng để hiển thị tính năng mới cho lớp hiện có.

Bạn có thể tham khảo tại đây để biết thêm chi tiết


Tôi không thấy sự liên quan để tạo các lớp Kiểm soát WinForms mới. Bạn có thể giải thích?
Peter Taylor

@Peter: Điều này không liên quan đến chỉ các lớp biểu mẫu windows. Điều này cũng có thể được áp dụng từ mã của chúng tôi. Bạn có thể mở rộng bất kỳ lớp nào bằng cách chỉ cần thêm một lớp tĩnh và sau đó thêm phương thức mới với đối số thứ nhất vì điều này để đối tượng cơ sở có thể được liên kết đến. Sau khi bạn biên dịch mã, bạn nhận được phương thức mới được thêm vào như là một phương thức của chính lớp cơ sở. Đây là những gì thành phần nhà nước. hy vọng tôi đúng ..
Saravanan

1
Tôi biết phương thức mở rộng là gì và đôi khi chúng khá tiện dụng, nhưng câu hỏi này là về các cách tiếp cận khác nhau để tạo các lớp mới.
Peter Taylor

@Peter: Sau đó tôi chỉ có thể chỉ sử dụng các lớp một phần, ngoài điều đó theo hiểu biết của tôi C # không có bất kỳ tính năng đáng chú ý nào khác. Nếu bạn biết bất kỳ, xin vui lòng cho tôi biết.
Saravanan
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.