Javaオブジェクト指向

クラスのイメージ クラスの配列

クラスの利用

クラスをnewでインスタンス(オブジェクト)を生成して使う。

例:乱数 Randomクラス

// Randomクラスの場合
Random ran = new Random();
int num = ran.nextInt(10);

上の例の ran は「Random」クラスのインスタンスを入れるための変数。
new でRandomクラスのインスタンスを生成している。
nextInt()はメソッドの呼び出し

クラスの作成

class クラス名{
	フィールド
	フィールド
	・
	・
	メソッド
	メソッド
	・
	・
}
class Member{
	String name;	// フィールド
	int age;		// フィールド
	
	public void show(){		//	メソッド
		System.out.println(this.name + " " + this.age + "歳");
	}
}

クラスからインスタンスを生成

クラスはインスタンスを生成しないと使えない。

Member m = new Member();	// Memberクラスのインスタンスの作成

//	フィールドの設定
m.name = "田中";	
m.age = 30;

// メソッドの使用
m.show();

上の例のmはMemberインスタンスを入れるための変数。new Member()でMemberクラスのインスタンスを生成している。

コンストラクタ

class Member{
	String name;
	int age;
	
	public Member(){	//	これがコンストラクタ
		age = 30;		//	newしたときに ageに30が入る。
	}
}

オブジェクト生成の例(上のMemberクラスの場合)

Member m = new Member(); // 自動的にコンストラクタが呼ばれる

System.out.println( m.age );	//	30と表示

コンストラクタに引数

コンストラクタに引数を付けると、それをnewするときに指定できる

class Member{
	String name;
	int age;
	
	public Member(String n,int a){
		name = n;
		age = a;
	}
}

オブジェクト生成の例(上のMemberクラスの場合)

Member m = new Member("田中",30);

System.out.println( m.name );	//	田中と表示

フィールドを使用したコンストラクタはEclipseのメニューから[ソース]-[フィールドを使用してコンストラクタを生成]で自動的に作ることが出来る

クラスの配列

詳細はクラスの配列

宣言

クラス名[] 変数名 = new クラス名[];

Member[] members = new Member[3];	//	3人分

members[0] = new Member("佐藤",30);
members[1] = new Member("山田",25);
members[2] = new Member("加藤",40);

初期化

クラス名[] 変数名 = { new クラス名(),new クラス名(),new クラス名()};

Member[] members = {new Member(),new Member(),new Member()};

拡張forでのクラス配列

for( クラス名 変数名 : クラス配列名 ){
}
for( Member m : members ){
	m.show();
}

ArrayListの場合

ArrayList<クラス名> 変数名 = new ArrayList<クラス名>();

変数名.add( インスタンス );
// Memberクラスの場合
ArrayList<Member> list = new ArrayList<Member>();

list.add(new Member("佐藤",30););
list.add(new Member("山田",25););
list.add(new Member("加藤",40););

ArrayList 拡張for

for(Member m : list){
    System.out.println( m.name );
}

カプセル化

クラスのメンバを外部からアクセスできないようにする

アクセス指定

属性・コンストラクタ・メソッドの前に付ける

private同じクラスからのみアクセスできる
無指定同じパッケージからのみアクセスできる
protected無指定に加えサブクラスからはアクセスできる
publicどこからでもアクセスできる

属性の書き方

	private int num;

getterとsetter

慣習として

class Member{
	private String name;	// privateなので外部からアクセスできない
	
	public void setName(String n){
		name = n;
	}

	public String getName(){
		return name;
	}

}
// 外部からの利用例
Member m = new Member();

m.setName("鈴木");

String name = m.getName();

getterとsetterはEclipseのメニューから[ソース]-[getterおよびsetterを生成]で自動的に作ることが出来る

static

staticが付いた変数=クラス変数
staticが付いたメソッド=クラスメソッド
staticが付いていない変数=インスタンス変数
staticが付いていないメソッド=インスタンスメソッド

インスタンス変数、インスタンスメソッドはインスタンスの数だけ存在する。つまり、newした数だけ存在する。

クラス変数、メソッドはインスタンスの数に関わらず、常に1個のみ存在する。newしなくても1個存在するので、いきなり使用可能。

使用法:クラス名.メンバー名

class Animal{
	static void show(){
		System.out.println("動物");
	}
}

// 上のshowメソッドを使う場合
Animal.show();

staticが付いたメソッドからはstaticが付いた変数・メソッドしか扱えない

class Animal{
	String name;
	static int num;
	staic void show(){
		System.out.println(num);	//	OK
		System.out.println(name);	//	エラー
	}
}

継承

スーパークラス(親クラス)のフィールド・メソッドを全て引き継いでサブクラスを作る

class サブクラス名 extends スーパークラス名{
}
//例:Animalクラスを継承しDogクラス
class Animal{
	String name;
	void showName(){
		System.out.println(name);
	}
}

class Dog extends Animal{
	void naku(){
		System.out.println("ワン");
	}
}
Dog d = new Dog();
d.name = "ぽち";	//	スーパークラスの属性を使う
d.showName();	//	スーパークラスのメソッドを使う
d.naku();

オーバーライド

スーパークラスのメソッドをサブクラスで上書き

//例:Animalクラスを継承しDogクラス
class Animal{
	String name;
	void naku(){
		System.out.println("がおー");
	}
}

class Dog extends Animal{
	void naku(){
		System.out.println("ワン");
	}
}
Dog d = new Dog();
d.naku();	//	ワンと表示

多態性(ポリモフィズム)

スーパークラス型にサブクラスのインスタンスを代入可能

Animal a = new Dog();

変数の型にかかわらず、インスタンスのメソッドが呼び出される

Animal a = new Dog();
a.naku();	//	ワンと表示

なお、逆(サブクラス型の変数にスーパークラス型のインスタンスを代入)にはキャストが必要。

Animal a = new Dog();
Dog d = (Dog)a;

継承とコンストラクタ

コンストラクタは継承されないので、サブクラスのコンストラクタからはスーパークラスのコンストラクタを必ず呼び出す。

スーパークラスのコンストラクタは super(引数) で呼び出せる

class Animal{
	Animal(){
		System.out.print("動物");
	}
	Animal(String name){
		System.out.print(name);
	}
}

class Dog extends Animal{
	Dog(){
		super("犬");	//	Animal(String name)が呼び出される。
		System.out.print("わんわん");
	}
}

// Dogのインスタンスを作る
Dog d = new Dog();	//	犬わんわんと表示

スーパークラスのコンストラクタ呼び出しを書かない場合、自動的に引数無しのsuper()を書いたものと見なされる

class Animal{
	Animal(){
		System.out.print("動物");
	}
	Animal(String name){
		System.out.print(name);
	}
}

class Dog extends Animal{
	Dog(){
		// superを指定していないのでsuper() とみなされる
		System.out.print("わんわん");
	}
}

// Dogのインスタンスを作る
Dog d = new Dog();	//	動物わんわんと表示

呼び出すコンストラクタがスーパークラスにない場合、エラー

class Animal{
	Animal(String name){
		System.out.print(name);
	}
}

class Dog extends Animal{
	Dog(){
		// superを指定していないのでsuper() とみなされる
		System.out.print("わんわん");
	}
}

// Dogのインスタンスを作る
Dog d = new Dog();	//	エラー。Animal()が無い

抽象クラス

コード例

//例:Animalクラス
abstract class Animal{
	String name;
	abstract public void naku();	//	抽象メソッド
}

class Dog extends Animal{
	public void naku(){	//	必ずオーバーライド
		System.out.print("わんわん");
	}
}

インタフェース

コード例

//例:Animalクラス
interface Animal{
	void naku();	//	自動的に public abstract
}

class Dog implements Animal{

	public void naku(){	//	必ずオーバーライド
		System.out.print("わんわん");
	}

}

インタフェースを実装したクラスはそのメソッドを全てオーバーライドしなければならない。

オーバーライドしないなら、抽象クラスになる(抽象メソッドがあるので)。