我有一个课程如下,
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
中的每个类都有很多类别。
答案 0 :(得分: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();
我怀疑你能为这三个片段提出一个好的和合理的论点(还有更多我能想到的)。它归结为:什么构造的代码满足您的要求“它必须调用method2”?
基本上这个要求根本无法执行!
唯一有效的方法可能是改变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 */
});
}
}
答案 1 :(得分: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();
}
}
答案 2 :(得分:1)
您可以/必须实现一个漂亮的设计模式:模板模式
说明:
假设你有一个类游戏的方法 初始化(); startPlay(); 和 endPlay(); 如果未初始化,则启动播放是错误的,甚至更多很清楚,不可能开始一个尚未播放的游戏......
所以在你的情况下,定义一个包装器方法,允许你按照应用程序需要的正确顺序调用method1和方法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();
}
}
然后实现Game类
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();
}
}
答案 3 :(得分: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
}
}