Java入門
はじめに
当記事はTECHSCOREのJava入門を私的勉強の為に読みながら内容を端的にまとめたものです。
内容的にはJavaにおける下記キーワード等の概念を理解するのに役立つと思います。
ロジックに関わる具体的な構文等についてはほとんど触れていません。
記事内の記述に誤り等あればご指摘いただければ幸いです。
- 変数
- クラス
- インスタンス
- 継承
- オーバーロード
- オーバーライド
- アクセス修飾子
Hello World!
public class Hello {
public static void main(String[] args) {
System.out.println("Hello World!");
}
}
- Javaのすべてのプログラムはクラス(Class Object)で構成されている。 (Hello)
- Public(後述)なクラスのクラス名はそのままファイル名になる必要がある。(Hello.java)
- クラスはインスタンス(Instance Object)のひな形であり、クラスを基にインスタンスが作成される。
- クラスから作成されたObjectを組み合わせてプログラムを動かすのがJavaのオブジェクト指向。
変数(Variables)
public class VarSample {
public static void main(String[] args) {
int a = 5;
System.out.println(a);
}
}
- Javaで変数を利用する際は型を指定し変数のを宣言する。
- 型にはプリミティブ型(基本データ型)とクラスを用いる参照型が存在する。
- 値の代入は後で行ってもよい。
プリミティブ型(基本データ型)一覧
種類 | 型 | 値 | bit数 |
---|---|---|---|
boolean | boolean | true/false | 1bit |
整数型 | byte | -128~128 | 8bit整数 |
整数型 | short | -32768~32767 | 16bit整数 |
整数型 | int | -2147483648〜2147483647 | 32bit整数 |
整数型 | long | -9223372036854775808〜9223372036854775807 | 64bit整数 |
整数型 | char | 1文字 | 16bit整数 |
浮動小数点型 | float | 単精度浮動小数点数 | 32bit実数 |
浮動小数点型 | double | 倍精度浮動小数点数 | 64bit実数 |
- 文字列はプリミティブ型ではなくjava.lang.Stringというクラスのインスタンス(参照型)として扱う。
- 数値型間の変換は可能でこれをキャストと呼ぶ。精度は変換先に準拠する。
float a = 3.14;
int b = (int)a; // b = 3
クラス
クラスとインスタンス
public class Human {
private String name = null;
private int age = -1;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age){
this.age = age;
}
public String toString(){
return "名前は" + name + "さんです。年は" + age + "歳です。";
}
}
- 上記クラスのHumanは特定個人を表現していない。あくまでもクラスは雛形でしかない。
- クラスから個々のインスタンスを生成し、それに情報を持たせることで特定個人を作る。
- クラスの修飾子は
public
,final
,abstract
などがある。
フィールド
public class Human {
private String name = null;
private int age = -1;
private static int NUM_EYE = 2;
}
- フィールドはクラス変数とインスタンス変数が存在する。
- クラス変数はクラスに属する変数で、アプリケーション全体で同じ値を参照する。
- インスタンス変数はインスタンスごとに持つ変数で、インスタンスごとの異なる値を参照する。
- 修飾子に
static
を加えるとクラス変数になる。 - 修飾子には
public
,protected
,private
,static
などがある。(後述)
メソッド
public class Human {
private String name = null;
private int age = -1;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
- メソッドはクラスとインスタンスの持つ機能や操作。
- 値を受け取り、受け取った値で処理を行い、処理の結果の値(戻り値)を返す。
-
void
(戻り値なし)以外を指定したメソッドは必ず指定した型の戻り値を返す必要がある。 -
this
はインスタンスを指し、引数の値と区別して使う。
オーバーローディング
public String getName() {
メソッド内処理 A
}
public String getName(int a, boolean b) {
メソッド内処理 B
}
- 同じ名前で呼び出しても引数の違いによって違うものが呼ばれるようにメソッドを定義することをオーバーローディングと呼ぶ。
-
getName()
としたら処理A、getName(10, true)
としたら処理Bが実行される。 - 同一シグネチャ(メソッド名、引数の型、引数の数、引数の並び順)を持つメソッドは定義できない。
継承
public class Student extends Human {
private String school = null;
public String getSchool() {
return school;
}
public void setSchool(String school) {
this.school = school;
}
public String toString() {
return "名前は" + name + "さんです。年は" + age + "歳です。学校は" + school + "です。";
}
}
-
extends Human
はStudent
クラスがHuman
クラスを継承していることを表す。 -
Human
のメンバ(フィールドとメソッド)は全てStudent
でも継承され定義されているので、利用できる。 - そのため、サブクラス(継承先のクラス)はスーパークラス(継承元のクラス)のインスタンスとして扱うことができる。
アクセス修飾子
修飾子 | 意味 |
---|---|
public | どのクラスからもアクセス可能 |
protected | サブクラスおよび同一パッケージのクラスからのみアクセス可能 |
修飾子なし(デフォルトアクセス) | 同一パッケージのクラスからのみアクセス可能 |
private | 同一クラスからのみアクセス可能 |
- アクセス修飾子を適切に設定することでアクセス制御を実現し、意図しない操作や内部の処理の隠ぺい(カプセル化)ができる。
- 継承にある
Student
クラスがHuman
から継承したtoString
はprivate
なフィールドname
とage
にアクセスしようとしている為、コンパイルエラーが起きる。 - 対応として
Human
クラスのフィールドをprivate
からpublic
やprivate
にすることでコンパイルエラーは解除できるがアクセス制御の目的から外れてしまう。 - 正しい対応としては
public
で作ったHuman
クラスのgetterメソッドを介して下記のように実装することで、アクセス制御を保ったまま意図通りの挙動になる。
public String toString() {
return "名前は" + getName() + "さんです。年は" + getAge() + "歳です。学校は" + school + "です。";
}
修飾子final
- クラスに
final
がつくと継承が不可能になる。 - メソッドに
final
がつくとオーバーライドが不可能になる。 - フィールドに
final
がつくとその値が定数になり変更が不可能になる。
オーバーライド
-
toString()
メソッドはHuman
クラスで定義されたものがStudent
クラスでオーバーライド(上乗せ)し再定義されている。 - オーバーライドは下記の規定がある。
- オーバーライドする側とされる側の戻り値の型、メソッド名、引数の型、引数の数、引数の並び順が同じであること。
- アクセスレベルが元のメソッドよりも緩くなっていないこと。
- オーバーライド元のメソッドが投げる例外以外の例外を、オーバーライド先のメソッドが投げていないこと。(ただし、元のメソッドの投げる例外を限定したものであればよい。)
- オーバーライド元のメソッドに修飾子 final がついていないこと。
- スーパークラスで abstract として定義されているメソッドはオーバーライドするか、サブクラス自身を abstract にしなければならない。
- オーバーライドしていることを明示的にするため、
@Override
というアノテーション(注釈)をつけることが推奨されている。 -
Student
クラスから親クラスであるHuman
クラスで定義したtoString()
を呼ぶこともできる。その場合はsuper.toString()
と記述する。(ただしprivate
メソッドの場合できない。)
public class Student extends Human {
private String school = null;
public String getSchool() {
return school;
}
public void setSchool(String school) {
this.school = school;
}
@Override
public String toString() {
return "名前は" + getName() + "さんです。年は" + getAge() + "歳です。学校は" + school + "です。";
}
}
インスタンスの生成
コンストラクタ
- コンストラクタは全てのクラスが持っている特殊なメソッドであり、インスタンスの初期化処理を実行する。
- インスタンス生成時に必ずコンストラクタが実行される。
- コンストラクタ名はクラス名と同一で、返り値は指定できない(voidも記述しない)。
- コンストラクタはメンバではないため、継承、オーバーライドもされない。
- クラス内で明示的に宣言しなくてもコンパイラが暗黙的に提供する。明示的な宣言ももちろん可能。
- コンストラクタを呼び出すのは基本的にインスタンス生成時、他コンストラクタからの呼び出し時となる。
インスタンスの生成
public class CSVReader {
public static void main(String[] args) {
Human taro = new Human();
}
}
-
new
演算子とコンストラクタHuman()
を用いてHuman
のインスタンスであるtaro
を生成している。
入出力とパッケージ
入出力
- Javaのデータ入出力はストリーム(Stream)という概念で行われる。
- 入出力の流れは必ず「ストリームを開く⇒データがなくなるまで書込/読込を行う⇒ストリームを閉じる」となる。
import java.io.FileReader;
import java.io.BufferedReader;
public class CSVReader {
public static void main(String[] args) {
FileReader reader = new FileReader("member.csv");
BufferedReader br = new BufferedReader(reader);
// ここに処理を記述
br.close();
}
}
外部ファイル:member.csv
MichaelDesanta,48
TrevorPhilips,48
FranklinClinton,28
-
import
文により他クラスを自クラス内で使えるようにできる。 -
import
なしだと下記のような記述になる。
java.io.FileReader reader = new java.io.FileReader("member.csv");
-
FileReader
型の変数reader
でmember.csv
を読み込んだFileReader
のインスタンスを代入している。 -
BufferReader
は読込をバッファして高速化する為に利用している。(FileReaderは逐次アクセスの為遅い)
パッケージ
- パッケージを利用してクラスファイルの管理を行い以下3つのメリットを享受できる。
- クラスファイル分類 - パッケージによる分類で目的のクラスがどこにあるか解りやすくなる。
- クラスファイル名の衝突防止 - 別パッケージであれば同クラス名が存在できる。(ただし利用時は片方を完全限定名にする必要がある)
- アクセス制御 - パッケージを基準にアクセス制御ができる。
- パッケージを指定せずともクラスファイルは作成できるが、扱いづらいため非推奨。
-
String
を含むjava.lang
パッケージのみ例外的にimport
の省略ができる。