2013-08-20 24 views
11

Tôi muốn ép buộc phân lớp thực hiện một phương pháp thực hiện của lớp mẹ. Tôi nhìn đây Java - Force implementation of an implemented method nhưng tôi không thể chuyển đổi lớp học của mẹ sang lớp trừu tượng.Làm thế nào để buộc thực hiện một phương thức trong phân lớp mà không sử dụng trừu tượng?

public class myMotherClass { 

    myMethod { 

     ...some code .. 

    } 

} 

public class myClass extends myMotherClass { 

    myMethod { 

     ... other code ... 
    } 

} 

Vì vậy, trong ví dụ này, tôi muốn buộc myClass triển khai myMethod.

Xin lỗi vì tiếng anh của tôi ...

+1

Tóm lại: Bạn không thể không làm cho nó trừu tượng –

+0

@stonedsquirrel Còn giao diện thì sao? –

+0

Điều này là không thể sử dụng chú thích hoặc bằng cách ném một ngoại lệ nếu lớp không thực hiện phương pháp? – Maniz

Trả lời

16

Bạn không thể ép buộc một lớp con để ghi đè lên một phương pháp. Bạn chỉ có thể ép buộc nó thực hiện một phương thức bằng cách làm cho nó trừu tượng.

Vì vậy, nếu bạn không thể làm myMotherClass trừu tượng bạn chỉ có thể giới thiệu một lớp cha mà kéo dài myMotherClass và các đại biểu cho phương thức đó phải được thực hiện:

public abstract class EnforceImplementation extends myMotherClass { 

     public final void myMethod(){ 
      implementMyMethod(); 
     } 

     public abstract void implementMyMethod(); 
} 

EDIT

tôi tìm thấy một cách khác interessting giải quyết vấn đề trong ví dụ hemcrest api được sử dụng bởi mockito.

public interface Matcher<T> extends SelfDescribing { 

    /** 
    * Evaluates the matcher for argument <var>item</var>. 
    * <p/> 
    * This method matches against Object, instead of the generic type T. This is 
    * because the caller of the Matcher does not know at runtime what the type is 
    * (because of type erasure with Java generics). It is down to the implementations 
    * to check the correct type. 
    * 
    * @param item the object against which the matcher is evaluated. 
    * @return <code>true</code> if <var>item</var> matches, otherwise <code>false</code>. 
    * 
    * @see BaseMatcher 
    */ 
    boolean matches(Object item); 

    /** 
    * This method simply acts a friendly reminder not to implement Matcher directly and 
    * instead extend BaseMatcher. It's easy to ignore JavaDoc, but a bit harder to ignore 
    * compile errors . 
    * 
    * @see Matcher for reasons why. 
    * @see BaseMatcher 
    */ 
    void _dont_implement_Matcher___instead_extend_BaseMatcher_(); 
} 

Giao diện qui định phương pháp _dont_implement_Matcher___instead_extend_BaseMatcher_. Tất nhiên nó không ngăn cản người khác thực hiện giao diện Matcher, nhưng nó hướng dẫn nhà phát triển đi đúng hướng.

Và lớp BaseMatcher thực hiện các phương pháp _dont_implement_Matcher___instead_extend_BaseMatcher_ như thức

public final void _dont_implement_Matcher___instead_extend_BaseMatcher_() { 
    // See Matcher interface for an explanation of this method. 
} 

Cuối cùng tôi nghĩ rằng đây là một vấn đề thiết kế, bởi vì BaseMatcher obviouosly thực hiện logic mà mỗi Matcher nên thực hiện. Do đó, tốt hơn hết là làm cho lớp Matcher trừu tượng và sử dụng một phương thức mẫu.

Nhưng tôi đoán họ đã làm điều đó vì đó là sự thỏa hiệp tốt nhất giữa khả năng tương thích bytecode và các tính năng mới.

4

Bạn có thể làm lại cấu trúc phân cấp để lớp bê tông chỉ là lá của cây.

Thay vì

myClass extends myMotherClass 

Cân nhắc

myClass extends myMotherAbstractClass 
myMotherClass extends myMotherAbstractClass 

Bằng cách này, lớp trừu tượng được thừa hưởng bởi cả hai lớp khởi tạo. Có khả năng trong trường hợp này, myMotherClass sẽ cực kỳ mỏng, chỉ cần thực hiện myMethod.

-1

Nếu bạn thực sự muốn ép buộc triển khai sử dụng phương pháp nên sử dụng interface.

public interface MyInterface{ 

    void myMethod(); 
} 

Bây giờ nếu một ai muốn thực hiện từ giao diện này như MyClass implements MyInterface, Bạn cần phải thực hiện myMethod();

public MyClass implements MyInterface{ 

    public void myMethod{ 
    // do something 
    } 

} 
+2

Tôi không nghĩ rằng điều này sẽ giải quyết được vấn đề. – Lokesh

0

Một điều hầu hết mọi người đều nhìn ra là việc thực hiện sau đây (mặc dù tôi thấy đề cập đến nó trong một chú thích):

public class MyMotherClass { 

    public void myMethod() { 
     throw new RuntimeException("Method not overwritten"); 
    }  

} 

Trong hầu hết các trường hợp này nên là đủ, như bạn nên có một số hình thức kiểm tra chấp nhận (ngay cả khi nó chỉ kiểm tra lớp kế thừa bằng tay). Về lý thuyết, bạn vẫn đang giới thiệu khả năng rằng không ai sẽ nhận ra rằng phương pháp này đã không bị ghi đè cho đến khi sản xuất.

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