📚

プログラミング自主学習 DAY53 Interface

2023/07/19に公開

形変換

アップキャスト(自動形変換)

B b = new B();
C c = new C();
D d = new D();
E e = new E();


A a;

a= b;
a= c;
a= d;  OK!
a= e;  OK! 

ダウンキャスト(強制形変換)

具象クラスの固有のメソッドを呼びだすためには、またキャストすれば良い。
Vehicleを具象したBusクラスのケースだ。

CastingExample

public class CastingExample {

	public static void main(String[] args) {
		
		Vehicle vehicle = new Bus();
		
		//Before Casting
		vehicle.run();
		//bus.checkFare(); X
		
		//After Casting
		Bus bus = (Bus) vehicle;
		bus.run();
		bus.checkFare();

	}

}


多態性(ポリモーフィズム)

フィールド

同じスパクラスを継承したサブクラスが、スパクラスの変数を通して、代替できるように、
同じインタフェースを具象したクラス同士はインタフェース変数を通して、代替できる。

Car
public class Car {
	//field
	Tire tire1 = new HankookTire();
	Tire tire2 = new HankookTire();

	//method
	void run() {
		tire1.roll();
		tire2.roll();
	}
}

CarExample

public class CarExample {

public static void main(String[] args) {
   // Tireのオブジェクト生成
 Car myCar = new Car();
		
 // run() メソッド呼び出し
 myCar.run();
		
System.out.println();
		
// Tireのオブジェクト交換
myCar.tire1 = new KumhoTire();  
myCar.tire2 = new KumhoTire();

// run() メソッド呼び出し
myCar.run();
	}

}

<result>

HankookTire is Rolling.  // HankookTire@tire1.roll(); 
HankookTire is Rolling.  // HankookTire@tire2.roll();

HankookTire is Rolling.  //KumhoTire@tire1.roll();
HankookTire is Rolling.  //KumhoTire@tire2.roll();

パラメータ

継承と同様、同じインタフェースを具象したクラスのオブジェクトは、パラメータに入ると自動形変換により、オーバーライドしたメソッドを呼び出す。

public class Driver {
	void drive(Vehicle vehicle) {
		vehicle.run();
	}
}
DriverExample
public class DriverExample {

	public static void main(String[] args) {
	    
	    Driver driver = new Driver();	
	
	    //同じVehicleをimplementしたCar,Busクラスのインスタンス化
	    Bus bus = new Bus();
	    Taxi taxi = new Taxi();

	    //パラメータのポリモーフィズムにより、異なる機能。
	    driver.drive(bus);
	    driver.drive(taxi);
	    
	    
	}

}

<result>
バスが走ります。
タクシーが走ります。



オブジェクトのタイプ確認

継承と同様、booleanタイプにリータンする演算子、instanceofで確認できる。
これにより、パラメータに入るオブジェクトの中、特定のクラスのオブジェクトをダウンキャストすることで、インタフェースのメソッドのみならず、具象クラス固有のメソッドも呼び出しすることができる。


public class InstanceOfExample {

public static void main(String[] args) {
   //2.Vehicleの具象クラスのオブジェクト生成
   Taxi taxi = new Taxi();
   Bus bus = new Bus();
		
   //3.ride() メソッド呼び出し時、具象オブジェクトをパラメータにする。
   ride(taxi);
   System.out.println();
   ride(bus);
		
		
    }
    public static void ride(Vehicle vehicle) {
    if(vehicle instanceof Bus) {
      Bus bus  = (Bus) vehicle;  
      //1.Vehicleにアップキャストされたbusのオブジェクトを元に戻す。
      bus.checkFare();
     }
   }
	
}

                    <-rideメソッドの結果(taxiのオブジェクト)
Check fare     <-rideメソッドの結果(busのオブジェクト)

sealed (Java 15)

インタフェースもクラスの継承のように、元のインタフェースにsealedを、継承させるインタフェースにpermitを付けることで、インタフェースの継承を制限することができる。

継承したインタフェースはsealedもしくはnon-sealedを付けることで、継承の不可を決めることができる。

Interface

public sealed interface Interface permits Interface2 {
	void method1();    //grandparent
}

Interface2
public non-sealed interface Interface2 extends Interface{
	void method2();   //parent
}

Interface3
public interface Interface3 extends Interface2 {
	void method3();   //grandson
}
ImpClass

public class ImpClass implements Interface3{
	@Override
	public void method1() {
		System.out.println("this is method1");
	}
	
	@Override
	public void method2() {
		System.out.println("this is method2");
	}
	
	@Override
	public void method3() {
		System.out.println("this is method3");
	}

}

SealedExample
public class SealedExample {

	public static void main(String[] args) {
		ImpClass imp = new ImpClass();
		
		Interface interface1= imp;
		interface1.method1();
		
		System.out.println();
		
		Interface2 interface2 = imp;
		interface2.method1();
		interface2.method2();
		
		System.out.println();
		
		Interface3 interface3 = imp;
		interface3.method1();
		interface3.method2();
		interface3.method3();
		
	}

}


<result>
grandparents

grandparents
parents

grandparents
parents
grandson

Discussion