この記事には複数の問題があります。改善
やノートページでの議論にご協力ください。抽象化(ちゅうしょうか、英: Abstraction)は、計算機科学において詳細を捨象し、一度に注目すべき概念を減らすことおよびその仕組みである。
この概念は数学における「抽象化」からのアナロジーである。数学での抽象化技法の起源は数学的定義である。例えば、コンピュータでも数学でも、数はプログラミング言語上の概念であり、数学上の概念でもある。数の計算概念は数学の概念に基づいているため、実装の詳細はハードウェアとソフトウェアに依存したとしても、それが制約とはならない。
大まかに言えば、抽象化は制御抽象化とデータ抽象化に分けられる。制御抽象化は動作の抽象化であり、データ抽象化はデータ構造の抽象化である。例えば、構造化プログラミングでの制御抽象化とは、サブプログラムや定式化された制御フローの使用を意味する。データ抽象化とは、本来ビット列であるデータを意味のある方法で扱うことを意味する。例えば、データ型の背景にある動機は抽象化である。オブジェクト指向プログラミングはデータとコードを同時に抽象化する試みと見ることもできる。 コンピューティングの大部分は実世界とは独立している。ハードウェアは計算モデルを実装したものであり、他のモデルとの入れ替えが可能である。ソフトウェアはソフトウェアアーキテクチャで構築され、人間が一時に一部の問題に集中することで巨大なシステムを生み出すことを可能にしている。このようなアーキテクチャは特定の抽象化を選択して利用している。グリーンスパンの10番目の規則
原理
コンピューティングでの主な抽象化は言語の抽象化である。新たな人工言語はシステムの特定の観点を表現するために開発される。モデリング言語は計画立案を補助する。コンピュータ言語はコンピュータで処理できる。このような抽象化プロセスの例として、プログラミング言語の世代的開発が挙げられる。各世代は次の世代の基盤となった。言語の抽象化は現在も続いており、例えばスクリプト言語やドメイン固有言語でこの進化が著しい。
プログラミング言語では、一部機能によってプログラマが新たな抽象化を生み出せるようにしている。例えば、サブルーチン、モジュール、ソフトウェアコンポーネントなどがそれである。プログラミング言語自体の機能ではないが、設計技法上の抽象化としてデザインパターンやソフトウェアアーキテクチャがある。
抽象化によっては、次々に構築される概念を完全に隠蔽することでプログラマが把握しなければならない概念の幅を制限しようとする。Joel Spolskyは、あらゆる抽象化は破綻しやすいと主張して批判した。つまり、抽象化によって下部構造が完全に隠蔽できたためしがないというのである。一部の抽象化は他との相互のやりとりのために設計されている。例えばプログラミング言語には外部関数インタフェースを持つものもあり、低レベルな言語を呼び出すことができる。
言語機能
プログラミング言語詳細は「プログラミング言語」を参照
プログラミング言語は、その言語の応用分野によってそれぞれ異なる抽象化を行う。例えば、次のような抽象化がある:
オブジェクト指向プログラミング言語(C++、Javaなど)での抽象化の概念は、必要に応じて virtual や abstract といったキーワードを使って宣言することである。このような宣言をした後、プログラマはその宣言に沿ってオブジェクトをインスタンス化するためにクラスを実装しなければならない。
関数型言語では、関数に関連した抽象化が一般的である。例えばラムダ計算、高階関数などである。
Lindaという言語では「サーバ」や「共有データ空間」といった概念を抽象化し、分散プログラミングを実現する。
仕様記述言語詳細は「仕様記述言語」を参照
仕様記述言語は一般に何らかの抽象化に基づいている。仕様はプロジェクトの初期に定義されるもので、最も抽象的なレベルであり、それが最終的に実装される。例えば仕様記述言語であるUMLは「抽象」クラスを定義でき、プロジェクトの仕様設計段階ではそれらは「抽象」のままである。
制御抽象化詳細は「制御構造」を参照
制御抽象化はプログラミング言語を使う主たる目的の1つである。コンピュータが理解する操作は極めて低レベルであり、メモリのある場所から別の場所へ何ビットかを移動させ、2つのビット列を加算するといったことでしかない。プログラミング言語を使うことでこれをもっと高いレベルに変換する。例えば、次のようなプログラム内の文(式)があるとする。a := (1 + 2) * 5
人間にとっては、これは非常に単純で明らかな計算である(1 足す 2 は 3、これに 5 をかけて 15)。しかし、これを評価するには低レベルの実行ステップに落とし込まねばならないし、計算結果である 15 を変数 "a" に代入するという作業も複雑である。数値は二進数表現に変換され(これも大方の予想よりも複雑な作業である)、(コンパイラやインタプリタが)計算をステップに分解して機械語の命令列に直す(機械語あるいはアセンブリ言語は一般のプログラマにとっては直観的に理解可能なものではなく、その内容は通常の加算や乗算といった人間の考える算術とは趣きが異なる)。そして、計算結果の "15" を "a" というラベルの付いた変数に格納するが、実際には物理メモリか仮想メモリ上のあるアドレスのメモリ位置がそれに対応しており……などなどである。
制御抽象化なしでは、プログラマは機械語レベルでレジスタやメモリアドレスを指定してプログラムを書かねばならない。その場合2つの深刻な結果を招く。第1に似たような機能を毎回コーディングしなおさなくてはならなくなる。第2にプログラマは特定のハードウェアや命令セット向けにプログラムを書くしかなくなる。
構造化プログラミング詳細は「構造化プログラミング」を参照
構造化プログラミングでは、複雑なプログラム作業を小さい部分に分割し、コンポーネント間に明確なインタフェースと制御フローを導入し、副作用的に複雑さを低減させる。
単純なプログラムでは、ループからの脱出点を明示的に1つにするようコーディングするとか、関数や手続きからの脱出点を1つにするといった工夫である。
大きなシステムでは、複雑なタスクを多数のモジュールに分割することになるだろう。例えば、港湾事務所での船員への給与支払い業務システムを考えてみよう。