クラスと一緒に継承する
クラスの場合、2つのスーパークラスから1つのサブクラスを作ることはできませんでした。
ところが、インタフェースはそんな制限がありません!
たとえば、1つのクラスと1つのインタフェースから1つのサブクラスを継承することができるのです!
/**
* 計算をするインタフェース。
*/
interface CalcInterface
{
/**
* 抽象メソッド。
*/
int calc( int lh, int rh );
}
/**
* 足算機能を持つクラス。
*/
class AddSuper
{
/**
* 足算します。
*/
int add( int lh, int rh )
{
return lh + rh;
}
}
/**
* CalcInterfaceインタフェースの実装クラスでかつ
* Addクラスのサブクラス。
*/
class ImplementedAndSub extends AddSuper implements CalcInterface
{
/**
* 抽象メソッドをオーバーライドします。
*/
public int calc( int lh, int rh )
{
// スーパークラスが持つadd()メソッドを使います。
return add( lh, rh );
}
}
/**
* 実行用クラス。このクラスを実行してください。
*/
class ImplementedAndSubRunner
{
public static void main( String[] args )
{
// ImplementedAndSubクラスのインスタンスを1つ作ります。
// 参照型変数はCalcInterfaceクラスです。
CalcInterface ref = new ImplementedAndSub();
// 実装したメソッドを呼び出します。
int i = ref.calc( 100, 200 );
System.out.println( i );
// 実行結果:
// 300
}
}
// ImplementedAndSubRunner.java /** * 計算をするインタフェース。 */ interface CalcInterface { /** * 抽象メソッド。 */ int calc( int lh, int rh ); } /** * 足算機能を持つクラス。 */ class AddSuper { /** * 足算します。 */ int add( int lh, int rh ) { return lh + rh; } } /** * CalcInterfaceインタフェースの実装クラスでかつ * Addクラスのサブクラス。 */ class ImplementedAndSub extends AddSuper implements CalcInterface { /** * 抽象メソッドをオーバーライドします。 */ public int calc( int lh, int rh ) { // スーパークラスが持つadd()メソッドを使います。 return add( lh, rh ); } } /** * 実行用クラス。このクラスを実行してください。 */ class ImplementedAndSubRunner { public static void main( String[] args ) { // ImplementedAndSubクラスのインスタンスを1つ作ります。 // 参照型変数はCalcInterfaceクラスです。 CalcInterface ref = new ImplementedAndSub(); // 実装したメソッドを呼び出します。 int i = ref.calc( 100, 200 ); System.out.println( i ); // 実行結果: // 300 } }
まず最初にCalcInterfaceインタフェースがあります。
* 計算をするインタフェース。
*/
interface CalcInterface
{
/**
* 抽象メソッド。
*/
int calc( int lh, int rh );
}
/** * 計算をするインタフェース。 */ interface CalcInterface { /** * 抽象メソッド。 */ int calc( int lh, int rh ); }
このインタフェースはcalc()メソッドを持っています。
「calc」、つまり「計算」をする抽象メソッドということで、実際に「どんな計算をするのか」は、実装するメソッド任せということにします。計算をポリモーフィズムさせるわけですね。
さてここに、「足算機能を持つAddSuperクラス」が元々あったとします。
* 足算機能を持つクラス。
*/
class AddSuper
{
/**
* 足算します。
*/
int add( int lh, int rh )
{
return lh + rh;
}
}
/** * 足算機能を持つクラス。 */ class AddSuper { /** * 足算します。 */ int add( int lh, int rh ) { return lh + rh; } }
このAddSuperクラスは足算をするadd()メソッドを持っています。このメソッドは、CalcInterfaceインタフェースの実装クラスとして使えそうです。
AddSuperクラスをCalcInterfaceインタフェースの実装クラスにしたい……そういう場合には、AddSuperクラスのサブクラスを作り、さらにそれをCalcInterfaceインタフェースの実装クラスにします。
* CalcInterfaceインタフェースの実装クラスでかつ
* Addクラスのサブクラス。
*/
class ImplementedAndSub extends AddSuper implements CalcInterface
{
/**
* 抽象メソッドをオーバーライドします。
*/
public int calc( int lh, int rh )
{
// スーパークラスが持つadd()メソッドを使います。
return add( lh, rh );
}
}
/** * CalcInterfaceインタフェースの実装クラスでかつ * Addクラスのサブクラス。 */ class ImplementedAndSub extends AddSuper implements CalcInterface { /** * 抽象メソッドをオーバーライドします。 */ public int calc( int lh, int rh ) { // スーパークラスが持つadd()メソッドを使います。 return add( lh, rh ); } }
ImplementedAndSubクラスはAddSuperクラスのサブクラスです。
そして同時にCalcInterfaceインタフェースの実装クラスです。
このように、インタフェースの実装は、クラスの継承と同時に行うことができるのです!
あとはこれまでと同じように使うだけです。
// 参照型変数はCalcInterfaceクラスです。
CalcInterface ref = new ImplementedAndSub();
// ImplementedAndSubクラスのインスタンスを1つ作ります。 // 参照型変数はCalcInterfaceクラスです。 CalcInterface ref = new ImplementedAndSub();
まずImplementedAndSubクラスのインスタンスを作り、CalcInterfaceインタフェースの参照型変数で受け取ります。
そしてインタフェースの抽象メソッドを通して実装クラスのメソッドを呼び出します。
int i = ref.calc( 100, 200 );
System.out.println( i );
// 実行結果:
// 300
// 実装したメソッドを呼び出します。 int i = ref.calc( 100, 200 ); System.out.println( i ); // 実行結果: // 300
そのメソッドの中で、スーパークラスが持っていたメソッドを呼び出します。
このように、インタフェースはクラスの継承関係のような制限がありません。
実はここに、インタフェースの特徴があるのです。