8回目

オブジェクト指向
プログラミング
第八回
知能情報学部
新田直也
構造化指向の問題点

構造化指向(C言語)または構造化指向っぽく書いた
オブジェクト指向(Java)のプログラムでは,データ構
造の変更に伴って変更すべき箇所が散乱する.
public class Main {
public static void main(String[] args) {
List l = new List();
add(l, 11);
add(l, 22);
int v = get(l, 1);
System.out.println("v = " + v);
}
public static void add(List l, int v) {
l.values[l.size] = v;
l.size++;
}
public static void get(List l, int n) {
return l.values[n];
}
}
public class List {
int values[] = new int[1000];
int size;
}
データ構造の修正
(構造体)
アルゴリズムの修正(関数)
カプセル化(1/2)

それなら,一緒に変更されるデータ構造とアルゴリ
ズムを一箇所にまとめればいい.
構造体
public class Main {
public static void main(String[] args) {
List l = new List();
add(l, 11);
add(l, 22);
int v = get(l, 1);
System.out.println("v = " + v);
}
public static void add(List l, int v) {
l.values[l.size] = v;
l.size++;
}
public static void get(List l, int n) {
return l.values[n];
}
関数
}
public class List {
int values[] = new int[1000];
int size;
}
関数を構造体の中に
入れてしまえばよい
カプセル化(2/2)

それなら,一緒に変更されるデータ構造とアルゴリ
ズムを一箇所にまとめればいい.
public class Main {
public class List {
public static void main(String[] args) { 構造体
int values[] = new int[1000];
List l = new List();
int size;
部分
l.add(11);
public void add(int v) {
l.add(22);
values[v.size] = v;
int v = l.get(1);
size++;
System.out.println("v = " + v);
}
関数部分
}
public int get(int n) {
}
return l.values[n];
}
}
構造体と関数をまとめた(カプセル化した)ものをクラスと呼ぶ.
クラスの内部にデータ構造とアルゴリズムの両方を隠蔽できる.
クラスはモノに相当すると考えよう(オブジェクト指向).
フィールドとメソッド

オブジェクト指向では,構造体部分の変数を
フィールド,関数をメソッドと呼ぶ.
public class List {
int values[] = new int[1000];
int size;
public void add(int v) {
values[v.size] = v;
size++;
}
public int get(int n) {
return l.values[n];
}
}
フィールド
メソッド
カプセル化に伴う呼び出し側の変更

カプセル化に伴って呼び出し側にも若干の変更が
必要.


インスタンスの生成
メッセージの送信(メソッド呼び出し)
public class Main {
public static void main(String[] args) {
List l = new List();
インスタンスの生成
l.add(11);
メッセージの送信先インスタンス
l.add(22);
int v = l.get(1);
System.out.println("v = " + v);
}
}
クラスとインスタンス
クラスはモノの概念,種類.
 インスタンスは個々のモノ,個体. インスタンスの生成×2

public class Main {
public static void main(String[] args) {
List l = new List();
l.add(11);
l.add(22);
lとl2はListクラスの
別のインスタンスなので
List l2 = new List();
その内容も異なる
l2.add(33);
l2.add(44);
int v1 = l.get(1);
int v2 = l2.get(1);
System.out.println("v1 = " + v1);
System.out.println("v2 = " + v2);
}
}
クラスとインスタンスの例(1/2)

人(Person)クラスを作成する.
public class Person {
String name;
double height;
double weight;
double getBMI() {
return weight / (height * height);
}
}
クラスとインスタンスの例(2/2)

main()メソッド内で Person クラスのインスタンスを
2つ生成する.

1つのクラスに対してインスタンスはいくつでも作成できる.
public static void main(String[] args) {
Person p1 = new Person();
p1.height = 1.7;
p1.weight = 65;
Person p2 = new Person();
p2.height = 1.6;
p2.weight = 55;
double bmi1 = p1.getBMI();
double bmi2 = p2.getBMI();
System.out.println(bmi1);
System.out.println(bmi2);
}
よりオブジェクト指向っぽく
(セッタ,ゲッタの追加)(1/2)

一般にフィールドの値を設定するメソッドをセッタ,値
を取得するメソッドをゲッタと呼ぶ.
public class Person {
String name;
double height;
double weight;
void setHeight(double h) {
height = h;
}
double getHeight() {
return height;
}
double getBMI() {
return weight / (height * height);
}
}
よりオブジェクト指向っぽく
(セッタ,ゲッタの追加)(2/2)

main()メソッドも以下のように書き換える.
public static void main(String[] args) {
Person p1 = new Person();
p1.setHeight(1.7);
p1.setWeight(65);
Person p2 = new Person();
p2.setHeight(1.6);
p2.setWeight(55);
double bmi1 = p1.getBMI();
double bmi2 = p2.getBMI();
System.out.println(bmi1);
System.out.println(bmi2);
}