オブジェクト指向の概念の要点
内容の確認日: 2026-10-03
この分野では、オブジェクト指向の考え方 (カプセル化・継承・ポリモーフィズム) の意味と、それを Java でどう書くかが問われます。用語の説明として正しいものを選ぶ問題と、抽象クラスやインタフェースを使ったコードがコンパイルできるかを判断する問題の両方が出ます。
出題項目は「具象クラス、抽象クラス、インタフェース」「データ隠蔽とカプセル化」「ポリモフィズム」の 3 つです。抽象クラスとインタフェースのルールの違いは、細かいところまで問われます。
オブジェクト指向の 3 つの考え方
カプセル化: データ (フィールド) と、それを扱う処理 (メソッド) を 1 つのクラスにまとめ、データを外から直接触れないようにする考え方です。外部には決められたメソッドだけを公開します。
継承: 既存のクラスの性質を引き継いで、新しいクラスを作る仕組みです。共通する部分を親クラス (スーパークラス) にまとめ、子クラス (サブクラス) では違う部分だけを書きます。Java のクラスの継承は 1 つの親からだけ (単一継承) です。
ポリモーフィズム (多態性): 同じ型の変数に対して同じメソッドを呼んでも、実際のオブジェクトの種類に応じて違う処理が実行される性質です。呼び出す側は具体的なクラスを知らなくても済みます。
試験では「不正な値の代入を防ぐ」はカプセル化、「既存のクラスを再利用して拡張する」は継承、「呼び出し側を変えずに種類を増やせる」はポリモーフィズム、のように、説明文と用語の対応がよく問われます。
具象クラスと抽象クラス
すべてのメソッドに処理が書かれていて、new でインスタンスを作れるクラスを具象クラスと呼びます。一方、abstract を付けたクラスは抽象クラスで、new でインスタンスを作れません。
abstract class Animal { abstract void sound();}public class Main { public static void main(String[] args) { Animal a = new Animal(); }}javac Main.java
コンパイルエラー (7 行目): 抽象クラス Animal は new でインスタンス化できない
抽象クラスには、処理を持たない抽象メソッドを宣言できます。抽象メソッドは abstract void sound(); のように、{ } を書かずセミコロンで終えます。抽象メソッドを 1 つでも持つクラスは、必ず抽象クラスにしなければなりません。逆に、抽象メソッドが 1 つもなくても、abstract を付ければ抽象クラスにできます。
抽象クラスを継承した具象クラスは、すべての抽象メソッドを実装 (オーバーライド) しなければなりません。実装し忘れるとコンパイルエラーです (子クラスも抽象クラスにする場合は、実装しなくても構いません)。
abstract class Shape { abstract double area();}class Square extends Shape { double side = 2;}public class Main { public static void main(String[] args) { System.out.println("ok"); }}javac Main.java
コンパイルエラー (5 行目): Square は抽象メソッド area() を実装していない
抽象クラスも普通のクラスと同じように、フィールド・コンストラクタ・処理を持つメソッドを持てます。「インスタンスを作れない」以外は普通のクラスと同じ、と覚えておきましょう。
インタフェース
インタフェースは、クラスが持つべきメソッドの「約束」だけを定めたものです。interface で宣言し、クラスは implements で実装します。クラスの継承は 1 つだけですが、インタフェースは implements A, B のように複数実装できます。
インタフェースのメソッドは、修飾子を書かなくても public abstract として扱われます (Java SE 8 からは、処理を持つ default メソッドと static メソッドも書けます)。フィールドは、書かなくても public static final の定数になります。
実装するクラスでは、メソッドを public にする必要があります。インタフェースのメソッドは暗黙的に public なので、修飾子を省略して実装すると「アクセスを狭めた」ことになり、コンパイルエラーです。
interface Greeter { void greet();}class JapaneseGreeter implements Greeter { void greet() { System.out.println("こんにちは"); }}public class Main { public static void main(String[] args) { new JapaneseGreeter().greet(); }}javac Main.java
コンパイルエラー (6 行目): greet() を public にしていないため、インタフェースのメソッドよりアクセスが狭くなる
抽象クラスとインタフェースの主な違いは次のとおりです。
・継承・実装できる数: 抽象クラスは 1 つだけ (extends)、インタフェースは複数 (implements)
・フィールド: 抽象クラスは普通のフィールドを持てる、インタフェースは定数 (public static final) だけ
・コンストラクタ: 抽象クラスは持てる、インタフェースは持てない
・インスタンス化: どちらも new できない
なお、同じ名前のメソッドを持っていても、implements と宣言していないクラスはそのインタフェースの型として扱えません。型の関係は宣言で決まります。
データ隠蔽とカプセル化
カプセル化の基本は、フィールドを private にして外から直接変更できないようにし (データ隠蔽)、値を読み書きするための public なメソッドを用意することです。値を変更するメソッドの中でチェックをすれば、不正な値が入るのを防げます。
class Account { private int balance; public void deposit(int amount) { if (amount > 0) { balance += amount; } } public int getBalance() { return balance; }}public class Main { public static void main(String[] args) { Account acc = new Account(); acc.deposit(1000); acc.deposit(-300); System.out.println(acc.getBalance()); }}java Main 1000
-300 の入金は deposit の中のチェックで無視されるので、残高は 1000 のままです。Main から acc.balance = -1; のように直接書き換えようとすると、balance が private なのでコンパイルエラーになります。値を取り出すメソッドを getXxx、設定するメソッドを setXxx と名付けるのが慣習で、それぞれゲッター・セッターと呼びます。
ポリモーフィズム
親クラスやインタフェースの型の変数には、それを継承・実装したクラスのオブジェクトを入れられます。その変数でメソッドを呼ぶと、変数の型ではなく、実際のオブジェクトのクラスのメソッドが実行されます。これがポリモーフィズムです。
interface Shape { double area();}class Rect implements Shape { private double width, height; Rect(double width, double height) { this.width = width; this.height = height; } public double area() { return width * height; }}class Triangle implements Shape { private double base, height; Triangle(double base, double height) { this.base = base; this.height = height; } public double area() { return base * height / 2; }}public class Main { public static void main(String[] args) { Shape[] shapes = {new Rect(2, 3), new Triangle(4, 5)}; for (Shape s : shapes) { System.out.println(s.area()); } }}java Main 6.0 10.0
for 文の中では、どの図形かを気にせず s.area() と呼ぶだけで、それぞれのクラスの計算が行われます。新しい図形のクラスを追加しても、Main の処理を変える必要はありません。
試験でよくある引っかけ
抽象クラスを
newする抽象クラスはインスタンス化できません。抽象クラスの型の変数に、具象クラスのオブジェクトを入れるのは問題ありません。
抽象メソッドに
{ }を書くabstract void sound() { }はコンパイルエラーです。抽象メソッドはセミコロンで終えます。抽象メソッドの実装し忘れ
抽象クラスを継承した具象クラスは、すべての抽象メソッドを実装しないとコンパイルエラーです。
インタフェースのメソッドを
publicにしないインタフェースのメソッドは暗黙的に
publicなので、実装側もpublicにする必要があります。インタフェースのフィールド
インタフェースのフィールドは
public static finalの定数です。実装クラスから値を変更するとコンパイルエラーです。呼ばれるメソッドは実際のクラスのもの
Shape s = new Rect(...)でs.area()を呼ぶと、Rectのarea()が実行されます。
問題で確認する
この分野の問題を、解説つきで読めます (登録不要)。
出典・参考
- Oracle University 日本「1Z0-818-JPN (Java SE Bronze) 試験」
- Java 言語仕様 (Java SE 11) 8.1.1.1「abstract Classes」
- Java 言語仕様 (Java SE 11) 9「Interfaces」
- The Java Tutorials「Abstract Methods and Classes」
コード例は、試験の対象バージョンで実際にコンパイル・実行して結果を確認しています。