JAVAプラットフォームのインタフェース

8810 ワード

JAVAプラットフォームのインタフェースクラスはC中のライブラリに比べている.外部プログラムの参照のために所望の機能を実現するAPIを対外的に提供する.外部APIと機能を事前に「約束」すれば、上層開発とライブラリ開発を同時に行うことができる.この「約束」はJAVAプラットフォームのマクロ抽象に似ている.
 
1.JAVAプラットフォームのインタフェースの特性:
    1).JAVAプラットフォームのインタフェースには定数、メソッド署名、ネストタイプしか含まれません.
    2).インタフェースは2つの部分に分けられます:宣言と実装体、インタフェース宣言の中でメソッド体の実装がなくて、メソッド体の実装はクラスの中にあります;
    3).JAVAプラットフォームのインタフェースにはコンストラクタがないため、インスタンス化することができず、クラスによって実現されるか、他のインタフェースによって継承されるしかない.
    4).JAVAの1つのクラスは1つの親からしか継承できないが、インタフェースは多重継承できる. 
 
2.インタフェースを定義する構文:
インタフェースを定義する構文の形式は次のとおりです.
 
[   ] interface      [extends        ]{
    //   
}

    1).修飾子:オプションで、publicまたはprotectedまたはprivateを使用できないインタフェースへのアクセス権を指定します.何もない場合は、デフォルトのアクセス権は現在のパッケージで使用されます.
    2).interface:インタフェースのキーワードを定義します.
    3).インタフェース名:インタフェース名の頭文字が大文字です.
    4).extends:親インタフェース名のリスト:オプションで、インタフェースがどの親インタフェースから継承されるかを指定します.マルチ継承の場合は、親インタフェース間をカンマで区切る必要があります.次のようになります.
public interface GroupedInterface extends Interface1,Interface2,Interface3{
    //   
}

 
3.インタフェースの構成:
インタフェースは、定数宣言+メソッド宣言の2つの部分から構成される.
    3-1.インタフェースの構文:
    [   ] interface      [extends        ]{

        //    

        [public] [static] [final]     ;

        //    

        [public] [abstract]          ;

    }

    1).定数宣言:インタフェースのすべてのフィールドにpublic、static、finalプロパティが隠されています.
    2).メソッド宣言:インタフェース内のメソッドは、戻りタイプとメソッド署名のみで、メソッドボディはありません.暗黙属性はpublic、abstractを有する.
次のようになります.
public interface GroupedInterface extends Interface1,Interface2,Interface3{
    //    
   double E = 2.718282;
    //          public static final double E = 2.718282
    //    
    void doSomething(int i,double x);
    int doSomethingElse(String s);
}

4.実装インタフェース
上記から分かるように、インタフェースの最も核心的な部分はやはり方法体の実現である.インタフェースにはメソッドの宣言しかなく、メソッドの具体的な実現はない.インタフェースにおける方法の具体的な実現はクラス内で実現する必要がある.インタフェースを実現する方法体のクラスを「インタフェースクラス」と呼ぶことができる.
    4-1.インタフェースクラスの構文:
インタフェースクラスを宣言するには、クラスの宣言にimplementsキーワードを使用する必要があります.1つのインタフェースクラスは複数のインタフェースを実現できるので、implementsキーワードの後に被クラスインタフェースのリストとカンマ区切りで区切る.構文の形式は次のとおりです.
[   ] class     [extends     ] implement     {
    //  
   //            
}

    4-2.例:
次に、異なるオブジェクトサイズのインタフェースインスタンスRelatableを比較する.インタフェースRelatableでは、Relatableインタフェースを実装オブジェクトと比較する役割を果たすisLargerThanメソッドを宣言する.
    1).Relatableインタフェースは次のように宣言されています.
public interface Relatable{
    public int isLargerThan(Relatable other);
}

    2).実装インタフェースクラス:
public class RectanglePlus implements Relatable {
    public int width = 0;						//        
    public int height = 0;
    public Point origin;						//      

    //      
    public RectanglePlus() {
		origin = new Point(0, 0);
    }
    public RectanglePlus(Point p) {
		origin = p;
    }
    public RectanglePlus(int w, int h) {
		origin = new Point(0, 0);
		width = w;
		height = h;
    }
    public RectanglePlus(Point p, int w, int h) {
		origin = p;
		width = w;
		height = h;
    }

    //        
    public void move(int x, int y) {
		origin.x = x;
		origin.y = y;
    }

    //          
    public int getArea() {
		return width * height;
    }
    
    //     Relatable      
    public int isLargerThan(Relatable other) {
    		RectanglePlus otherRect = (RectanglePlus)other;	//      
    		if (this.getArea() < otherRect.getArea())		//                  
    			return -1;									//  -1
    		else if (this.getArea() > otherRect.getArea())	//                  
    			return 1;									//  1
    		else
    			return 0;    								//                ,  0
    }
}

    3).テストプログラム
public class ImlDemo1{
	public static void main(String[] args){
		RectanglePlus rect1 = new RectanglePlus(3,5);	//     Relatable   RectanglePlus  
		RectanglePlus rect2 = new RectanglePlus(2,7);	//     Relatable   RectanglePlus  
		int result = rect1.isLargerThan(rect2);			//               
		switch(result){									//       ,       
			case -1:
				System.out.println("  rect1   rect2 。");
				break;
			case 1:
				System.out.println("  rect1   rect2 。");
				break;
			default:
				System.out.println("  rect1   rect2    。");
		}
}
}

    4).インタフェース付きインスタンスのコンパイルと実行
上記の4種類がある:Pointクラス、RectanglePlusクラス、メインクラスImlDemo 1およびインタフェースRelatable.このインスタンスを実行するには、次の2つの形式があります.
A.4種類をそれぞれ独立ソースファイルとして保存する(ファイル名はpublicクラス名と同じでなければならない).4つのソースファイルを同じディレクトリの下に置く.そして、コマンドでImlDemo 1をコンパイルする.java;
B.4つのタイプを同じソースファイルに配置し、1つのpublicクラスのみを保持する(ファイル名はpblicクラス名と同じでなければならない).そしてコンパイルする.
 
5.複数のインタフェース
JAVAプラットフォームは、複数のインタフェースが多重継承されているためである.1つのクラスが実装2つのインタフェースのうち、2つのインタフェースが同じ名前の定数または同じ名前のメソッドを宣言場合、この2つのインタフェースを実装クラスで定数または実装メソッドを参照する場合、どのインタフェースのものであるかは不明である.これはインタフェースの衝突問題です.定数の競合の場合は、クラス内で定数が属するインタフェースを明示的に指定するには、フルリミット名(インタフェース名.定数名)を使用する必要がある.方法の衝突であれば、一つの方法を実現するだけでよい.
例:
//    Calculate.java 
public interface Calculate {	   
   float PI = 3.14f;				//              PI
   float getArea( );				//             
   float getGirth( );				//             
}

 
//    Shape.java 
public interface Shape{	   
   float PI = 3.14159f;				//              PI
   float getArea( );				//             
   void draw( );					//           
}

 
//    Circle.java 
public class Circle implements Calculate,Shape {

   //        radius,      
   private float radius;

   //   ,       radius
   public Circle(float r){
	radius = r;
   }

   //          ,          ,        
   public float getArea( ){
	 float area = Calculate.PI*radius*radius;	//      ,        Calculate      
	 return area;
   }

   //          
   public float getGirth ( ){
	 float circuGirth = 2*Shape.PI*radius ;	//      ,        Shape      
	 return circuGirth;
   }

   //         
   public void draw( ){
	 System.out.println("         !");
   }

}

 
//    ImlDemo2.java 
public class ImlDemo2 {	   
   public static void main(String[ ] args){
   	 Circle circle = new Circle(7);
	 float area = circle.getArea( );
	 System.out.println("     :" + area);
	 float girth = circle.getGirth();
	 System.out.println("     :" + girth);
	 circle.draw( );
   }
}

簡単な分析:
CircleでJAvaでは、クラスShapeの定数PIを参照します.文「Shape.PI」で指定します.
 
6.インタフェースをタイプとして使用
インタフェースはintなどと同様にデータ型と見なすことができる.例えば、インタフェースタイプの参照変数を定義すると、この変数に付与任意のオブジェクトは、このインタフェースを実現するクラスの一例でなければならない.
例:
public  Object findLargest(Object object1,Object object2){
    Relatable obj1 = (Relatable)object1;
    Relatable obj2 = (Relatable)object2;
    if((obj1).isLargerThan(obj2) > 0)
        return object1;
    else
        return object2;
}

簡単な分析:
上記の例では、object 1、object 2は、Relatableインタフェースを実現するクラスのインスタンスオブジェクトである必要がある.
したがって、オブジェクトインスタンスの実装を捨てる、どのように継承するかは、指定されたインタフェースが実現する限り、「部分的特徴」の比較操作を行うことができる.
 
7.インタフェースの書き換え
1つのインタフェースが宣言すると、何らかの理由でインタフェース内の宣言の方法(例えば、新しい方法を追加したり、方法体の実装を変更したりするなど)を修正する必要がある可能性がある.次のような状況です.
プログラム猿AはDoItというインタフェースを作成しました.
public interface DoIt{
    void doSomething(int i,double x);
    int doSomethingElse(String s);
}

ある理由から、プログラム猿Aはこのインタフェースに3つ目の方法を追加しなければならない.次のようになります.
public interface DoIt{
    void doSomething(int i,double x);
    void doSomethingElse(String s);
    boolean didItWork(int i,double x,String s);
}

この場合、古いインタフェースでは新しいインタフェースを使用することができない.この場合、最も適切な方法は、元のインタフェースを動かさずに、元の古いインタフェースから新しいインタフェースを派生させ、新しいインタフェースに3つ目の方法を追加することである.次のようになります.
public interface DoItPlus extends DoIt{
    boolean didItWork(int i,double x,String s);
}

他の人は古いインタフェースを選択することもできるし、新しいインタフェースにアップグレードすることもでき、インタフェースプログラムが使用できない場合を避けることができる.