2013-06-19 58 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()'的方法。這是實現的接口「遊戲」的一種方法。但'getStartScreen()'方法沒有在'AndroidGame'中實現,因此它是一個抽象類。你記得'方法'getStartScreen()'在'MrNomGame'中實現。正如我已經提到的,方法'getStartScreen()'在onCreate方法中被調用。這是令我困惑的一點。超類從它的子類中調用一個方法。它是如何工作的?如果有兩個擴展'AndroidGame'的子類會發生什麼?例如:

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

哪個'getStartScreen()'方法會被調用? MrNomGame或MrNomGame2的那一個?

至少遊戲的界面:

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

你能不能展示Manifest? – gunar

+1

這不是特定於Android的。請參閱http://docs.oracle.com/javase/tutorial/java/IandI/abstract.html –

+0

我不知道如何將代碼插入評論中,但我想您想知道清單中的哪些活動。只有MrNomGame Class。 –

回答

1

這是MrNomGame2實例,它會調用getStartScreen()方法,而不是你的AndroidGame類。我確信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

難道是因爲android在後臺實例化了類MrNomGame嗎?如果我將Mr.NomGame2放在清單中,那麼它也會與MrNomGame2合作? –

2

這是關於OO編碼一個很基本的概念上的問題。

當一個類被擴展,然後實例化,結果 是一個單一的類,它結合了 兩個方法和屬性。只要方法是爲超類定義的,超類就可以執行對該方法的調用,即使該方法的代碼 只能寫在子類中。事實上,不同的子類 可以定義該方法的不同實現,使得子類的實例在這方面表現不同,儘管超類的方法相同。

你提到的兩個類沒有歧義 - MrNomGame被實例化爲 ,調用它的方法將執行它定義的那個,同樣對於MrNomGame2也是如此。

如果你真的想知道「它是如何工作的」,那會多一點技術性。
這些類中的方法用「跳轉表」表示,這意味着,在對其中一個進行調用時,該方法的地址位於此表的 在運行時生成。所以編譯器可以通過 跳轉表準備對方法的調用,並且運行時可以確保正確的 方法的正確地址在執行時位於跳轉表中。

相關問題