2012-03-14 26 views
16

Hãy xem xét sau tình huống:Java có thể làm điều gì đó như thể loại trong Mục tiêu C không?

Object > MyClass > MyClassA, MyClassB 

Nếu tôi muốn một cái gì đó ở mức đối tượng, ví dụ, tôi đã thêm printDetail(); Làm thế nào tôi có thể làm điều đó trong thực hiện Java? Hơn nữa, tôi có thể ghi đè lên tất cả các phương pháp của Object. Ví dụ: tôi cần phải có toàn bộ .toString() mới, tôi có thể ghi đè nó không? Cảm ơn.

Trả lời

28

Không, nó không thể, không thực sự anyway. Mục tiêu C là một ngôn ngữ được gõ động và có phạm vi, điều này làm cho nó rất phù hợp với các tính năng như thể loại. Việc gần nhất bạn có thể đến với điều này trong Java là thiết bị đo lớp thông qua một thư viện thao tác mã byte như ASM hoặc Javassist. Tuy nhiên, thực sự, khi sử dụng một ngôn ngữ OO được đánh máy mạnh như Java, bạn nên nắm lấy các tính năng của nó thay vì cố gắng sao chép các ngôn ngữ khác của ngôn ngữ khác.

+0

câu trả lời tuyệt vời .. !! –

+0

Mặc dù nhận xét có phần mang tính học thuật, tôi cho rằng vấn đề là bao thanh toán: ví dụ: nếu tôi muốn một cách để ngẫu nhiên thứ tự của những thứ trong một mảng tôi có thể nói "ngữ nghĩa đó là đúng nhất một hành động mà tôi muốn yêu cầu mảng để thực hiện; tôi do đó sẽ thêm nó như là một phương pháp trên mảng". Mà tôi không nghĩ rằng cắt giảm chống được đánh mạnh mẽ hoặc hướng đối tượng. Nhưng, không, nó không phải là Java. – Tommy

+1

Không phải là C# một ngôn ngữ OO được đánh máy mạnh? Bởi vì C# cung cấp khả năng này thông qua các phương thức mở rộng. Có vấn đề gì khi lấy nội dung hay từ các ngôn ngữ khác? Đó là một cách để tiến bộ ... – obe

2

Tất cả các lớp Java cuối cùng có java.lang.Object Do đó, tất cả các phương thức Java classes inherit từ Object. Một nửa trong số các phương pháp này là final và không thể là overridden. Tuy nhiên, các phương pháp khác trong đối tượng có thể được và được ghi đè
Phương thức toString() trong lớp Object được sử dụng để hiển thị một số thông tin về bất kỳ đối tượng nào.
Vì vậy, bạn có thể Override nó theo tự của bạn ...
EX ..

public class Test{ 
    @Override 
    public String toString() { 
    /// staff 
    } 
} 
+0

Tôi hiểu. Tôi sử dụng ruby, cho phép tôi ghi đè lên đối tượng cấp cao nhất. – DNB5brims

11

Như đã đề cập trong câu trả lời khác, không có gì thực sự giống như một loại là. Tôi có một số giải pháp phổ biến mà tôi sử dụng cho một số danh mục trong mã mục tiêu-c khi chuyển sang java. Nhiều danh mục mục tiêu của tôi tồn tại vì tôi không muốn mở rộng các lớp cơ sở iOS nhưng tôi muốn thêm một số chức năng vào lớp đó. Nhiều loại mục tiêu-c không thêm thuộc tính bằng objc_SetAssociatedObject. Đối với những trường hợp này, tôi sử dụng một lớp trợ giúp tĩnh trong Java. Hãy xem một ví dụ sử dụng NSString và String. Tôi sẽ thêm chức năng cho cả hai để thêm dấu ngoặc kép vào chuỗi. Chúng tôi giả định điều này hữu ích và không tồn tại cho mục đích minh họa. Trong Objective-C chúng ta có thể có:

@interface NSString (MyCategory) 

/** 
* Creates and autoreleased image from self. 
*/ 
- (NSString*)quotedString; 

@end 

@implementation NSString (MyCategory) 

- (NSString *)quotedString 
{ 
    return [NSString stringWithFormat:@"\"%@\"", self]; 
} 

@end 

Bạn sẽ gọi đây là từ một nơi nào như thế này:

NSString *myString = @"When you're curious, you find lots of interesting things to do."; 
NSString *quotedString = [myString quotedString]; 

Đây là cách tôi sẽ thực hiện điều này trong Java:

public class StringHelper { 

    public static String quotedString(String that) { 
     return '"' + that + '"'; 
    } 
} 

Và để gọi nó:

String myString = = "When you're curious, you find lots of interesting things to do."; 
String quotedString = StringHelper.quotedString(myString); 

Nếu bạn nghĩ về các phương thức thể loại như các phương thức tự động gửi biến tự làm đối số phương thức đầu tiên (mặc dù vô hình) thì điều này có ý nghĩa hơn.

Ví dụ, nếu tôi sẽ không mở rộng đối tượng cụ thể, tôi có thể làm điều gì đó như:

public class ObjectHelper { 

    public static void printDetail(Object that) { 
     // do what it takes; 
    } 
} 

UPDATE: Một commenter yêu cầu hạn chế.

Hạn chế sẽ là mã nằm trong một lớp tĩnh riêng biệt. Nó không thuận tiện như một thể loại. Bạn phải nhớ những tên lớp, hoặc tìm thấy chúng, và bạn sẽ không nhận được tự động hoàn thành về phương pháp đối tượng ban đầu của bạn trong helper. Ngoài ra, bạn không thể sử dụng thuộc tính hoặc thuộc tính ở mức đối tượng như bạn nhận được với objc_SetAssociatedObject. Bạn có thể sử dụng một bản đồ băm và tạo ra một cái gì đó tương tự với thể hiện đối tượng ban đầu như là một khóa băm.

public class StringHelper { 
    private static Map<String, Integer> order = new HashMap(); 

    public static int getOrder(String that) { 
     if(that == null) { return 0; } 
     Integer ret = StringHelper.order.get(that); 
     if(ret == null) { return 0; } 
     else { return ret; } 
    } 
    public static void setOrder(String that, int order) { 
     if(that != null) { 
      StringHelper.order.put(that, order); 
     } 
    } 
} 

Cũng không có xung đột tên với lớp gốc, điều này sẽ mang lại nhiều lợi ích hơn. Các xung đột tên trong các danh mục khách quan c được coi là xấu.

+0

Tôi thích câu trả lời này tốt nhất vì nó mang lại cho tôi một giải pháp. Cảm ơn! –

+0

@ptoinson Những hạn chế nào nếu chúng ta so sánh theo cách này với danh mục trong iOS? – NghiaDao

+0

@NghiaDao - Các giới hạn được thêm vào bản cập nhật cho câu trả lời. – ptoinson

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