継承
継承とは
以前作ったことのあるクラスと似通ったクラスを作る
コピペで作ると・・・
デメリット
1 追加・修正が大変
2 管理・把握が大変
継承したクラス
extendesというキーワードを使う
書き方
class クラス名 extends もとになるクラス{
親クラスとの差分メンバ(属性・操作)
}
差分だけでいいのは親クラスのメンバを引き継いでいるから
継承関係
継承してできた新しいクラスには、「継承関係」という
関係性ができる
もとになったクラス→親クラス(スーパークラス)
新しくできたクラス→子クラス(サブクラス)
継承の禁止事項
親クラスから見ると複数の子クラスを持つことはできるが
子クラスが複数の親は持てない
→多重継承の禁止
オーバーライド(上書定義)
継承のメンバを上書き更新する方法
オーバーライドの条件
1 継承関係であること
2 同名メソッド(シグネチャが同一)が親クラスにあること
※シグネチャ→引数の型・引数の個数・メソッド名の総称
戻り値の型
つまり・・・
親クラスに同じメンバがなければ「追加」
親クラスに同じメンバがあれば「上書き」
※親クラスの実行したい時はsuper.メソッド名でできる
継承の禁止にする方法
→finalを使う
(ex)
final void waru();
public final class Kanagata{}
コンストラクタ
→「属するクラス名と同じでなくてはいけない」というルールがあるので・・・
継承することができない
「継承すると必ず親クラスのインスタンス生成を行う」というルールがある
親クラスのコンストラクタ呼び出しが書かれていない場合は、
その呼び出し処理が自動的に用意される
書き方:super(引数);
これが自動的に挿入される
※コンストラクタの1行目にしか親クラスの呼び出しは書けない
引数がある時は自分で書かないとダメ・・・
自動追加はあくまで引数なしのもの
引数ありなしは合わせること
カプセル化
カプセル化とは
フィールドへの読み書きやメソッドの呼び出しを制限する機能
どうやって制限するのか
・フィールドのアクセス制御をする場合
アクセス修飾子 フィールド宣言;
・メソッドのアクセス制限をする場合
アクセス修飾子 メソッド宣言{・・・・}
アクセス修飾子
private 自分自身のクラスのみ
package private 自分と同じパッケージに属するクラス
procted 自分と同じパッケージに属するか自分を継承した子クラス
public 全てのクラス
※何もつけなかったらprivateパッケージがつく
GetterとSetter
カプセル化した取得用のメソッド群→Getter
カプセル化した設定用のメソッド群→Setter
プライベートを用意してGetterとSetterを作る
Getterの書き方
public 取り出すフィールドの型 getフィールド名(){
return フィールド名=変数名;
}
Setterの書き方
public void setフィールド名(フィールドの型 変数名){
this.フィールド名=変数名;
}
(ex)
public String getName( ){
return this.name;
}
public void setName(String name){
this.name=name;
}
Getter・Setterのメリット
1 Readonly・Writeonlyを実現できる
2 クラスの内部設計を自由に変更できる
フィールド名を変更してもメソッド名は変更しなくて良い
3 フィールドへのアクセスを検査できる
クラス機構
メモリ
コンピュータが持っている保存領域
メモリの動き
領域として空いているところに自動的にインスタンスが保存される
作った変数にはインスタンスが入っているわけではなく、保存場所
が入っている
クラス型をフィールドに
クラス定義した時にできる型も同じようにフィールドとして
扱うことができる
クラス型で引数や戻り値
クラス型は引数にも戻り値にも使用することができる
String型の真実
1 所属しているのがjava.langパッケージ
2 ””で文字列を囲むだけでインスタンス生成
(String型だけの特例)
((ex)”こんにちは”でインスタンス生成)
String str = new String("こんにちは");
と書いてもインスタンス生成が可能だけど・・・
実引数を渡している
✡実引数に追加じょうを渡してnewできる仕組み
生まれたてのインスタンスとは
インスタンスを生成した直後は中に何も入っていない
この状態をプログラム上でnullという
コンストラクタ(フィールドの初期値を設定する)
newというキーワードの後に自動実行されるもの
(ex)
Kanagata( ){
this.nakami = "あんこ";
}
コンストラクタ作成ルール
1 クラス名とコンストラクタ名にする
2 メソッドに似ているので引数が使える
3 メソッドと異なるのは戻り値が使えない
(ex)
Taneクラスに引数をつけたコンストラクタ作成
Tane(String name){
this.name = name;
}
複数コンストラクタ
1つのクラスに複数書くことができる
引数を変更し、用途により使い分ける
暗黙のコンストラクタ
インスタンス生成する場合、クラスは最低でも1つ以上のコンストラクタ定義を持っている。必要があるクラスに1つもコンストラクタが定義されていない場合、デフォルトコンストラクタがコンパイル時、自動的に追加される
※自分で作成する場合は引数を合わせること
※ローカル変数は優先度が高いので注意!
(this.をつけてフィールドを見るようにする!!)
静的メンバ(クラスフィールド・クラスメソッド)
静的・・・統一されていること
メンバ・・・フィールド+メソッド
各インスタンス同士で共有したい情報
1つの情報を共有できればムダなメモリを消費しなくなる
staticを付けると静的メンバにできる
→クラス側に存在し、インスタンス生成時にフィールドとして作成されない
インスタンス生成しても情報を使いたい時は
クラス名.フィールド名(メソッド名)
とすれば参照できる
(ex)Kanagata.SIZE
インスタンスとクラス
オブジェクトという用語
今までオブジェクトとして使ってたものを厳密にいう場合
インスタンスという方が正しいとされている
インスタンスを生み出す手順
インスタンスは設計図を元に生み出されている
その設計図をクラスという名前で呼ぶ
生み出す手順
1 クラスを定義する
2 クラスに基づいてインスタンスを生み出す
クラスとインスタンスが別な理由
クラス1つで大量のインスタンスが生成可能
クラス定義の後は・・・
できることが2つ増える
1 クラスを基にインスタンスを生成することができる
2 1で生成したインスタンスを格納する
変数の型が利用できるようになる
(ex)たい焼きを作成する
new Kanagata( ); →インスタンス生成
つまりnew クラス名;となる
たい焼きを箱に入れる
Kanagata k1 = new Kanagata( );
つまり
クラス名 変数名=new クラス名();
たい焼きの中身設定
k1.nakami ="あんこ";
つまり
変数名.フィールド名=値;
たい焼きへの指示(割る)
k1.waru( );
つまり
変数名.メソッド名;
thisとは・・・
自分自身のインスタンスという意味
.(ドット)は〜のという意味
(ex)
this.SIZE→自分自身のインスタンスのサイズ
※フィールドを見るときはthisを必ず使うこと
ローカル変数を優先するために(パソコンの動き)
複数クラスを用いた開発
長いプログラム
1 機能ごとにまとまった形で分割できればどこまで処理しているのか
わかりやすい
2 複数の人が同時に作業できる
→クラスを分割する必要がある
クラスを分割する
似た機能ごとにメソッドをまとめる
※クラス名の先頭は大文字にすること
複数ファイルのコンパイル
同じクラスにないメソッドの呼び出し方
書き方
クラス名.メソッド名(引数リスト)
※mainメソッドがあるものを実行すること
パッケージ
→分類分けしてまとめる
パッケージに所属する、という言い方をする
パッケージ名は小文字を使う
パッケージ名は .(ドット)で区切る
(ex)
overload.callパッケージ
package文
書き方
package 所属させるパッケージ名;
※一番上に書くこと!
完全限定クラス名(パッケージ名をつけたクラス名)
書き方
所属するパッケージ名.クラス名
→Full Qualified Class Name
省略してFQCNという
パッケージにするメリット
1 クラスの数が多くなると一元管理が難しくなること
2 異なるパッケージに所属していれば同じ名前のクラスが作れること(✡)
✡2つ目のメリットがおおきい!!
パッケージ名自体の重複
パッケージ名自体が同じになると区別ができにくくなってしまうので
インターネットドメイン名を逆にしたものを使うことを推奨されている
(ex)
milk.jpというドメイン名であれば
jp.milkというパッケージにする
※ドメイン名は世界で1つしかない!!
import文
毎回、完全限定クラス名を書くのは面倒なので・・・
import文を使う
書き方
1 import パッケージ名.クラス名;
2 import パッケージ名. * ;
※ *(アスタリスク)は全てを意味する
書く順番
package文もimport文もあるクラス
1 package文
2 import文
3 クラスの定義
アスタリスクを使った書き方
import overload.call.*;
import overload.out.*;
の2行がある時に
import overload.*;
の1行にすることはできない
※フォルダは見てくれない!クラスだけ!
※同名クラスを使いたい時は完全限定クラス名を使って指定する
(import文は使えない!)
java.langパッケージ
非常に基本的なクラスが入っているのでimport文を書かなくてもコンパイル時に
自動的にimport文が追加されるようになっている
メソッド
メソッドとは
プログラムが複雑になってくると・・・
・プログラムが長くなってきて、どこでどんな処理をしているのか
わかりずらい
・同じような処理が何度も出てきて効率が悪い
・同じ処理が何箇所にもあって、そのどれかを1つ直す場合
他も全部直す必要があり、見落としやすい
↑これらを解決するために・・・
プログラムを細かく分けて「部品化」する
この部品のことをメソッドという
メソッドの考え方
ただ単に細かく分ければいい・・・というものではない
「処理の流れから切り離して、必要に応じて呼び出す」
という考え方をする
メソッドの定義
→メソッドを作ること
書き方
public static 戻り値の型 メソッド名(引数リスト){
呼び出した時に実行する処理
}
メソッドを書く位置
メソッドの中にメソッドは書けないので、mainメソッドの
上か下に書く
メソッドの呼び出し
→必要に応じて呼び出す
書き方
メソッド名(引数リスト);
mainメソッドから順番に呼び出していく
メソッドは機能ごとの処理
各機能をひとつのメソッドに入れてしまうのはあまり良くない
メソッド間のデータの受け渡し
注意点
箱の名前が同じだったら自動的にデータが受け渡されるわけではない(スコープ外)
データを受け渡す仕組みが必要になる
引数と戻り値
引数(ひきすう)(パラメータ)
呼び出し元からメソッドに渡すデータのこと
何個でも、0でもok
戻り値(返り値)
メソッドから呼び出し元に渡すデータのこと
個数は0か1
2以上のデータを戻すことはできない(配列はok)
引数を受け取る
メソッド側はどんなデータが渡されるかわからないのでそれを受け取る箱が必要
そのため、引数は変数で受け取る
( )(丸カッコ)の中で変数を宣言すると引数として受け取ることができる
(※セミコロンはなしなので注意!)
メソッド側の引数のことを仮引数という
(ex)
public static void convertToAD (int heisei){
int ad = heisei + 1988;
}
メソッドに引数を渡す
渡したいデータをそのまま丸カッコの中に書く
(ex)
convertToAD(5)
convertToAD(x+1)
呼び出し元側の引数を実引数という
※実引数は仮引数のデータ型に合わせて指定する必要がある
メソッドから戻り値を返す
書き方
public static 戻り値の型 メソッド名(引数リスト){
呼び出された時に実行する処理
return 戻り値;
}
戻り値を戻すためにはreturn文を使う
戻り値は変数・リテラル・式も指定できる
戻り値がない(0個)の場合は戻り値の型としてvoidを指定する
メソッドの左を戻り値の型にしなければならない
メソッドから戻り値を受け取る
書き方
型 変数名=メソッド名(引数リスト);
戻り値をそのまま使う
戻り値は変数に入れず、直接使うこともできる
(ex)
return heisei+1;
引数を複数渡す
受け取る方も渡す方もカンマ(,)で区切って指定する
※引数の順序が重要(仮引数と同じ順番にする)
引数の型、数、並び順が違えば同じメソッド名を複数定義できる
呼び出し方は同じ
実引数と同じメソッドをJVMが自動判断
引数に配列を用いる
仮引数に使えるものは変数だけでなく配列も可能
1つの配列は1個と数える
値渡しと参照渡し
値渡し
値を仮引数に代入
参照渡し
アドレスを仮引数に代入
mainメソッドの仮引数
args = argments(引数)
コマンドライン引数
実行時に渡すデータ
書き方
java プログラム名 引数リスト