2011-10-25 31 views
9

Trong một câu hỏi gần đây, có người hỏi về các phương pháp tĩnh và một trong những câu trả lời nói rằng bạn thường gọi chúng với cái gì đó như:Đang gọi phương thức tĩnh thông qua một đối tượng "biểu mẫu xấu"? Tại sao?

MyClassName.myStaticMethod(); 

Các ý kiến ​​về mà cũng nói rằng bạn cũng có thể gọi nó là thông qua một đối tượng với :

MyClassName myVar; 
myVar.myStaticMethod(); 

nhưng nó bị coi là xấu.

Bây giờ có vẻ như với tôi rằng làm điều này thực sự có thể làm cho cuộc sống của tôi dễ dàng vì vậy tôi không cần phải lo lắng về những gì tĩnh hay không (a).

Có phải có vấn đề gì khi gọi các chức năng tĩnh qua đối tượng không? Rõ ràng bạn sẽ không muốn tạo một thương hiệu đối tượng mới chỉ để gọi nó là:

Integer xyzzy; 
int plugh = xyzzy.parseInt ("42", 10); 

Nhưng, nếu bạn đã có một đối tượng của kiểu như mong muốn, là có một vấn đề trong sử dụng nó?


(a) Rõ ràng, tôi không thể gọi một phương thức không tĩnh với:

MyClassName.myNonStaticMethod(); 

nhưng đó không phải là vấn đề tôi đang hỏi về tại đây.

+1

Xem câu trả lời SO này để biết thông tin http://stackoverflow.com/questions/610458/why-isnt-calling-a-static-method-by-way-of-an-instance-an-error-for-the -java-co/610674 # 610674 –

+0

Khi tôi đọc mã và có một cuộc gọi đến một phương pháp, với tôi nó ** rất cao ** có liên quan để có thể nói ngay rằng cuộc gọi đó không thể đọc và sửa đổi trạng thái của đối tượng nó thuộc về. Với 'MyClassName.myStaticMethod();' thậm chí không cần phải tự hỏi về nó trong một giây. Với 'myVar.myStaticMethod();' bạn cần xem mã của phương thức, và bạn sẽ luôn nghi ngờ về các lệnh gọi _all_. Tất nhiên các IDE khác nhau có thể làm cho thông tin này dễ lấy lại (chú giải công cụ Javadoc, tô sáng cú pháp, v.v.) nhưng tôi sẽ không dựa vào đó để quyết định cách viết mã. – SantiBailors

Trả lời

14

biểu mẫu nhận xét xấu xuất phát từ ước Mã hóa cho Java

Xem http://www.oracle.com/technetwork/java/codeconventions-137265.html#587

Lý do cho nó, nếu bạn nghĩ về nó, đó là phương pháp, là tĩnh, không thuộc để bất kỳ đối tượng cụ thể nào. Bởi vì nó thuộc về lớp, tại sao bạn muốn nâng một đối tượng cụ thể lên một trạng thái đặc biệt như vậy mà nó dường như sở hữu một phương thức?

Trong ví dụ cụ thể của bạn, bạn có thể sử dụng một số nguyên hiện thông qua đó để gọi parseInt (có nghĩa là, nó là hợp pháp trong Java) nhưng mà đặt của người đọc tập trung vào đối tượng số nguyên cụ thể. Nó có thể gây nhầm lẫn cho độc giả, và do đó hướng dẫn là để tránh phong cách này.

Liên quan đến việc tạo lập cuộc sống dễ dàng hơn cho bạn lập trình viên, xoay vòng và hỏi điều gì làm cho cuộc sống dễ dàng hơn trên đầu đọc ? Có hai loại phương thức: ví dụ và tĩnh. Khi bạn thấy biểu thức C.m và bạn biết C là một lớp, bạn biết m phải là phương pháp tĩnh. Khi bạn nhìn thấy x.m (trong đó x là một ví dụ), bạn không thể nói, nhưng nó trông giống như một phương thức thể hiện và vì vậy hầu hết mọi người chỉ đặt cú pháp này cho các phương thức ví dụ.

3

Nó có thể trở nên siêu khó hiểu khi bạn có một đối tượng kế thừa từ một đối tượng khác, ghi đè phương thức tĩnh của nó. Đặc biệt là nếu bạn đang đề cập đến đối tượng như là một loại lớp tổ tiên của nó. Nó sẽ không được rõ ràng như phương pháp mà bạn đang chạy.

+1

Nếu điều đó "siêu bối rối" là một trò chơi chữ, tôi sẽ phải đi qua và tát bạn xung quanh một chút :-) – paxdiablo

+0

@paxdiablo Tôi ước gì tôi đã làm ... điều đó sẽ khá tốt. – bdares

4

Đó là vấn đề liên lạc. Gọi phương thức trên một cá thể ngụ ý bạn đang hành động với/với cá thể cụ thể đó, không phải trên/với lớp của cá thể đó.

20

Theo ý kiến ​​của tôi, trường hợp sử dụng thực sự làm cho điều này không thể đọc được là một cái gì đó như thế này. Mã dưới đây in ra sao?

//in a main method somewhere 
Super instance = new Sub(); 
instance.method(); 

//... 
public class Super { 
    public static void method() { 
     System.out.println("Super"); 
    } 
} 

public class Sub extends Super { 
    public static void method() { 
     System.out.println("Sub"); 
    } 
} 

Câu trả lời là in "Siêu", vì phương pháp tĩnh không phải là ảo. Mặc dù instance là một Sub, trình biên dịch chỉ có thể đi trên loại biến số là Super. Tuy nhiên, bằng cách gọi phương thức qua instance thay vì Super, bạn ngầm ngụ ý rằng nó sẽ là ảo.

Thực tế, nhà phát triển đọc số instance.method() sẽ phải xem xét khai báo phương thức (chữ ký của nó) để biết phương thức thực sự được gọi. Bạn đề cập đến

có vẻ như với tôi rằng làm điều này thực sự có thể làm cho cuộc sống của tôi dễ dàng hơn vì vậy tôi không phải lo lắng về những gì là tĩnh hay không

Nhưng trong trường hợp trên bối cảnh thực sự là rất quan trọng !

Tôi khá tự tin có thể nói rằng đó là một sai lầm cho các nhà thiết kế ngôn ngữ cho phép điều này ngay từ đầu. Tránh xa.

+1

+1 Đồng ý rằng đó cũng là một sai lầm (IMHO). Và một ví dụ tốt đẹp BTW. –

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