Tôi có một baseclass, Statement
, mà một số lớp khác kế thừa từ, có tên IfStatement
, WhereStatement
, v.v ... Cách tốt nhất để thực hiện thử nghiệm trong một if
là gì tuyên bố để xác định loại Statement
lớp một trường hợp có nguồn gốc từ?Java có phương pháp thử nghiệm "kiểu lớp" không
Trả lời
if (obj.getClass().isInstance(Statement.class)) {
doStuffWithStatements((Statement) obj));
}
Điều tốt đẹp về kỹ thuật này (trái với từ khóa "instanceof") là bạn có thể vượt qua lớp thử nghiệm xung quanh làm đối tượng. Nhưng, yeah, khác hơn thế, nó giống hệt với "instanceof".
LƯU Ý: Tôi đã cố tình tránh biên tập về việc có kiểm tra loại cá thể hay không là phải điều cần làm. Yeah, trong hầu hết các trường hợp, tốt hơn là sử dụng đa hình. Nhưng đó không phải là những gì OP hỏi, và tôi chỉ trả lời câu hỏi của anh ấy.
if(object instanceof WhereStatement) {
WhereStatement where = (WhereStatement) object;
doSomething(where);
}
Lưu ý rằng mã này thường có nghĩa là lớp cơ sở của bạn thiếu phương pháp đa hình. tức là doSomething()
phải là phương thức Statement
, có thể là trừu tượng, được ghi đè bởi các lớp con.
Cảm ơn bạn đã cung cấp thông tin bổ sung! Tôi sẽ xem xét nó để xem nếu có một cách sạch sẽ để cải thiện thiết kế. –
+1 cho câu trả lời, mặc dù tôi sẽ thêm rằng 'instanceof' có rất nhiều sử dụng hợp lệ - nó không phải luôn luôn là một mùi thiết kế. Ví dụ, nếu 'doSomething()' chỉ có thể áp dụng cho các mệnh đề thì mẫu này có lẽ tốt hơn là tạo một phần 'doSomething()' của lớp Statement (nơi nó không hợp lý). – mikera
Một ví dụ khác về nơi 'instanceof' hữu ích. Trong JavaFX, bạn có một Pane. Tôi cần phải đi qua cây của các nút con. 'getChildren()' trả về các nút. Nhưng nếu một trong các nút là một Pane, tôi cũng cần phải đi qua các em _its_. Node không có phương thức 'getChildren()' và không phải là của tôi để thêm vào. Vì vậy, tôi phải sử dụng 'nút instanceof Pane' để xem liệu tôi có cần truyền Node tới một Pane và đi qua các con của nó hay không. – dwilliss
Câu trả lời cho câu hỏi của bạn là instanceof.
Tuy nhiên, hãy nhớ rằng nếu mã của bạn cần instanceof, đó là dấu hiệu cho thấy có điều gì đó không phù hợp với thiết kế của bạn. Có một số trường hợp khi instanceof là hợp lý, nhưng chúng khá ngoại lệ. Thông thường, nếu các lớp con của bạn cần phải hoạt động khác nhau, bạn phải sử dụng đa hình thay vì if() s.
Điều duy nhất tôi sẽ thêm vào lời khen của bạn là gợi ý mạnh mẽ về lập trình bằng giao diện. – monksy
Đây là không phải là cách để thực hiện mọi thứ theo cách hướng đối tượng, đó là một sự trở lại đối với sự phân đôi mã/dữ liệu cũ. Bây giờ, đó không nhất thiết là một điều xấu (nếu bạn biết bạn đang làm gì) nhưng bạn nên để các ngôn ngữ không hướng đối tượng như C.
Với thiết kế phù hợp, bạn không cần loại hành vi đó . Thay vì xây dựng:
if (obj.getClass().isInstance(Statement.class)) {
doStuffWithStatements((Statement) obj));
}
(lời xin lỗi đến benjismith cho 'ăn cắp' mã số của mình), bạn thực sự nên được làm cho đối tượng tự chịu trách nhiệm về hoạt động của mình như sau:
obj.doStuff();
Sau đó, mỗi khác nhau obj
lớp học sẽ có định nghĩa riêng cho doStuff
. Đó là cách đúng đắn để làm điều đó.
Nếu chỉ có một lớp con có thể làm doStuff (™ paxdiabio) và bạn có một mảng các đối tượng trong đó một lớp siêu lớp của lớp con thì đây là cách tốt hơn để làm điều đó (thay vì thêm no-op'd các phương thức doStuff cho các siêu lớp có thể vô nghĩa (hoặc "chỉ sai")). – geowar
@geowar, nếu bạn có một bộ sưu tập những thứ không đồng nhất, chúng có thể không * được * trong bộ sưu tập. Hoặc, ở mức tối thiểu, bạn không nên lặp qua bộ sưu tập đó theo cách muốn làm doStuff. Có nhiều cách khác nhau để xử lý việc này nhưng buộc nó vào tên hoặc loại của lớp có thể rất có vấn đề khi thực hiện thay đổi. Trong thế giới thừa kế/OO, có một hàm rỗng cho lớp cha mà không muốn làm gì cho trường hợp này thực sự là một giải pháp hợp lệ, làm cho mã xử lý trở nên sạch hơn. – paxdiablo
isAssignableFrom (java.lang.Class) từ lớp là câu trả lời của bạn. http://download.oracle.com/javase/6/docs/api/java/lang/Class.html#isAssignableFrom(java.lang.Class)
Hãy thử điều này:
if (Statement.class.isInstance(obj)) {
doStuffWithStatements((Statement) obj));
}
từ Class.isInstance() phương pháp có một trường hợp đối tượng như một tham số.
- 1. Phương pháp thử nghiệm
- 2. Cách chạy phương pháp thử nghiệm hoặc lớp học dưới dạng Thử nghiệm Android trong Android Studio
- 3. Thử nghiệm phương pháp thay vì thử nghiệm toàn bộ tệp trong Netbeans w/JUnit
- 4. Phương pháp riêng thử nghiệm đơn vị: Mẫu mặt tiền
- 5. Các phương pháp SetUp và TearDown có cần [RequiresSTA] nếu các thử nghiệm có nó không?
- 6. Thử nghiệm đơn vị Các phương pháp Spring @Around AOP
- 7. Phương pháp thử nghiệm đơn vị phụ thuộc
- 8. Khi thử nghiệm với rspec, nơi để đặt phổ biến "phương pháp thử nghiệm tiện ích"?
- 9. Công cụ Java để thử nghiệm các phương pháp riêng tư?
- 10. Mockito bỏ qua phương pháp tĩnh để thử nghiệm
- 11. Phương pháp thử nghiệm đơn vị với tệp IO
- 12. TDD: Có hợp lý để thử nghiệm tích hợp, nhưng không có thử nghiệm đơn vị?
- 13. Phương pháp thử nghiệm nào đi cùng? [Rails]
- 14. Phương pháp thiết lập thử nghiệm Nunit với đối số
- 15. Chạy một phương pháp thử nghiệm duy nhất
- 16. Thử nghiệm đơn vị VS2008 - phương pháp xác thực thoát
- 17. đơn vị thử nghiệm một phương pháp nhà máy
- 18. Đơn vị thử nghiệm một phương pháp điều khiển?
- 19. Phương pháp riêng Thử nghiệm đơn vị với Jasmine
- 20. Tôi có nên ghi lại các phương pháp thử nghiệm đơn vị của mình không?
- 21. Làm thế nào tôi có thể thử nghiệm đơn vị một phương pháp [Test] trong MonoDevelop?
- 22. JUnit 4: Thiết lập mọi thứ trong một bộ thử trước khi chạy thử nghiệm (như phương pháp @BeforeClass của thử nghiệm, chỉ dành cho bộ thử nghiệm)
- 23. Có bao nhiêu đơn vị thử nghiệm trước khi bắt đầu mã hóa một phương pháp/lớp học?
- 24. Làm cách nào để thêm phương pháp thử nghiệm vào một nhóm các lớp có nguồn gốc từ Django TestCase?
- 25. Java: Thử nghiệm với generics
- 26. Phương pháp chính Java, Kiểu mã hóa tốt
- 27. làm thế nào để thử một phương pháp trong một đối tượng khi thử nghiệm một phương pháp trong cùng một đối tượng
- 28. Đơn vị thử nghiệm phương pháp không đồng bộ cho ngoại lệ cụ thể
- 29. Tại sao Phương pháp Mở rộng của tôi không hiển thị trong lớp thử nghiệm của tôi?
- 30. Phương pháp thử Spring MVC @ExceptionHandler với Spring MVC thử nghiệm
Tại sao không chỉ sử dụng kiểm tra instanceof đơn giản hơn? –
instanceof không phải là ác như goto. Có một lý do khiến nó được thêm vào ngôn ngữ và tại sao nó không bị phản đối. –
+1 không phải là "chỉnh sửa về việc có kiểm tra loại cá thể hay không là điều đúng để làm" –