試験と現実のギャップ(Feat. OOP)
2025年05月06日
資格の勉強をしている。何の資格かって?
2020年に改訂される前までは「誰でも取れる」とまで言われていた、情報処理技術者試験だ。
※これは日本でいうところの「基本情報技術者試験(FE)」に相当する国家資格で、ITエンジニアの登竜門とされている。
過去問を解いていたとき、こんな問題が出てきた。
オブジェクト指向において、情報隠蔽と最も密接な関係にあるのはどれか?
- カプセル化(Encapsulation)
- クラス(Class)
- メソッド(Method)
- インスタンス(Instance)
正解は「カプセル化(Encapsulation)」だった。
正解はしたけど、なんとなくモヤモヤが残った。その理由は、自分がPythonエンジニアだからだ。
Pythonでは、カプセル化が明示的なアクセス制御なしに、クラスとメソッドの組み合わせによって暗黙的に実装されることが多い。
つまり、カプセル化という概念が独立しているというより、クラスの文脈において慣習的に使われる“擬似的な封装”のようなものに近い。
じゃあ、Python的なオブジェクト指向を前提にすれば、この問題は複数正解になるのか?
いや、ならない。
Pythonにおけるカプセル化は、情報隠蔽とはほぼ無関係だ。
もちろん __(ダブルアンダースコア) やデコレーターを使えば「隠している風」に見せることはできるけど、C++やJavaのようにアクセス修飾子が存在しない以上、本来の意味での情報隠蔽は成り立たない。
だからこの問題を見たとき、自分は「カプセル化」でも「クラス」でもなく、抽象化(Abstraction)を思い浮かべた。
PythonのOOP文脈で言えば、最も近いのはそれだと思ったから。
問題の解説にはこう書かれていた。
「カプセル化されたオブジェクトは、内部の詳細を外部から隠すことができるため、情報隠蔽と密接な関係がある」
でも本当にそうなのか?
Javaの例を見てみよう。
public class User {
public String name;
public int balance;
}
このようなクラスは存在しているが、カプセル化されていないとされる。
public class User {
private String name;
private int balance;
public String getName() { return name; }
public int getBalance() { return balance; }
}
このようにゲッターで外部からのアクセスを制御して初めて、「カプセル化されたクラス」と言えるらしい。
じゃあPythonでは?
class User:
def __init__(self):
self.balance = balance
このコードは、クラスでもあり、カプセル化でもある。
そして情報隠蔽を意識するなら、こう書くだろう。
class User:
def __init__(self, balance):
self.__balance = balance
def get_balance(self):
return self.__balance
account = User(1000)
print(account.get_balance())
こういった書き方(__アンダースコアやデコレーターなど)で、ある程度の“情報隠蔽っぽいこと”は可能かもしれない。
でもこれはあくまで“情報を隠したいから書いたコード”であって、完全な情報隠蔽でもないし、Javaで言うところの「カプセル化されたクラス」とはまったく別物だ。
そういう観点で言えば、Pythonエンジニアの立場から見ると、この問題はそもそも正解がないように思える。
もし問題文に「C++/Javaベースの視点で答えろ」と一言でもあったら、迷いなくカプセル化を選んでいたと思う。
確かに、C++やJavaではカプセル化の結果として情報隠蔽がついてくるから。
でもPythonやRubyみたいな言語では、「カプセル化 = 情報隠蔽」なんて式は成り立たない。
構造的にはカプセル化っぽいものはあるけど、情報を本当に隠すかどうかは実装者の意思に任されているだけなんだ。
そして、もっと根本的な話をすると――
オブジェクト指向って、そもそもある特定の言語の仕様に縛られたものじゃない。
言語を超えた考え方や設計の哲学のはず。
なのにこの問題は、まるでC++とかJavaの実装スタイルを前提にして、その“概念”を定義しているように感じてしまった。
これは国家資格の試験なんだからこそ、言語に依存しない形で、本質的なCSの理解力を測るべきだと思う。
もし“概念”を問いたかったのなら、こんなふうに一部の言語に偏った選択式ではなく、記述式で出題されるべきだったんじゃない?“実務”に寄せたかったのなら、どうしてPythonやRuby、Goといった実用言語では通用しないような解説を押し付けてくるのか、不思議でならない。
OOPって、そもそもどこから来たの?
OOP(オブジェクト指向プログラミング)という言葉を作ったのは Alan Kay という人物だ。
そして彼はこう語っている。
“I invented the term ‘object-oriented’, and I can tell you I did not have C++ in mind.”
「オブジェクト指向」という言葉を作ったのは私だが、そのときにC++のことを考えていたわけではない――。
つまり、OOPはC++やJavaで生まれたものではない。
OOPの原点は Smalltalk という言語にあり、そこでは次のような思想が大事にされていた。
オブジェクトは状態を持ち、メッセージを使って相互作用する
カプセル化とは、実装の詳細を隠し、インターフェースだけを公開すること
クラスや継承よりも、メッセージ伝達や隠蔽性の方が重要
結局のところ、カプセル化が情報隠蔽につながるかどうかは使っている言語による。
自分のメイン言語であるPythonでは、そうではない。
でも、Pythonにも立派なOOPはある。
「正解した問題をなんでそんなに深掘りしてんの?」
そう思う人もいるかもしれない。
でも、こうして突き詰めていくことで
「カプセル化=情報隠蔽」という自分の言語環境とはズレた “死んだ知識” ではなく、
“生きた知識” が手に入るような気がするんだよね。
カカオ
グーグル
ネイバー