見出し画像

JavaSilverに向けて⑨ クラスの継承、インターフェース、抽象クラス

・継承の特徴


コンストラクタとprivateなフィールドやメソッドは継承を使っても以下のものは引き継がれない。
そのため、以下のようにスーパークラスでコンストラクタが定義されていてもサブクラスには継承されない。以下のような場合はコンパイルエラーとなる。
class superSample {
    superSample(String str) {
        //処理
    }
}
class Sample extends superSample { }

public class Main {
    public static void main (String[] args) {
        Sample s = new Sample(“hello”);
    }
}

・メソッドのオーバーライド


メソッドをオーバーライドする際には、以下の3つの項目を守る必要がある。
1、シグニクチャが同じである事
2、戻り値が同じか、サブクラス型である事
3、アクセス修飾子は同じか、より緩いものである事


・インターフェースの特徴


  ー 他のクラスからの扱い方を規定したもの。
  ー メソッドにアクセス修飾子を記述しなくても、コンパイラによって自動的にpublicで修飾される。
  ー 抽象メソッドは、protectedやprivateで定義する事はできない。
  ー インターフェースはインスタンス化する事はできない。
  ー インターフェースでは、多重継承する事が可能。クラスは多重継承する事が不可。
public class A implements InterfaceA, InterfaceB { }
  ー インターフェースでは、メソッドを宣言する事ができるが、処理を書く事ができない。
  ー インターフェースでフィールドを宣言する場合は以下の点を守る必要がある。
finalで宣言されている(定数)。
staticでインスタンスが生成できなくても使える。

・defaultメソッド


interfaceでdefaultメソッドを使う事で、処理内容を実装したメソッドを定義する事ができるようになった。
以下では、Sampleクラスではメソッドをオーバーライドしていないが、defaultメソッドを作成する事でコンパイルエラーにはならない。

interface InterfaceSample {
    default String greeting() {
        return “Hello”;
    }
}
class Sample implements InterfaceSample {
}
public class Main {
    public static void main(String[] args) {
        Sample s = new Sample();
        System.out.println(s.greeting());
    }
}
//Hello

・defaultメソッドの多重継承(暗黙的なメソッド)


メソッドの名称が同じで重複が生じた場合、どちらのメソッドが呼び出されるかは優先順位によって異なる。
メソッドを呼び出しているクラスから最も近い位置にあるメソッドが優先順位が高くなる。

interface InterfaceKyoto {
    default String greeting() {
        return “Hello Kyoto”;
    }
}
interface InterfaceTokyo extends InterfaceKyoto {
    default String greeting() {
        return “Hello Tokyo”;
    }
}
interface InterfacePref extends InterfaceKyoto {
}
class Pref implements InterfaceTokyo, InterfacePref {
}
public class Main {
    public static void main(String[] args) {
        Pref pf = new Pref();
        System.out.println(pf.greeting());
    }
}
//Hello Tokyo

・defaultメソッドの多重継承(明示的なメソッド)


以下では、Prefクラスでオーバーライドする際、superを使い、呼びたい方を選んでいる。以下では、TokyoではなくOsakaを明示的に呼び出している。
defaultメソッドをオーバーライドしたメソッドから元ののdefaultメソッドを呼び出す際は以下のように書く。
インターフェース名.super.メソッド名();

interface InterfaceKyoto {
    default String greeting() {
        return “Hello Kyoto”;
    }
}
interface InterfaceTokyo extends InterfaceKyoto {
    default String greeting() {
        return “Hello Tokyo”;
    }
}
interface InterfaceOsaka extends InterfaceKyoto {
    default String greeting() {
        return “Hello Osaka”;
    }
}
class Pref implements InterfaceTokyo, InterfaceOsaka {
    @Override
    public String greeting() {
        return InterfaceOsaka.super.greeting();
    }
}
public class Main {
    public static void main(String[] args) {
        Pref p = new Pref();
        System.out.println(p.greeting());
    }
}
//Hello Osaka

・interfaceとstatic
staticを使う事で、defaultと同様、処理内容を記載する事ができる。
defaultと違うのは、継承クラスを実装する必要がない点である。

interface InterfaceTokyo {
    public static String greeting() {
        return “Hello Tokyo”;
    }
}
public class Main {
    public static void main(String[] args) {
        System.out.println(InterfaceTokyo.greeting());
    }
}
//Hello Tokyo

この記事が気に入ったらサポートをしてみませんか?