Java 接口和类型多态性,一个实现 vs 扩展
Java interfaces and type polymorphism, one implement vs extend
所以我认为这更像是一个好奇的问题,而不是需要解决的问题。
所以我在 Android Studio 中与 AndEngine 坐在一起 Android,我想制作一个 AudioManager 来处理我的所有音频,作为开始。
我可以实现 AndEngine 的接口 IAudioManager 或扩展 BaseAudioManager,它已经是前面提到的接口的实现。这让我想到了我的问题。 IAudioManager 和 IAudioEntity:
public interface IAudioManager<T extends IAudioEntity> {
public float getMasterVolume();
public void setMasterVolume(final float pMasterVolume);
public void add(final T pAudioEntity);
public boolean remove(final T pAudioEntity);
public void releaseAll();
}
public interface IAudioEntity {
public void play();
public void pause();
public void resume();
public void stop();
public float getVolume();
public void setVolume(final float pVolume);
public float getLeftVolume();
public float getRightVolume();
public void setVolume(final float pLeftVolume, final float pRightVolume);
public void onMasterVolumeChanged(final float pMasterVolume);
public void setLooping(final boolean pLooping);
public void release();
}
现在,如果我想使用此接口创建一个 AudioManager,可以将其键入为 T extends IAudioEntity。但我认为您实现了接口而不是扩展它们,对吗?
所以我想知道在接口方面是否遗漏了什么。我不太喜欢 Java 但我在大学上过一门课所以我记得很多东西但细节可能很模糊,但这是否仅仅意味着这种情况下的实际语法并不重要因为它必须被实现才能被实例化,任何扩展 class 的东西都可以作为这个 AudioManager?
的参数
它只是语法。在定义 class 时,您确实使用 implements
来指示 class 实现了一个接口,并使用 extends
来指示 class 是一个子 class 另一个 class。
在 <
和 >
中使用 extends
时,您指定了类型变量的范围。这里A<T extends B>
表示T
一定是类型(不是subclass)的B
。因此 extends
关键字可以根据其出现的上下文具有不同的含义。
这样做的原因是在不破坏代码的情况下向语言添加关键字并不容易。如果向语言添加新关键字(例如 subtype
),则使用 subtype
作为变量名的代码将无法编译。所以在 Java 1.5 中加入泛型时,他们选择重用关键字 extends
和 super
而不是添加新的关键字。
Now if I want to make an AudioManager using this interface it can be typed as T > extends IAudioEntity.
不,您可以扩展 classes 或实现接口。 IAudioEntity 是一个接口,因此您需要实现它。
或者您可以扩展 BaseAudioManager,它是一个class、实现 IAudioEntity。
或者你可以两者都做,但这基本上没有意义。
请注意,自从 java 8(有一天,它甚至可能达到 Android ;))以来,差异比以往任何时候都小,因为接口可以通过使用防御方法来引入代码。
所以我认为这更像是一个好奇的问题,而不是需要解决的问题。
所以我在 Android Studio 中与 AndEngine 坐在一起 Android,我想制作一个 AudioManager 来处理我的所有音频,作为开始。
我可以实现 AndEngine 的接口 IAudioManager 或扩展 BaseAudioManager,它已经是前面提到的接口的实现。这让我想到了我的问题。 IAudioManager 和 IAudioEntity:
public interface IAudioManager<T extends IAudioEntity> {
public float getMasterVolume();
public void setMasterVolume(final float pMasterVolume);
public void add(final T pAudioEntity);
public boolean remove(final T pAudioEntity);
public void releaseAll();
}
public interface IAudioEntity {
public void play();
public void pause();
public void resume();
public void stop();
public float getVolume();
public void setVolume(final float pVolume);
public float getLeftVolume();
public float getRightVolume();
public void setVolume(final float pLeftVolume, final float pRightVolume);
public void onMasterVolumeChanged(final float pMasterVolume);
public void setLooping(final boolean pLooping);
public void release();
}
现在,如果我想使用此接口创建一个 AudioManager,可以将其键入为 T extends IAudioEntity。但我认为您实现了接口而不是扩展它们,对吗?
所以我想知道在接口方面是否遗漏了什么。我不太喜欢 Java 但我在大学上过一门课所以我记得很多东西但细节可能很模糊,但这是否仅仅意味着这种情况下的实际语法并不重要因为它必须被实现才能被实例化,任何扩展 class 的东西都可以作为这个 AudioManager?
的参数它只是语法。在定义 class 时,您确实使用 implements
来指示 class 实现了一个接口,并使用 extends
来指示 class 是一个子 class 另一个 class。
在 <
和 >
中使用 extends
时,您指定了类型变量的范围。这里A<T extends B>
表示T
一定是类型(不是subclass)的B
。因此 extends
关键字可以根据其出现的上下文具有不同的含义。
这样做的原因是在不破坏代码的情况下向语言添加关键字并不容易。如果向语言添加新关键字(例如 subtype
),则使用 subtype
作为变量名的代码将无法编译。所以在 Java 1.5 中加入泛型时,他们选择重用关键字 extends
和 super
而不是添加新的关键字。
Now if I want to make an AudioManager using this interface it can be typed as T > extends IAudioEntity.
不,您可以扩展 classes 或实现接口。 IAudioEntity 是一个接口,因此您需要实现它。
或者您可以扩展 BaseAudioManager,它是一个class、实现 IAudioEntity。
或者你可以两者都做,但这基本上没有意义。
请注意,自从 java 8(有一天,它甚至可能达到 Android ;))以来,差异比以往任何时候都小,因为接口可以通过使用防御方法来引入代码。