gpt4 book ai didi

java - 抽象类调用子类的方法。它是如何工作的?

转载 作者:行者123 更新时间:2023-12-01 23:45:17 25 4
gpt4 key购买 nike

我读了《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;
}
}

您会看到该类自行扩展了“Activity”。这意味着如果您在手机上打开该应用程序,该应用程序就会进入。在 onCreate 方法中有一个名为“getStartScreen()”的方法。这是接口(interface)“Game”所实现的方法。但“AndroidGame”中未实现“getStartScreen()”方法,因此它是一个抽象类。您还记得,方法“getStartScreen()”是在“MrNomGame”中实现的。正如我已经提到的,“getStartScreen()”方法是在 onCreate 方法中调用的。这就是令我困惑的一点。父类(super class)从其子类调用方法。它是如何运作的?如果有两个扩展“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();
}

我知道代码很多。我希望你可以帮助我。非常感谢。

彼得

最佳答案

这是一个关于 OO 编码的非常基本的概念问题。

当一个类被扩展然后实例化时,结果是一个单独的类,它结合了两者的方法和属性。只要该方法被定义为父类(super class),父类(super class)可以执行对该方法的调用,即使代码因为该方法只能写在子类中。事实上,不同的子类可以定义该方法的不同实现,以便尽 pipe 类的方法相同,但在这方面的行为有所不同父类(super class)。

您提到的两个类没有歧义——MrNomGame 已实例化调用其方法将执行其定义的方法,对于 MrNomGame2 也是如此。

如果您真的想知道“它是如何工作的”,那就需要更多技术性的知识。
类中的方法用“跳转表”表示,这意味着,当调用其中之一,该方法的地址在此表中在运行时构建。因此编译器可以通过以下方式准备对方法的调用跳转表,并且运行时可以保证正确的地址为正确的方法执行时在跳转表中。

关于java - 抽象类调用子类的方法。它是如何工作的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17189549/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com