Java上級

上級 Javaで学ぶオブジェクト指向設計|練習問題編

導入

オブジェクト指向設計は、ソフトウェア開発において重要な手法の一つです。特に、Javaを使用したプロジェクトでは、クラスやオブジェクトを効果的に利用することで、柔軟かつ拡張性のあるシステムを構築できます。本記事では、実務で遭遇する具体的なシチュエーションを通じて、オブジェクト指向設計の重要性とその応用方法を深掘りします。

教科書レベルの解説(オブジェクト指向設計)

重要な概念の整理

オブジェクト指向設計では、クラス、オブジェクト、継承、ポリモーフィズムなどの基本概念が基盤となります。特に、継承を利用することで、既存のクラスの機能を拡張し、新しいクラスを作成することが可能です。ポリモーフィズムは、同一のインターフェースを持つ異なるオブジェクトが、異なる実装を持つことを可能にし、コードの再利用性を高めます。

コード例(Java)


abstract class Shape {
    abstract void draw();
}

class Circle extends Shape {
    void draw() {
        System.out.println("Drawing a Circle");
    }
}

class Rectangle extends Shape {
    void draw() {
        System.out.println("Drawing a Rectangle");
    }
}

class ShapeDrawer {
    void drawShape(Shape shape) {
        shape.draw();
    }
}

public class Main {
    public static void main(String[] args) {
        ShapeDrawer drawer = new ShapeDrawer();
        Shape circle = new Circle();
        Shape rectangle = new Rectangle();
        
        drawer.drawShape(circle);
        drawer.drawShape(rectangle);
    }
}

コードの行ごとの解説

  1. abstract class Shape: Shapeクラスは抽象クラスであり、具体的な図形クラスがこのクラスを継承することを示しています。
  2. void draw(): このメソッドは抽象メソッドとして定義されており、サブクラスで実装される必要があります。
  3. class Circle extends Shape: CircleクラスはShapeクラスを継承し、drawメソッドを具体的に実装しています。
  4. class Rectangle extends Shape: RectangleクラスもShapeクラスを継承し、drawメソッドを実装しています。
  5. class ShapeDrawer: ShapeDrawerクラスは、Shapeオブジェクトを受け取り、そのdrawメソッドを呼び出す役割を持っています。
  6. public static void main: メインメソッドでは、CircleとRectangleのインスタンスを作成し、それらをShapeDrawerを通じて描画しています。

練習問題編

以下に、オブジェクト指向設計に関連する練習問題を用意しました。各問題には模範解答と解説を付けています。

問題1

Shapeクラスに、色を表すプロパティを追加し、CircleとRectangleのクラスでそのプロパティを利用して描画時に色を表示するように実装してください。

模範解答:


abstract class Shape {
    String color;
    
    Shape(String color) {
        this.color = color;
    }
    
    abstract void draw();
}

class Circle extends Shape {
    Circle(String color) {
        super(color);
    }
    
    void draw() {
        System.out.println("Drawing a " + color + " Circle");
    }
}

class Rectangle extends Shape {
    Rectangle(String color) {
        super(color);
    }
    
    void draw() {
        System.out.println("Drawing a " + color + " Rectangle");
    }
}

解説: Shapeクラスに色のプロパティを追加し、サブクラスでそのプロパティを利用することで、より具体的な情報を持たせることができます。

問題2

ShapeDrawerクラスに、複数の図形を同時に描画できるメソッドを追加してください。

模範解答:


class ShapeDrawer {
    void drawShapes(Shape[] shapes) {
        for (Shape shape : shapes) {
            shape.draw();
        }
    }
}

解説: 配列を受け取るメソッドを追加することで、複数の図形を一度に描画することが可能になります。

問題3

Shapeクラスに面積を計算するメソッドを追加し、CircleとRectangleで具体的な計算を実装してください。

模範解答:


abstract class Shape {
    abstract void draw();
    abstract double area();
}

class Circle extends Shape {
    double radius;
    
    Circle(double radius) {
        this.radius = radius;
    }
    
    void draw() {
        System.out.println("Drawing a Circle");
    }
    
    double area() {
        return Math.PI * radius * radius;
    }
}

class Rectangle extends Shape {
    double width, height;
    
    Rectangle(double width, double height) {
        this.width = width;
        this.height = height;
    }
    
    void draw() {
        System.out.println("Drawing a Rectangle");
    }
    
    double area() {
        return width * height;
    }
}

解説: 面積を計算するメソッドを追加することで、図形の特性をより具体的に扱うことができるようになります。

まとめ

  • オブジェクト指向設計は、クラスやオブジェクトを通じて柔軟なシステムを構築する手法です。
  • 継承やポリモーフィズムを活用することで、コードの再利用性や拡張性を高められます。
  • 具体的なシチュエーションに基づいた設計が、実務において非常に重要です。