2017-01-29 5 views
2

У меня есть класс следующим образом,ограничение метод в Java

public class Class1 { 
    public void method1(String data){   
    } 
    public void method2(String data){ 
    } 
} 

И я использую его как,

public class Class2{ 
    public void doSomething(){ 
     Class1 class1 = new Class1(); 
     class1.method1("123"); 
     // doSomething will find a value as result 
     class1.method2(result); 
    } 
} 

Он является обязательным для вызова method2(); когда method1(); звонит.
Если только method1(); звонит, мне нужно показать ошибку времени компиляции.
Как мы можем достичь того же.
Как Class2 У меня так много классов в каждом doSomething отличается.

+1

/* Это является обязательным call method2(); когда метод1(); звонит*. Вы всегда хотите вызвать метод2 при вызове метода1? – CKing

+0

Немного непонятно, что вы спрашиваете! Не могли бы вы рассказать? –

+1

Это не работа компилятора. Вы можете, например, попробуйте написать какой-нибудь плагин maven, который обеспечивает это ограничение. Но почему бы просто не называть write 'method2();' как последний оператор в 'method1'? – luk2302

ответ

5

Я хотел бы сказать, что вы пытаетесь достичь, это смесь «невозможно сделать» и «не следует делать», если вы хотите, чтобы компилятор это сделал.

Спросите себя следующее: следующие действия:

class1.method1(); 
class1.method1(); 
class1.method2(); 

или

public void doSomething(){ 
    Class1 class1 = new Class1(); 
    class1.method1(); 
    callIt(class1); 
} 

void callIt(Class1 class1) { 
    class1.method2(); 
} 

или

class1.method1(); 
if (true) return; 
class1.method2();  

Я сомневаюсь, что вы можете прийти с хорошим и аргументированно для этих трех фрагментов (и многие другие, я мог придумать). Это сводится к следующему: какая конструкция кода удовлетворяет вашему требованию «обязательно вызвать метод2»?

В принципе, это требование просто невозможно выполнить!


Единственный допустимый способ, вероятно, изменить способ method1 работы: Пусть принять Runnable в качестве аргумента, вызывающий абонент должен пройти, в котором дает абоненту возможность работать после обычной обработки method1 завершается. Затем вызовите method2 внутри method1:

public void method1(Runnable postRunAction) { 
    // regular computation 
    postRunAction.run(); 
    method2(); 
} 

Чтобы сделать пример немного более сложным, если вы хотите использовать возвращаемые значения методов:

public class Class1 { 
    public SomeReturnType2 method1(Function<SomeReturnType1, SomeParameterType1> yourDoSomething) {   
     SomeReturnType1 something = /* your computation of method1 */ 
     SomeParameterType1 param = yourDoSomething.apply(something); 
     return method2(param); 
    } 

    private SomeReturnType2 method2(SomeParameterType1 param1){ 
     // do some calculation of method2 
    } 
} 

public class Class2 { 
    public void doSomething(){ 
     Class1 class1 = new Class1(); 
     class1.method1((theReturnValueOfMethod1Computation) -> { 
      /* do what do you want to do with the return value + return what do you want to pass to method2 */ 
     }); 
    } 
} 
+0

В чем причина внедрения 'Runnable' здесь? На первый взгляд это для меня немного избыток, поскольку то, что требуется, может быть достигнуто с помощью модификаторов доступа. –

+0

@ GrzegorzGórkiewicz нет, если * "// doSomething" * - это то, что можно сделать только вне класса Class1. – luk2302

+0

Все еще не имеет смысла для меня ... Можете ли вы привести пример, почему вы используете «Runnable's здесь»? –

2
public class Class1 { 

    public void method1(String input){ 
    //doSomething(); 
    //you can pass whatever parameters you want or leave it as it is 
    method2(result);  
    } 

    private void method2(int input){ 
    } 
} 

А потом просто позвонить method1:

public class Class2 { 
    public void doSomething(){ 
     Class1 class1 = new Class1(); 
     class1.method1(); 
    } 
} 

Чтобы увидеть ошибку:

public class Class2 { 
    public void doSomething(){ 
     Class1 class1 = new Class1(); 
     class1.method1(); 
     class1.method2(); 
    } 
} 
+0

Где ошибка компиляции, которую запросил ОП, если он вызывает метод2 напрямую? – CKing

+2

Попробуйте вызвать 'class1.method2()' внутри 'Class2'. –

+0

Но это не то, чего хочет OP. То, что вы сделали, скрывает сам метод. Это похоже на удаление метода. В идеале метод 2 должен быть открыт для вызовов независимо. Тем не менее, +1, потому что это хороший ответ. – CKing

0

Это не возможно иметь ошибку времени компиляции, потому что, насколько компилятор, программа действительна.

В вашем случае вы можете отправить RuntimeException (или любое другое исключение, которое вам подходит), проверив, было ли вызвано method1, когда вызывается method2.

Например, в Class1: ошибка времени

public class Class1 { 
    private boolean method1Called = false; 
    public void method1(){ 
    method1Called=true; 
    // rest of method1 code 
    } 
    public void method2(){ 
    if(!method1Called) { 
     throw new RuntimeException("method 1 should be called first"); 
    } 
    // rest of method2 code 
    } 
} 
+0

* Невозможно иметь ошибку времени компиляции *. Не удалось ли это получить через аннотации? – CKing

+0

Какую аннотацию вы могли бы создать, которая вызовет ошибку компиляции для вызова метода без вызова другого ранее? – JChrist

+0

Не знаю. Вот почему я спросил и не предлагал. – CKing

0

Compile не могут быть использованы, так как в конфигурации, использование методов вполне допустимо. Если вы действительно хотите вызвать method2 за method1, то вы должны переместить логику method2 внутри method1

1

Вы можете/должны реализовать хороший дизайн шаблона: шаблонов Pattern

объяснение:

Представьте, что у вас есть класс Игра с методами initialize();startPlay(); и endPlay(); тогда неправильно запускать игру, если она не инициализирована или даже более понятная, невозможно запустить игру, которая еще не была сыграна ...

поэтому в вашем случае определите метод обертки, который позволяет вы должны вызвать метод 1 и метод 2 в правильном порядке, в котором нуждается ваш приложение!

Пример

public abstract class Game { 
    abstract void initialize(); 
    abstract void startPlay(); 
    abstract void endPlay(); 

    //template method 
    public final void play(){ 

     //initialize the game 
     initialize(); 

     //start game 
     startPlay(); 

     //end game 
     endPlay(); 
    } 
} 

затем реализовать класс игры

public class Football extends Game { 

    @Override 
    void endPlay() { 
     System.out.println("Football Game Finished!"); 
    } 

    @Override 
    void initialize() { 
     System.out.println("Football Game Initialized! Start playing."); 
    } 

    @Override 
    void startPlay() { 
     System.out.println("Football Game Started. Enjoy the game!"); 
    } 
} 

и конечный класс Исполнитель:

public class TemplatePatternDemo { 
    public static void main(String[] args) { 

     game = new Football(); 
     game.play();  
    } 
} 
Смежные вопросы