📚
プログラミング自主学習 DAY53 Interface
形変換
アップキャスト(自動形変換)
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