クラスの理解
オーバーロードとオーバーライドの違い
- オーバーライドはスーパークラスで定義されたメソッドをサブクラスで再定義すること
- オーバーロードは同一クラス内で、メソッド名が同一で引数の型、数、並び順が異なるメソッドを複数定義すること
全然違う!
メソッドのオーバーロード
同じクラスに、同じ名前で、引数の型や並びが異なるメソッドを定義することを、メソッドのオーバーロードという。メソッドのオーバーロードは、引数の型を変えれば複数定義出来るが、同じ名前のメソッドができることになるので、オーバーロードする場合は処理は同じ種類に限定すべき。
class Person {
String name;
int age;
// コンストラクタ
Person(String name, int age) {
this.name = name;
this.age = age;
}
void showInfo() {
System.out.println("引数なしのメソッド");
System.out.println("名前 : " + name + " / 年齢 : " + age + "歳");
}
void showInfo(String msg) {
System.out.println("メソッドのオーバーライド");
System.out.println("名前 : " + name + " / 年齢 : " + age + "歳");
}
}
class PersonSample {
public static void main(String[] args) {
Person p = new Person("花村太郎", 60);
p.showInfo();
p.showInfo("こんにちは");
}
}
シグネチャ(signature:署名、サイン。一意であるという意味か)はメソッド名と変数の並びのこと。仮引数の名前ではなく、変数の型と順序で判断される。
void add(int a, String b){
//...
}
void add(String a, int b){
//...
}
上記でもコンパイルは通る。組み合わせではなく、順序が違えばOKっぽい。
またコンストラクタもオーバーロード出来る。コンストラクタから別のコンストラクタを呼び出して重複する処理をまとめることができる。thisで同名のコンストラクタ(引数の型・順序が一致するもの)を呼び出せる。
デフォルトのコンストラクタ(引数なし)のものが暗黙的に存在する(書かなくても呼び出せる)。クラス内で定義した場合、デフォルトのコンストラクタは消えて呼び出せなくなる。必要な場合、新規に引数なしのコンストラクタを定義する。
Person(String name) {
this(name,99);
}
インスタンス変数は参照型
データ型には、基本データ型と参照型の2種類ある。インスタンス(クラス型)の変数は参照型。参照はアドレス、ポインタと呼ばれる。Javaはポインタはあるが、ポインタの値自体を操作できない。
Person p = null;
p.showInfo(); // NullPointerException
値渡しと参照渡し
- メソッドの引数で値そのものを渡すことを値渡し(pass by value)
- メソッドの引数で参照を渡すことを参照渡し(pass by reference)
と呼ぶ。
static修飾子
- staticを付けるとクラスに属するフィールド、メソッドになる
- staticを付けないとインスタンスに属するものになる
class Person {
//スタティックなフィールド
static int counter;
String name = "John Doe";
int age = 120;
// コンストラクタ
Person(String name, int age) {
this.name = name;
this.age = age;
counter++;
}
Person() {
counter++;
}
void showInfo() {
System.out.println("名前 : " + name + " / 年齢 : " + age + "歳");
}
static void showCount(){
System.out.println("作成した人の数は" + counter + "人です");
}
}
class PersonSample {
public static void main(String[] args) {
//Person.counter = 100;
Person p = new Person("花村太郎", 60);
Person p2 = new Person();
Person.showCount(); // 2
}
}
staticメソッドはインスタンスが持つ値に依存しないため、簡単に呼び出したいメソッドなどで利用できる。グローバル変数のようなもので、バグの原因になりやすい。
イニシャライザ
コンストラクタ以外のクラスの初期化で利用される。{...}
、またはstatic{...}
で囲う。
定数
final static int SEIJIN_AGE = 20;
みたいな書き方。finalとstaticは順序逆でも通る。
アクセス修飾子
クラスの外部からのアクセスを制御するための修飾子。public/private/protectedがある。
アクセス修飾子 | アクセス可能な範囲 |
---|---|
public | 全てのクラス |
protected | 同じパッケージ内のクラス、サブクラスのみ |
(指定なし/デフォルト) | 同じパッケージ内のクラスのみ |
private | 同じクラス内のみ |
上記テーブルは上から下にアクセス制限が強くなる。
- クラスに指定できるアクセス修飾子 : public or 指定なし
- メンバに指定できるアクセス修飾子 : public or private or protected or 指定なし
セッタ、ゲッタ
基本的に、フィールドはprivateで宣言して、セッタ、ゲッタを用意する。クラスのアクセス修飾子と合わせてセッタ、ゲッタを使うことで、カプセル化する。
class SetterGetterSample{
private String message;
final static String GREETING = "HELLO";
public void setMessage(String message){
this.message = message;
}
public String getMessage(){
return message;
}
}
class SetterGetterSampleMain{
public static void main(String[] args){
SetterGetterSample sg = new SetterGetterSample();
// フィールド SetterGetterSample.message は不可視です
// System.out.println(sg.message);
// System.out.println(sg.GREETING);
sg.setMessage("hogehoge");
System.out.println(sg.getMessage());
}
}
Eclipseでのセッタ、ゲッタの自動生成
Eclipseではprivateのメンバ及び定数にセッタ、ゲッタメソッドを自動生成出来る。便利。書き方は、privateで宣言して、メニュー→ソース→getterおよびsetterの生成から、ダイアログボックスを呼び出して、チェックボックスで選んで生成。
標準ライブラリとAPIリファレンス
//ライブラリのインポート
import java.io.IOException;
import java.util.Date;
//同じパッケージを複数呼び出すような場合、以下の書き方でもOK
import java.util.*;
完全限定クラス名
public class PackageImportSample {
public static void main(String[] args) {
//こういう呼び出し方もOK(あんまりやらないけど)
java.util.Random rand = new java.util.Random();
int num = rand.nextInt(10);
System.out.println(num);
}
}
標準ライブラリ
java.lang
は暗黙的にインポートされている。
APIリファレンスを見る
使ったメソッドやクラスはなるべく目を通す癖をつける。
Systemクラスの利用
public class SystemSample {
public static void main(String[] args) {
//start time
//現在時刻をミリ秒で取得
long time1 = System.currentTimeMillis();
long num = 0;
for(long i = 0; i <= 100000 * 10000; i++){
//無限級数的なやつ。
num += i;
}
//end time
long time2 = System.currentTimeMillis();
System.out.println("count = " + num);
System.out.println("time = " + (time2 - time1) + " ms");
}
}
Dateクラスの利用
import java.util.Date;
public class DateSample {
public static void main(String[] args) {
Date d = new Date();
System.out.println(d);
//推奨されていないDate.getDay()メソッド、Eclipseでは打ち消しで表示される。
//JDK version 1.1以降は、Calendar.get(Calendar.DAY_OF_WEEK)に置き換えられています。
String s = String.valueOf(d.getDay());
System.out.println(s);
}
}
Calendarクラス、SimpleDateFormatクラスの利用
SimpleDateFormatクラスと合わせて書いてみた。
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
public class CalendarSample {
public static void main(String[] args) {
/* Calendarクラスの書き方 */
//CalendarクラスはgetInstanceというstaticなメソッドを呼び出す...ファクトリーメソッド
Calendar cal = Calendar.getInstance();
System.out.println("今日は" + cal.get(Calendar.YEAR) + "年" + (cal.get(Calendar.MONTH) + 1) + "月" + cal.get(Calendar.DATE) + "日です。");
//SimpleDateFormatの書き方
Date date = new Date();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy/mm/dd");
String txt = sdf.format(date);
System.out.println("今日は" + txt + "です。");
}
}
String型からDateを作成しようとしたところ、
//文字列からDateを作成する例
SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy/mm/dd");
String txt2 = "2014/08/01";
Date date2 = sdf2.parse(txt2);
ParseExceptionでエラーになった。今日はここまで。
その他・雑記
kobito.app
インストールした。使い勝手よさ気だけど、windowsで作業する場合に引っかかると嫌なので、しばらくはウェブからノートを取ることにする。
KeyRemap4MacBook→Karabiner
MacBookProの標準キーボードの上下移動キーがどういったわけか3ヶ月くらい前から使えなくなってしまい、KeyRemap4MacBookのお世話になっていたところ、ソフトウェアアップデートでKarabinerに名前変更されてた。とはいっても、基本的には他ソフトウェアのアップデートと変わらず、ダウンロード&アップデートして、アプリケーション名変わったこともあり、再度管理者権限でアクセシビリティ変更するだけ。
別件だけど、カーソル移動が遅いので、キー入力の反応速度を早くするように、システム環境設定→Karabiner→KeyRepeatタブの、DelayUntilRepeatとKeyRepeatの数値を、キー入力しながら変更。それぞれ0と20にした。とりあえず早くなった。
Windowsのキーリピートの反応速度変更は、Windows環境の時に調べることにする。