データ構造とオブジェクトの違いとは?基本概念からJava実装例まで徹底解説
基本概念
データ構造(データクラス)とは、Car(車)、Kid(子ども)、Animal(動物)、Event(イベント)、Employee(従業員)、Company(会社)、Customer(顧客)などのように、データを保持することだけを目的とした特別なクラス、いわゆる「純粋なモデル」として定義されるものです。これらのデータは、他のクラスの冒頭部分でインスタンス変数として宣言されたり、そう扱われたりするのが一般的です。
データ構造クラスのメソッドには、実質的に重要な処理を含めてはいけません。もし実作業に相当するロジックを書いてしまうと、そのクラスはもはやデータ構造ではなくなってしまうからです。
したがって、メソッドは基本的にゲッターとセッター(アクセサおよびミューテーター)のみとなります。これは通常、インスタンス変数が private として扱われるためです。ただし、「データ構造の変数は public にして、インスタンスから直接アクセスできるようにすべきだ」という異なる意見も存在します。private 変数の考え方の方が優れているかどうかについては、議論の分かれるところです。
- この文脈におけるデータ構造クラスは、自身のデータ(変数)を公開・露出し、意味のある(重要な)メソッドや関数を持ちません。
- 一方、MainActivity、ListAdapter、Calculator、Iterator のような通常のクラス(ここでは「オブジェクト」と呼びます)は、データを隠蔽し、そのデータを操作するメソッドだけを外部に公開します。
つまり、目の前の問題を解決するためのアプローチは2つあります。ひとつは、最も純粋な形でデータ構造を実装し、そのデータに対する操作を担う別のオブジェクトクラスを作る方法。もうひとつは、モデルクラス自体をオブジェクトクラスとして設計し、データを隠蔽しながらメソッドを公開する方法です。以下の具体例で確認してみましょう。
public class Square {
public Point topLeft;
public double side;
}
public class Rectangle {
public Point topLeft;
public double height;
public double width;
}
public class Circle {
public Point center;
public double radius;
}
public class Geometry {
public final double PI = 3.141592653589793;
public double area(Object shape) throws NoSuchShapeException {
if (shape instanceof Square) {
Square s = (Square)shape;
return s.side * s.side;
}else if (shape instanceof Rectangle) {
Rectangle r = (Rectangle)shape;
return r.height * r.width;
}else if (shape instanceof Circle) {
Circle c = (Circle)shape;
return PI * c.radius * c.radius; }
throw new NoSuchShapeException(); }
}この解決策では、各図形クラス(Square、Rectangle、Circle)はデータ構造として扱われ、面積計算を担当する Geometry クラスがオブジェクトとして機能します。
メリット: 新しいメソッドを追加したい場合、Geometry クラスに追記するだけで済みます。まさにこのようなケースでこそ、この解決策を採用すべきといえます。
デメリット: 一方、新しいデータ構造(つまり新しい図形)を追加したい場合は、Geometry クラス内のすべてのメソッドを修正する必要が生じます。
データ構造とオブジェクトの違い
- オブジェクトは振る舞い(メソッド)を公開し、データを隠蔽します。そのため、既存の振る舞いを変更することなく、新しい種類のオブジェクトを簡単に追加できる一方、既存のオブジェクトに新しい振る舞いを後から追加するのは難しくなります。
- データ構造はデータを公開・露出し、重要な振る舞いを持ちません。そのため、既存のデータ構造に対して新しい振る舞い(処理)を追加するのは容易ですが、既存の関数群に新しいデータ構造を組み込むのは困難になります。
-
二分木(バイナリツリー)のデータ構造と重要な性質を解説
二分木(バイナリツリー)とは、各ノードが持てる子ノードの数を最大2つに制限した木構造のデータ構造です。本記事では、この二分木が持つ重要な性質について、具体例とともにわかりやすく解説します。まず、次のような二分木を例に考えてみましょう。二分木の主な性質各レベルの最大ノード数:レベル「l」における最大ノード数は 2l−1 です。ここでいうレベルとは、根(ルート)からそのノードまでの経路上にあるノードの総数を指し、ルート自身も含みます。なお、ルートのレベルは1として扱います。木全体の最大ノード数:高さ h の二分木に含まれる最大ノード数は 2h−1 です。ここでいう高さとは、ルートから葉までの経路上
-
データ構造における二分木の表現方法|配列と連結リストの違いを解説
コンピュータメモリ上での二分木の表現方法 ここでは、二分木をコンピュータのメモリ上でどのように表現するかについて解説します。表現方法には主に2種類あり、配列を使う方法と連結リスト(リンクリスト)を使う方法があります。 配列による表現 まず、次のような二分木を例に考えてみましょう。 配列による表現では、木の要素をレベル順(幅優先順)に走査しながら格納していきます。つまり、ノードを上のレベルから順番に保存する方式です。存在しない要素がある場合は、その位置を空白のまま残します。上記の木を配列で表現すると、次のようになります。 123456789101112131415 10516-81520