CLASS:継承
継承とは
継承とはクラスに別のクラスをくっつけて、前のクラスからの
コードの引用で楽をしようという考えです。
継承はオブジェクト指向の中で一番中心的な存在とも言えます。
しかし、コードの引用だけではサブクラスへの拡張しか出来ません。
クラス継承の本当の意義というのは、後々出てくるインターフェースによって、
この継承機能の真価が見えてくることでしょう。
継承の長所と短所
まずは、継承の利点を挙げてみしょう。
1.コードの引用が簡単に出来る。
2.クラスのカプセル化を行うことで、クライアントに分かりやすい設計が行える。
3.一つ一つのクラスの状態が独立しており、他のプログラムに影響を与えない。
4.ポリモーフィズム概念による、クライアントへの考慮。
5.C++と違い、クラスの多重継承が出来ない。
6.安全性の高い設計が出来る。
逆に欠点としてあげるのであれば、
1.設計を間違えると難解なプログラムになってしまう。
2.Javaのクラスは全て参照型で、実体はヒープ領域に作られるため動作が遅い。
3.継承しすぎると難解である。
4.インターフェイスでしか、多重継承が出来ない。
といったところが欠点でしょう。
これらの長所や短所はJavaのテクニカルリファレンスの項を読むことで、
理解が出来るようになります。
継承:基本クラスと派生クラス
クラスを継承する時は、継承されるクラスと、継承するクラスがあります。
[継承されるクラス] → [継承するクラス]
これらのことをJavaでは、
[基本クラス] → [派生クラス]
と呼びます。
また、英語では、
[スーパークラス(Super Class)] → [サブクラス(Sub Class)]
と呼ばれています。
基本的に、基本クラス(Super Class)のメソッドやフィールド情報は、
派生クラス(Sub Class)に全て受け継がれています。
例外として、privateで宣言されているメソッドやフィールドは
一応継承されているのですが、隠蔽されて見えなくなっており、
明示的に指定してもコンパイルエラーを起こします。
この性質を上手く利用したもので、高速コンパイルテクニックで使ったりしますが、
少々難しい話なので、Javaテクニカルリファレンスの項を参照してください。
また、ポリモーフィズムとしての使い方としては、
基本クラスで仮宣言としておき、
様々な派生クラスでその機能を実装し、
それを基本クラスのポインタで参照することにより、
共通性を保つものとして使われます。
ポリモーフィズムの詳しい使い方は
Javaテクニカルリファレンスの項を参照してください。
実際に継承を利用したコード
------ExtendsClass.java--------
class SuperObject {
public void print(String str){
System.out.println(str);
}
}
public class ExtendsClass extends SuperClass {
public static void main (String args[]){
print("ABCDEF");
}
}
//ABCDEF
上記のコードはprintというメソッドを単純に機能継承したものです。
継承の予約コード
継承関連で使われる予約コードを一覧しておきます。
・extends
・implements
・private
・protected
・public
・abstract
・指定無し
・final
extends
extends はクラスの継承や、インターフェイスの継承を行う時に使います。
クラス継承は多重継承できないので、extendsでは単体でしか指定できません。
インターフェイスの継承は、extendsで多重継承することが出来ます。
しかし、クラスからインターフェイスにextendsすることはできません。
クラスの多重継承はサポートされていないからです。
(C++ではサポートされているため、問題が指摘されている)
クラス継承
class ClassName extends SuperClassName { }
インターフェイス継承
interface InterfaceName extends SuperInterfaseName1 , SuperInterfaceName2 {}
インターフェイスをクラスに取り込む時はextendsではなく、
implementsを使います。
それについては、インターフェイスの項にて説明したいと思います。
これもまた、多重的にインターフェイスをクラスへ引き込むことが出来ます。
private
プライベートアクセス子。
プライベートで指定したメンバの以下のような効果があります。
・指定されたメンバはクラス外部から見えなくなる。
・指定されたメンバは継承して派生したクラスからも見えなくなる。
・クラス内部からのアクセスはアクセスは可能。
・自分のクラス意外の全ての場所からのアクセスが不可能。
・クラス外からアクセスしようとした時は、コンパイルエラーが起きる。
・指定されたメンバを変更した時、そのクラスのみコンパイルがされるようになる。
使い方の例
private int method(int rhs) { }
private double vector;
protected
プロテクテッドアクセス子。
プロテクテッドで指定したメンバの以下のような効果があります。
・指定されたメンバは内部クラス、又は継承して派生したクラスからのみ見える。
・クラス内部からのアクセスはアクセスは可能。
・派生クラスからのアクセスはアクセスは可能。
・全く関係の無いクラスや、グローバルからのアクセスは不可能。
・クラス内部・派生クラス外からアクセスしようとした時は、コンパイルエラーが起きる。
・指定されたメンバを変更した時、そのクラス関連のコンパイルが起こる。。
使い方の例
protected int method(int rhs) { }
protected double vector;
public
パブリックアクセス子。
パブリックで指定したメンバは以下のような効果があります。
・全ての領域から見ることが出来る。
・全ての領域からのアクセスが可能。
・指定されたメンバを変更した時、他の関係ない部分も全てコンパイルが行われる。
使い方の例
public int method(int rhs) { }
public double vector;
指定無し
指定無しでメンバを宣言した場合、protectedと同じ効果が得れます。
しかし、通常のprotectedでは行えるパッケージ間のアクセスが出来ません。
パッケージに関しては後の、パッケージの項で説明します。
安全なアクセス子の順番としては、
private
指定無し
protected
public
となります。
使い方の例
int method(int rhs) { }
double vector;
abstract
アブストラクト。
仮想関数や仮想クラスを作る時に用います。
アブストラクトで指定したクラスやメンバは以下のような効果があります。
仮想クラス abstract class ClassName { }
・そのクラスの実体(インスタンス)そのままでは生成が出来なくなる。
・実体化させるには派生させるしかない。
・インターフェイスと違い、メソッドに実装を持たせることが出来る。
・インターフェイスと違い、多重継承は出来ない。
仮想メソッド abstract type MethodName ( ) { }
・そのメソッドを明示的に仮想関数として扱う。
・アブストラクトメソッドはそのままでは使えない。
・アブストラクトメソッドは必ず派生クラスでオーバーライドしなければならない。
ちなみに、フィールドをアブストラクト化することはできません。
やっても意味がないのでしかたないのですが。
こういったabstract指定のクラスを一般に抽象クラスと言い、
abstractメソッドのことを実体を持たない関数、即ち仮想関数と呼ばれています。
この仮想関数や仮想クラスは後に出てくるオブジェクト指向の考え方の一つ、
ポリモーフィズムと呼ばれる概念を用いる時に使われます。
ポリモーフィズムについては、Javaテクニカルリファレンスの項を参照してください。
使い方の例
abstract class Object { }
abstract int method(int rhs);
final
ファイナルは、クラスの継承をストップさせる時に使います。
また、メソッドのオーバーライドを行う時や、
フィールドを変更したくない時に定数として扱ったりするために用います。
使い方の例
public final int method(int rhs) { }
public final double vector;
final class ClassName { }