class クラス名1 extends クラス名2{ }
という記述で継承していきます。
クラス名1はクラス名2のサブクラス、クラス名2はクラス名1のスーパークラスになります。
継承のソースと継承の図
#codeprettify{{
class x{ int i; } class x1 extend x{ int i2; } class x2 extend x1{ int i3; } class x3 extend x1{ int i4; }
}}
x x1のsuper class x1がxを継承 ↓ x1 xのsub class x2とx3のsuper class ┌──┴──┐ ↓ ↓ x2がx1を継承 x3がx1を継承 ↓ ↓ x2 x3 x1のsub class x1のsub class
なので
x2.i; x4.i2; x2.i3;
という値の参照が可能
継承関係にあるクラス内で同じ名前の変数がある場合、継承先の変数に隠される。
隠された変数を参照したい場合はsuper.をつけると参照できる
継承のソースと継承の図
#codeprettify{{
class x{ int i; } class x1 extend x{ int i2; } class x2 extend x1{ String i; } class x3 extend x1{ int i4; }
}}
この場合、Xにi,x2にiがあります。
しかし、x2はxを継承しています。継承先です。
継承先の変数は継承元と同じ変数名のものを隠してしまうので
x2.iとやってもiはString型として扱われます。
#codeprettify{{
class x1{ int i = 1; } class x2 extends x1{ int i = 2; void display(){ System.out.println(i); //x2.iを参照している System.out.println(super.i); //こうすると、x2.iではなくx1.iを参照する } } class mainprg{ public static void main(String args[]){ x2 xx = new x2(); xx.display(); } }
}} 継承関係にあるなかで、メソッドがオーバーライドしている場合、 型(引数とか)をみてメソッドを実行します。
#codeprettify{{
class a1{ void hello(){ System.out.println("hello! a1"); } } class b1 extends a1{ void hello(int i){ System.out.println("hello! b2"); } } class c1 extends b1{ void hello(){ System.out.println("hello! c2"); } } class hello_out{ public static void main(String args[]){ a1 obj new c1(String s); obj.hello(); } }
}}
といった場合、当てはまるものはb1のhelloメソッドです。
a1,b1,c1のhelloメソッドがすべて
#codeprettify{{
void hello{ System.out.println("hello! メソッド名"); }
}} で、上記のソースの場合はc1のhelloメソッドが呼び出されます。
継承関係にあるもののコンストラクタを呼ぶ場合、
スーパークラスのコンストラクタも呼ばなければなりません。
スーパークラスのコンストラクタの呼び方は
super(引数:省略可);
です。
スーパークラスのコンストラクタの呼び出しは、サブクラスのコンストラクタの
最初のステートメントで行わないといけません。
先にスーパークラスのコンストラクタを呼び出すことによりコンパイルエラーを防げるので。