カプセル化

Java基礎 8

1.本章での学習項目

本章では、オブジェクト指向の基本的事項の一つであるカプセル化について学習します。

2.本章の講義

本章で学習する内容を動画としてまとめたものです。最初に一通り見終わった後で、学習に入るようにしてください。

講義:カプセル化

3.カプセル化とは

「クラス」の章で説明したように、オブジェクト指向言語であるJavaでは、色々なクラスが相互にやりとりをして処理が進むことが特徴です。

しかし、クラス間でお互いにフィールドやメソッドへの利用を制限したいことがあります。
例えば、フィールドに対して制限を行うことで、そのクラスの中の処理の整合性を保つ必要がある場合などです。
お互いに、必要なフィールドやメソッドのみを他のクラスから生成されたオブジェクトから利用できるようにし、他のオブジェクトから利用することがないものは、できるだけ他のオブジェクトから見えないようにしてしまうという考え方は、オブジェクト指向の基本です。
そうすることにより、各クラスのフィールドやメソッドの整合性や安全性を保つことができます。

この「他のクラスから見えないようにする」ことを、カプセル化と呼びます。
カプセル化は、「オブジェクトの中を隠蔽する」とも言われます。
カプセル化は、他のオブジェクトからの影響をなくす目的があり、オブジェクト間の依存関係を少なくします。
カプセル化を行うことにより、オブジェクトの仕様変更があっても影響が少なくなったりという利点もあります。
他のオブジェクトに対する影響を気にせずに、変更対象のオブジェクトのみに集中することができ、プログラムのメンテナンス性(修正のしやすさ)が向上します。


capsule1

それでは、これからカプセル化の実際の手法について、学習していきましょう。

4.パッケージ

カプセル化を学ぶにあたり、まずはパッケージについて学習します。
Javaで開発されたシステムやソフトウェアは、多くのクラスで構成されています。
パッケージは、これらのクラスを分類して管理することができる機能です。
パッケージは、クラスをまとめ、実際のプログラムファイルやクラスファイルも同様にパッケージというフォルダの中にまとめて管理されるようになります。
パッケージを使用することにより、パッケージごとにアクセスの制限をかけることができます。


encapsulation package1

4.1.パッケージの宣言

クラスをパッケージに属すようにするには、パッケージの宣言が必要です。
パッケージ宣言は、ファイルの先頭、クラスの宣言の前に行います。

以下がパッケージ宣言の書式です。

package パッケージ名;

プログラムで書くと以下のようになります。

package pac1; // パッケージ宣言
public class MyPackage1 {
	・・・・・・・
}

パッケージの中にパッケージを作成すると、その中のクラスのパッケージ宣言は、以下のような書式になります。

package パッケージ名.その中のパッケージ名;

プログラムで書くと以下のようになります。

package pac1.sub1; // パッケージ宣言
public class MySubPackage1 {
	・・・・・・・
}
4.1.1.Eclipseでのパッケージ作成

それでは、Eclipseでパッケージを作成してみましょう。

Eclipseでは、パッケージは、以下の手順で作成します。通常、パッケージ宣言は、Eclipseが自動的に記述をしてくれます。
まず、「パッケージ・エクスプローラー」の「src」フォルダを右クリックし、「新規」⇒「パッケージ」を選択します。


encapsulation package2

以下のポップアップ画面が表示されますので、名前にパッケージ名「pac1」を入力し、「完了」ボタンを押下します。


encapsulation package3

「パッケージ・エクスプローラー」に以下のようにパッケージが表示されます。


encapsulation package4

このパッケージを右クリックし、新規クラスを作成すると、以下のようにパッケージ宣言「package pac1;」が自動的に記述されます。


encapsulation package5

4.1.2.パッケージフォルダの保存場所

これまでは、Eclipseを使用していたため実際のソースファイルやクラスファイルの保存場所を意識したことがありませんでした。
今回、パッケージを学習するにあたって、実際に作成されるパッケージフォルダとその中にあるデータファイルを確認してみましょう。

まず、「パッケージ・エクスプローラー」の「FirstJava」プロジェクトを選択し、メニューの「ファイル」 ⇒ 「プロパティー」をクリックしてください。


package7

以下のポップアップ画面の「ロケーション」に表示されているフォルダが、「FirstJava」プロジェクトの保存場所です。


encapsulation package8

それでは、実際のデータを見てみましょう。
上記のロケーションの場合、「PC」の「Cドライブ」の「pleiades」フォルダの「yyyy-MM」形式フォルダの「workspace」フォルダを開いてみましょう。
以下のようなフォルダが見えてくると思います。これが、作成してきた「プロジェクト」のフォルダです。


encapsulation package9

更に「プロジェクト」のフォルダの中を見ると、「src」フォルダがあります。その「src」フォルダの中にプロジェクトのソースファイルが保存されているフォルダが置かれています。
パッケージが作られている場合は、「src」フォルダの中に、パッケージのフォルダが存在します。
また、「src」フォルダと同じ階層になる「bin」フォルダには、クラスファイルが保存されています。
「src」フォルダと同様に、パッケージが作られている場合には、パッケージのフォルダが存在します。併せて確認しておきましょう。

Information

Eclipseのデフォルト・パッケージ

本章でパッケージを学習するまで、パッケージを意識してきませんでした。
クラスを作成する際、Eclipse上に「デフォルト・パッケージ」というパッケージの中に作成してきていたことを気づいたでしょうか。
実は、このデフォルト・パッケージは、実際には存在しないパッケージのフォルダなのです。
Eclipse上で、あたかも存在するかのように表示されているだけで、実は、「src」フォルダの直下にソースファイルを作っていた状態でした。
通常は、パッケージを適切に作成して、その中にクラスを作成していくようにしたほうが良いでしょう。

4.1.3.Javaの標準クラスライブラリのパッケージ

Javaの標準クラスライブラリについては、「よく使うクラス」の章で学習しましたが、その標準クラスライブラリには、多くのパッケージがあります。
これらのパッケージは、「java」で始まり、その下に各クラスを分類するパッケージが定義されています。

よく使うパッケージを以下に紹介します。

パッケージ名 説明
java.lang Javaの基本的なクラスを分類
java.util 色々なところで使える様々なユーティリティクラスを分類
java.io コンソールやファイルなどからデータ読み込み・書き込みを行うクラスを分類
java.sql データベースを扱うクラスを分類

4.2.パッケージのインポート

他のパッケージに属しているクラスを利用するときは、どのパッケージのどのクラスを使うのかということを明示する必要があります。

4.2.1.パッケージとクラスの都度指定

記述の方法は、2通りあります。

まず1つ目は、プログラムの処理の中で都度、パッケージとクラスを指定する方法です。書式は、以下のとおりです。

パッケージ名.クラス名

例えば、パッケージpac2に属するクラスMyPac2が、パッケージpac1に属するクラスMyPac1を利用するときには、以下のような記述でインスタンス化を行うことができます。

package pac2; // パッケージ宣言

public class MyPac2 {
	public static void main(String[] args) {
		// 他のパッケージのクラスをインスタンス化
		pac1.MyPac1 myPac1 = new pac1.MyPac1();
		・・・・・・・
	}
}
4.2.2.パッケージとクラスをインポート

2つ目の方法は、インポート文を記述する方法です。
クラスの宣言の前に、どのパッケージのどのクラスを利用するかを宣言します。

パッケージ宣言がある場合は、パッケージ宣言の後に記述します。
このインポートをしたクラスは、1つ目の方法のように、都度パッケージとクラスを指定する必要はありません。
今までどおり、インスタンス化するときにクラス名のみで記述できます。書式は、以下のとおりです。

import パッケージ名.クラス名;

プログラムで書くと以下のとおりとなります。
以下の例は、パッケージpac2に属するクラスMyPac2が、パッケージpac1に属するクラスMyPac1を利用する場合です。

package pac2; // パッケージ宣言

import pac1.MyPac1; // パッケージpac1のクラスMyPac1をインポート

public class MyPac2 {
	public static void main(String[] args) {
		// 他のパッケージのクラスをインスタンス化(パッケージ名は不要)
		MyPac1 myPac1 = new MyPac1();
		・・・・・・・
	}
}

インポートは、あるパッケージに属している全てのクラスを一度にインポートする記述も可能です。
書式は、以下のとおりとなります。

import パッケージ名.*;

「パッケージ名.」の後に記述している「*」は、アスタリスクと呼び、「全て」という意味があります。
以下がサンプルソースです。

package pac2; // パッケージ宣言

import pac1.*; // パッケージpac1のクラス全てをインポート

public class MyPac3 {
	public static void main(String[] args) {
		// 他のパッケージのクラスをインスタンス化(パッケージ名は不要)
		MyPac1 myPac1 = new MyPac1();
		・・・・・・・
	}
}
4.2.3.Javaの標準クラスライブラリのインポート

Javaの標準クラスを利用するときには、通常、インポート文を記述して利用します。
例えば、Javaのファイルデータの読み込みや書き込み用のクラスを利用するときには、java.ioパッケージをインポートします。

プログラムで書くと、以下のようになります。

package pac2; // パッケージ宣言
import java.io.*; // パッケージjava.ioのクラス全てをインポート
public class MyPac4 {
	public static void main(String[] args) {
		・・・・・・・
	}
}

Javaの標準クラスを利用するときには、基本的にインポート文が必要です。
「よく使うクラス」の章で学習したIntegerクラスやStringクラスが属しているjava.langパッケージは、インポート文を記述しませんでしたが、この「java.lang」パッケージは、特別なパッケージで、インポート文を記述しなくても、このパッケージに属しているクラスは、そのまま利用できるのです。

他のパッケージの属しているクラスの利用について、2つの方法を理解できたでしょうか。
通常は、2つ目の方法のインポート文を利用しましょう。

それでは次に、カプセル化の手法として、アクセス権限について学習します。
その中で、パッケージごとにアクセス制限をかける方法も学習します。

5.アクセス権限

これから、カプセル化の手法としてアクセス権限について学習します。

「カプセル化」で説明したように、クラス、メソッド、フィールドに対し、アクセスの制限をかけることがあります。
アクセス権限とは、他のクラスやメソッドから、クラス、フィールドやメソッドへのアクセス(利用)を許可したり、拒否したりすることです。
また、上記で学習したパッケージごとに、アクセス権限を設定することも可能です。

5.1.アクセス修飾子

今まで、クラスやメソッド、フィールドの定義をするときに「public」という単語を記述してきていました。
この「public」が、これから学習するアクセス修飾子と呼ばれるもので、クラスやメソッド、フィールドの他からのアクセス制限設定しています。
Javaは、アクセス修飾子を使って、クラス、フィールド、メソッドに対して、アクセスの許可または拒否を設定することができます。

アクセス修飾子には、以下の4パターンがあります。

アクセス修飾子 クラスへのアクセス制限 フィールド・メソッドへのアクセス制限
public 全てのクラスからアクセス可 属しているクラスがアクセス可であれば、全てアクセス可
protected 指定不可 同一パッケージ内、またはサブクラス(後述します)からアクセス可
指定なし 同一パッケージ内は可 同一パッケージ内は可
private 指定不可 同一クラス内は可

5.2.クラスのアクセス修飾子

クラスへのアクセスの方法を説明します。クラスには、クラス宣言の前に「public」を付けるか付けないかの2通りのみで、アクセス制限をします。
上記の表で説明したように、publicを付けると全てのクラスからアクセスが可能となり、付けていないと同一パッケージのクラスからのみアクセスが可能になります。

以下がpublic修飾子を付けたサンプルソースです。

MyClass1.java
package pac1;

public class MyClass1 { //全クラスからアクセス可能なクラス
}

以下がアクセス修飾子がないサンプルソースです。

MyClass2.java
package pac1;

class MyClass2 { //同一パッケージ内でアクセス可能なクラス
}

pac1に属するクラスMyClass3は、上記のクラスに問題なくアクセスできます。

MyClass3.java
package pac1;

public class MyClass3 {
	public static void main(String args[]) {
		// public修飾子が付いているクラスは、アクセス可
		MyClass1 my1 = new MyClass1();

		// アクセス修飾子がないクラスは、同一パッケージ内はアクセス可
		MyClass2 my2 = new MyClass2();
	}
}

pac2に属するクラスMyClass4が、上記のクラスにアクセスしようとすると、アクセス修飾子がないMyClass2は、エラーになります。

MyClass4.java
package pac2;

// public修飾子が付いているクラスは、インポート可
import pac1.MyClass1;

// エラー:アクセス修飾子がないクラスは、パッケージが異なるとインポート不可
import pac1.MyClass2;

public class MyClass4 {
	public static void main(String args[]) {
		// public修飾子が付いているクラスは、アクセス可
		MyClass1 my1 = new MyClass1();

		// アクセス修飾子がないクラスは、パッケージが異なるとアクセス不可
		MyClass2 my2 = new MyClass2();
	}
}


encapsulation access1

クラスのアクセス修飾子は、基本的に「public」を付けた方が良いです。

5.3.フィールド、メソッドのアクセス修飾子

フィールドやメソッドは、アクセス修飾子がpublic、protected、指定なし、privateの4パターンあります。
これから、この4パターンの使い方を説明します。

5.3.1.public修飾子

フィールドやメソッドpublicをつけると同一パッケージの他のクラスだけではなく、他のパッケージのクラスからもアクセス可能です。

以下がサンプルソースです。

MyClass5.java
// 他のパッケージからもアクセスできるクラス
public class MyClass5 {
	// 他のパッケージからもアクセスできるフィールド
	public int a;

	// 他のパッケージからもアクセスできるフィールド
	public int b;

	// 他のパッケージからもアクセスできるメソッド
	public int MyAdd(int x, int y) {
		return x + y;
	}
}
5.3.2.protected修飾子

フィールドやメソッドにprotectedをつけると、そのメソッドや変数には、同じパッケージ内か、クラス内部か、そのサブクラスからしかアクセスできません。
サブクラスについては、「インヘリタンス」の章で説明します。

MyClass6.java
//  他のパッケージからもアクセスできるクラス
public class MyClass6 {
	// MyClass6内、同じパッケージ、サブクラスのみアクセス可能なフィールド
	protected int a;

	// MyClass6内、同じパッケージ、サブクラスのみアクセス可能なフィールド
	protected int b;

	// MyClass6内、同じパッケージ、サブクラスのみアクセス可能なメソッド
	protected int add(int x, int y) {
		return x + y;
	}
}
5.3.3.アクセス修飾子が指定なし

フィールドやメソッドにアクセス修飾子の指定がない場合は、同じパッケージ内でのみアクセス可能になります。

MyClass7.java
// 他のパッケージからもアクセスできるクラス
public class MyClass7 {
	// 同一パッケージ内でアクセス可能なフィールド
	int a;

	// 同一パッケージ内でアクセス可能なフィールド
	int b;

	// 同一パッケージ内でアクセス可能なメソッド
	int myAdd(int x, int y) {
		return x + y;
	}
}
5.3.4.private修飾子

フィールドやメソッドにprivateをつけると、そのメソッドや変数はクラス内部でしかアクセスできません。

MyClass8.java
// 他のパッケージからもアクセスできるクラス
public class MyClass8 {
	// MyClass8内でしか使えないフィールド
	private int a;

	// MyClass8内でしか使えないフィールド
	private int b;

	// MyClass8内でしか使えないメソッド
	private int myAdd(int x, int y) {
		return x + y;
	}
}
5.3.5.各アクセス修飾子の違い

同一クラス内で、色々なアクセス修飾子を指定したフィールドを定義し、その違いを再度確認しましょう。

以下、利用されるクラスの定義です。フィールドに色々なアクセス修飾子を指定しています。

MyClass9.java
// パッケージpac1宣言
package pac1;

// 他のパッケージからもアクセスできるクラス
public class MyClass9 {

	// 他のパッケージのクラスからもアクセスできるフィールド
	public int a;

	// MyClass9内、同じパッケージ、サブクラスのみアクセス可能なフィールド
	protected int b;

	// MyClass9内、同じパッケージ内でアクセス可能なフィールド
	int c;

	// MyClass9内でしか使えないフィールド
	private int d;

	public void testAccess() {
		// 全てのフィールドは、MyClass9からアクセス可能
		a = 0;
		b = 0;
		c = 0;
		d = 0;
	}
}

次に、利用するクラスで、上記のMyClass9の各フィールドにアクセスしてみましょう。
まずは、同一パッケージのクラスから確認します。

MyClass10.java
// パッケージpac1宣言
package pac1;

public class MyClass10 {
	public static void main(String[] args){
		// 同一パッケージ内のクラスをインスタンス化
		MyClass9 my = new MyClass9();

		// public修飾子付き変数aは、アクセス可
		int x = my.a;

		// protected修飾子付き変数bは、アクセス可
		int y = my.b;

		// 修飾子なし変数cは、アクセス可
		int z = my.c;

		// エラー:private修飾子付き変数dは、アクセス不可
		int w = my.d;
	}
}


encapsulation access2

次に、別パッケージのクラスからのアクセスについて、確認します。

MyClass11.java
// パッケージpac2宣言
package pac2;

// 別のパッケージのクラスをインポート
import pac1.MyClass9;

public class MyClass11 {
	public static void main(String[] args){
		// 別のパッケージ内のクラスをインスタンス化
		MyClass9 my = new MyClass9();

		// public修飾子付き変数aは、アクセス可
		int x = my.a;

		// エラー:protected修飾子付き変数bは、アクセス不可
		int y = my.b;

		// エラー:修飾子なし変数cは、アクセス不可
		int z = my.c;

		// エラー:private修飾子付き変数dは、アクセス不可
		int w = my.d;
	}
}


encapsulation access3

6.練習問題1

練習問題1は、クラスの復習問題です。

6.1.問題1

shopパッケージを作成し、そのパッケージに、Catクラスを利用している以下のCatShopクラスを作成してプログラムをそのまま記述してください。
そのあと、表に示されているとおりにCatクラスを作成して、実行結果と同様の出力結果が表示されるようにしてください。

CatShop.java
package shop;

public class CatShop {

	public static void main(String[] args) {
		Cat myCat = new Cat();
		CatShop.buyCat(myCat);

		myCat = new Cat("アメリカンショートヘアー","オス", 0);
		CatShop.buyCat(myCat);
	}

	static void buyCat(Cat tCat) {
		System.out.println(tCat.getSyurui()
			+ "の"
			+ tCat.getSeibetsu()
			+ "、"
			+ tCat.getToshi() + "歳を買いました。");
	}
}

以下が、Catクラスの仕様です。

表 1. Catクラス
パッケージ shop
クラス Cat
フィールド String syurui 猫の種類
String seibetsu 猫の性別
int toshi 猫の年
コンストラクタ Cat() 下記内容で各フィールドを初期化する

  • syurui = "スコティッシュフォールド"
  • seibetsu = "メス"
  • toshi = 0
Cat(String tSyurui, String tSeibetsu, int tToshi) 各引数でフィールドを初期化する
メソッド String getSyurui() 猫の種類を返す
String getSeibetsu() 猫の性別を返す
int getToshi() 猫の年を返す
実行結果
スコティッシュフォールドのメス、0歳を買いました。
アメリカンショートヘアーのオス、0歳を買いました。

Cat.java
package shop;

/**
 * 処理概要:猫の種類、性別、年齢を扱うクラス
 */
public class Cat {
	// フィールド定義
	String syurui;      // 猫の種類
	String seibetsu;    // 猫の性別
	int toshi;          // 猫の年齢

	// 引数なしコンストラクタ定義(各フィールドを指定した値で初期化)
	Cat() {
		syurui = "スコティッシュフォールド";
		seibetsu = "メス";
		toshi = 0;
	}

	// 引数ありコンストラクタ定義(各フィールドを引数で初期化)
	Cat(String tSyurui, String tSeibetsu, int tToshi) {
		syurui = tSyurui;
		seibetsu = tSeibetsu;
		toshi = tToshi;
	}

	// フィールドsyuruiの値を戻すメソッド
	String getSyurui() {
		return syurui;
	}

	// フィールドseibetsuの値を戻すメソッド
	String getSeibetsu() {
		return seibetsu;
	}

	// フィールドtoshiの値を戻すメソッド
	int getToshi() {
		return toshi;
	}
}

フィールド、コンストラクタ、メソッドの定義は、各構文の形式通りに記述します。

引数なしのコンストラクタと引数ありのコンストラクタを2つ定義します。
利用するクラスでインスタンス化をするときに、引数なしの場合、引数なしのコンストラクタが呼び出され、引数ありの場合、引数ありのコンストラクタが呼び出されてオブジェクトが生成されます。

CatShop.java
package shop;

public class CatShop {
	public static void main(String[] args) {

		// Catクラスをインスタンス化
		Cat myCat = new Cat();

		// buyCatメソッドを呼び出し
		CatShop.buyCat(myCat);

		// Catクラスをインスタンス化
		myCat = new Cat("アメリカンショートヘアー","オス", 0);

		// buyCatメソッドを呼び出し
		CatShop.buyCat(myCat);
	}

	// buyCatメソッド
	static void buyCat(Cat tCat) {
		// 各フィールド値を出力
		System.out.println(tCat.getSyurui()
			+ "の"
			+ tCat.getSeibetsu()
			+ "、"
			+ tCat.getToshi() + "歳を買いました。");
	}
}

最初のCatクラスのインスタンス化は、引数がありませんので、Catクラスの引数がないコンストラクタ が呼び出され、オブジェクトが生成されます。
フィールドsyuruiには、「スコティッシュフォールド」、seibetsuには「メス」、toshiには「0」が設定されます。
そのオブジェクトの参照値(ハッシュコード値)が変数myCatに代入され、buyCatメソッドを呼び出すときに、引数として引き渡しています。

buyCatメソッドの定義を確認すると、引数の受け皿として「Cat tCat」と定義されているため、引き渡された参照値が代入されます。
その参照値を元に、生成したオブジェクトの情報を取得し、各フィールド値を出力します。

2回目のインスタンス化では、引数として値を引き渡していますので、Catクラスの引数があるコンストラクタが呼び出され、引数で渡された値をフィールドに設定してオブジェクトが生成されます。
そのあとは、同様にbuyCatメソッドを呼び出し、フィールド値を出力しています。

7.練習問題2

7.1.問題1

catpacパッケージを作成し、練習問題1で作成したCatクラスをそのパッケージに移動しましょう。
Catクラスのフィールドをすべてprivateに変更してください。
また、メソッド、コンストラクタについては、CatShopクラスがエラーにならないよう、
それぞれ適切なアクセス権限に変更してください。

※この問題の解答は掲載しておりません。Tech Fun ITスクールのJava研修では、講師が丁寧に解説しています。

8.練習問題3

練習問題3も、クラスの復習問題です。

8.1.問題1

shopパッケージに、Dogクラスを利用している以下のDogShopクラスを作成してプログラムをそのまま記述してください。
そのあと、表に示されているとおりにDogクラスを作成して、実行結果と同様の出力結果が表示されるようにしてください。

DogShop.java
package shop;

public class DogShop {

	public static void main(String[] args) {
		Dog myDog = new Dog();
		DogShop.buyDog(myDog);

		myDog = new Dog("ゴールデンリトリバー","オス", 0);
		DogShop.buyDog(myDog);
	}

	static void buyDog(Dog tDog) {
		System.out.println(tDog.getSyurui()
			+ "の"
			+ tDog.getSeibetsu()
			+ "、"
			+ tDog.getToshi() + "歳を買いました。");
	}
}

以下が、Dogクラスの仕様です。

表 2. Dogクラス
パッケージ shop
クラス Dog
フィールド String syurui 犬の種類
String seibetsu 犬の性別
int toshi 犬の年
コンストラクタ Dog() 下記内容で各フィールドを初期化する

  • syurui = "トイプードル"
  • seibetsu = "メス"
  • toshi = 0
Dog(String tSyurui, String tSeibetsu, int tToshi) 各引数でフィールドを初期化する
メソッド String getSyurui() 犬の種類を返す
String getSeibetsu() 犬の性別を返す
int getToshi() 犬の年を返す
実行結果
トイプードルのメス、0歳を買いました。
ゴールデンリトリバーのオス、0歳を買いました。

Dog.java
package shop;

/**
 * 処理概要:犬の種類、性別、年齢を扱うクラス
 */
public class Dog {
	// フィールド定義
	String syurui; // 犬の種類
	String seibetsu; // 犬の性別
	int toshi; // 犬の年齢

	// 引数なしコンストラクタ定義(各フィールドを指定した値で初期化)
	Dog() {
		syurui = "トイプードル";
		seibetsu = "メス";
		toshi = 0;
	}

	// 引数ありコンストラクタ定義(各フィールドを引数で初期化)
	Dog(String tSyurui, String tSeibetsu, int tToshi) {
		syurui = tSyurui;
		seibetsu = tSeibetsu;
		toshi = tToshi;
	}

	// フィールドsyuruiの値を戻すメソッド
	String getSyurui() {
		return syurui;
	}

	// フィールドseibetsuの値を戻すメソッド
	String getSeibetsu() {
		return seibetsu;
	}

	// フィールドtoshiの値を戻すメソッド
	int getToshi() {
		return toshi;
	}
}
DogShop.java
package shop;

public class DogShop {

	public static void main(String[] args) {

		// Dogクラスをインスタンス化
		Dog myDog = new Dog();

		// buyDogメソッドを呼び出し
		DogShop.buyDog(myDog);
		// Dogクラスをインスタンス化
		myDog = new Dog("ゴールデンリトリバー", "オス", 0);

		// buyDogメソッドを呼び出し
		DogShop.buyDog(myDog);
	}

	// buyDogメソッド
	static void buyDog(Dog tDog) {
		// 各フィールド値を出力
		System.out.println(tDog.getSyurui()
			+ "の"
			+ tDog.getSeibetsu()
			+ "、"
			+ tDog.getToshi() + "歳を買いました。");
	}
}

解説は、練習問題1と同様ですので割愛します。

9.練習問題4

9.1.問題1

dogpacパッケージを作成し、練習問題3で作成したDogクラスをそのパッケージに移動しましょう。
また、Dogクラスのフィールド、メソッド、コンストラクタのアクセス権限を以下のとおりに変更してください。

クラス public
フィールド すべてprivate
コンストラクタ すべてpublic
メソッド すべてpublic

Dog.java
package dogpac;

/**
 * 処理概要:犬の種類、性別、年齢を扱うクラス
 */
public class Dog {

	// フィールド定義
	private String syurui;      // 犬の種類
	private String seibetsu;    // 犬の性別
	private int toshi;          // 犬の年齢

	// 引数なしコンストラクタ定義(各フィールドを指定した値で初期化)
	public Dog() {
		syurui = "トイプードル";
		seibetsu = "メス";
		toshi = 0;
	}

	// 引数ありコンストラクタ定義(各フィールドを引数で初期化)
	public Dog(String tSyurui, String tSeibetsu, int tToshi) {
		syurui = tSyurui;
		seibetsu = tSeibetsu;
		toshi = tToshi;
	}

	// フィールドsyuruiの値を戻すメソッド
	public String getSyurui() {
		return syurui;
	}

	// フィールドseibetsuの値を戻すメソッド
	public String getSeibetsu() {
		return seibetsu;
	}

	// フィールドtoshiの値を戻すメソッド
	public int getToshi() {
		return toshi;
	}
}

10.本章のまとめ

  • 「カプセル化」とは「他のクラスから見えないようにする」ことである。
  • 様々なクラスを分類ごとに管理するために「パッケージ」を使用する。
  • ほかのパッケージに属しているクラスを使用するときは「その都度パッケージとクラスを指定する」もしくは「パッケージとクラスをインポートする」ことが必要となる。
  • クラスやメソッド、フィールドなどのアクセス制限は「アクセス修飾子」を使用して行う。

用語の意味などに不明点がある場合は、教材をもう一度読み直すなどして復習しておきましょう。

カプセル化についての説明は、以上です。

執筆・編集

Tech Fun Magazine編集部
Tech Funの現役のITエンジニアが、システム開発の基礎知識や実践的なノウハウを執筆・編集しています。
Tech Fun ITスクールの研修講師として活躍するメンバーもおり、プログラミング初心者がつまづきやすいポイントを丁寧に解説しています。

ARTICLE
記事一覧

Java基礎

Java12からJava17までに導入された機能の紹介

システム開発の基本

プログラミングとテストの要点

データベース環境構築

データベース環境構築(Windows版) テストデータ作成

データベース環境構築

データベース環境構築(Windows版) MariaDBの設定

データベース環境構築

データベース環境構築(Mac版) テストデータ作成

データベース環境構築

データベース環境構築(Mac版) MariaDBの設定

Java基礎

はじめてのJava

Java基礎

Javaのデバッグ方法

Java基礎

ポリモフィズム

記事一覧を見る