2013-06-19 1 views
0

"Beginning Android Games"라는 책에 실린 코드를 읽었지만 완전히 이해하지 못합니다. 응용 프로그램의 진입 점은 다음과 같습니다서브 클래스의 메소드를 호출하는 추상 클래스. 어떻게 작동합니까?

public class MrNomGame extends AndroidGame { 
    public Screen getStartScreen() { 
     return new LoadingScreen(this); 
    } 
} 

클래스 여기에 확장되어 'AndroidGame'

public abstract class AndroidGame extends Activity implements Game { 
    AndroidFastRenderView renderView; 
    Graphics graphics; 
    Audio audio; 
    Input input; 
    FileIO fileIO; 
    Screen screen; 
    WakeLock wakeLock; 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 

     requestWindowFeature(Window.FEATURE_NO_TITLE); 
     getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, 
       WindowManager.LayoutParams.FLAG_FULLSCREEN); 

     boolean isLandscape = getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE; 
     int frameBufferWidth = isLandscape ? 480 : 320; 
     int frameBufferHeight = isLandscape ? 320 : 480; 
     Bitmap frameBuffer = Bitmap.createBitmap(frameBufferWidth, 
       frameBufferHeight, Config.RGB_565); 

     float scaleX = (float) frameBufferWidth 
       /getWindowManager().getDefaultDisplay().getWidth(); 
     float scaleY = (float) frameBufferHeight 
       /getWindowManager().getDefaultDisplay().getHeight(); 

     renderView = new AndroidFastRenderView(this, frameBuffer); 
     graphics = new AndroidGraphics(getAssets(), frameBuffer); 
     fileIO = new AndroidFileIO(this); 
     audio = new AndroidAudio(this); 
     input = new AndroidInput(this, renderView, scaleX, scaleY); 
     screen = getStartScreen(); 
     setContentView(renderView); 

     PowerManager powerManager = (PowerManager) getSystemService(Context.POWER_SERVICE); 
     wakeLock = powerManager.newWakeLock(PowerManager.FULL_WAKE_LOCK, "GLGame"); 
    } 

    @Override 
    public void onResume() { 
     super.onResume(); 
     wakeLock.acquire(); 
     screen.resume(); 
     renderView.resume(); 
    } 

    @Override 
    public void onPause() { 
     super.onPause(); 
     wakeLock.release(); 
     renderView.pause(); 
     screen.pause(); 

     if (isFinishing()) 
      screen.dispose(); 
    } 

    public Input getInput() { 
     return input; 
    } 

    public FileIO getFileIO() { 
     return fileIO; 
    } 

    public Graphics getGraphics() { 
     return graphics; 
    } 

    public Audio getAudio() { 
     return audio; 
    } 

    public void setScreen(Screen screen) { 
     if (screen == null) 
      throw new IllegalArgumentException("Screen must not be null"); 

     this.screen.pause(); 
     this.screen.dispose(); 
     screen.resume(); 
     screen.update(0); 
     this.screen = screen; 
    } 

    public Screen getCurrentScreen() { 
     return screen; 
    } 
} 

당신은 그 자체로 클래스 확장 '활동'을 참조하십시오. 즉, 휴대 전화에서 앱을 열면 앱이 연결됩니다. onCreate 메서드에는 'getStartScreen()'이라는 메서드가 있습니다. 그것은 구현 된 inferface 'Game'의 한 방법입니다. 그러나 'getStartScreen()'메서드는 'AndroidGame'에 구현되어 있지 않으므로 추상 클래스입니다. 'getStartScreen()'메서드는 'MrNomGame'에 구현되어 있습니다. 앞서 언급했듯이 onCreate 메소드에서 'getStartScreen()'메서드가 호출되었습니다. 그것은 나를 혼란스럽게하는 요점이다. 수퍼 클래스는 서브 클래스에서 메소드를 호출합니다. 어떻게 작동합니까? 그리고 'AndroidGame'을 확장하는 두 개의 하위 클래스가 있다면 어떻게됩니까? 예 :

public class MrNomGame2 extends AndroidGame { 
    public Screen getStartScreen() { 
     return new LoadingScreen(this); 
    } 
} 

'getStartScreen()'메소드가 호출됩니다. MrNomGame 또는 Mr.NomGame2에서 나온 것?

적어도 게임 인터페이스 :

public interface Game { 
    public Input getInput(); 

    public FileIO getFileIO(); 

    public Graphics getGraphics(); 

    public Audio getAudio(); 

    public void setScreen(Screen screen); 

    public Screen getCurrentScreen(); 

    public Screen getStartScreen(); 
} 

나는 그 많은 코드 알고있다. 네가 나를 도울 수 있기를 바랍니다. 고맙습니다.

피터

+0

매니페스트도 표시 할 수 있습니까? – gunar

+1

이것은 Android와 관련이 없습니다. http://docs.oracle.com/javase/tutorial/java/IandI/abstract.html을 참조하십시오. –

+0

코드에 주석을 어떻게 삽입 할 수 있는지 모르겠지만 매니페스트에있는 활동을 알고 싶습니다. . Mr.NomGame 클래스 만 있습니다. –

답변

1

IT는 getStartScreen() 방법이 아니라 당신의 AndroidGame 클래스를 호출 할 MrNomGame2 인스턴스입니다. onCreate() 메서드가 MrNomGame2 클래스의 인스턴스에서 호출되고 런타임이 실행되는 동안 getStartScreen()을 호출해야하고 MrNomGame2 클래스에 구현 된 getStartScreen()을 호출하면 암시 적으로 this.getStartScreen()이됩니다.

interface A12 { 
    void show(); 
} 
abstract class B1 implements A12 { 

    public void callShow() { 
    show(); 
    } 
} 
class C extends B1 { 

    @Override 
    public void show() { 
     System.out.println("You are in C"); 
    } 

} 
public class AbstractTester { 
     public static void main(String[] args){ 
     C c = new C(); 
     c.callShow(); 
    } 
} 
+0

이것은 좋은 예이며 나는 그것을 잘 알고 있습니다. 고맙습니다. –

+0

이것은 좋은 예이며 나는 그것을 잊어 버렸습니다. 고맙습니다. 그러나 'C c = new C()'와 같은 행이 없기 때문에 예제로 전송할 수 없습니다. 내 수업은 어디에서 인스턴스화됩니까? 이 클래스는 앱의 시작 절차의 일부입니다. 그것은 비슷하게 보이지만 그것을 완전히 이해하지 못합니다. –

+0

안드로이드가 매니 페스트에 설명되어 있기 때문에 백그라운드에서 클래스 MrNomGame을 인스턴스화 할 수 있습니까? MrNomGame2를 매니페스트에 넣으면 Mr.NomGame2와도 작동할까요? –

2

이 OO 코딩에 대한 아주 기본적인 개념 질문은 :

이 샘플로 시험 인쇄를 해보십시오.

클래스를 확장 한 다음 인스턴스화하면 결과는 둘 모두의 메서드와 특성을 결합하는 단일 클래스입니다. 메소드가 수퍼 클래스에 대해 정의되어있는 한, 해당 메소드의 코드 이 서브 클래스에만 기록 될 수 있더라도 수퍼 클래스는 메소드 호출을 실행할 수 있습니다. 실제로 다른 하위 클래스 은 메소드의 구현을 다르게 정의 할 수 있으므로 하위 클래스의 인스턴스는 해당 하위 클래스에서 다르게 동작하지만 수퍼 클래스의 메소드에서 동일합니다.

MrNomGame이 인스턴스화 된 이라는 두 클래스에 모호성이 없으며 해당 메서드를 호출하면 정의 된 메서드가 실행되고 MrNomGame2도 마찬가지로 실행됩니다.

"작동 방식"을 알고 싶다면 좀 더 기술적입니다.
클래스의 메소드는 "jump table"으로 표현됩니다. 즉, 중 하나가 호출되면 메소드의 주소는 런타임에이 테이블 에 빌드됩니다. 따라서 컴파일러는 점프 테이블을 통해 메서드 호출을 준비 할 수 있으며 런타임은 올바른 메서드의 올바른 주소가 실행될 때 점프 테이블에 있는지 확인합니다.

관련 문제