Javaクラスの基礎
概要
「Java SE 11 Programmer II (1Z0-816-JPN) 試験」の出題範囲「Javaの基礎」の自己学習メモになります
final修飾子とstatic修飾子
final修飾子
適用箇所 | 説明 |
---|---|
クラス | final指定されたクラスを元に、サブクラスは作成できない |
メソッド | final指定されたメソッドを元に、オーバーライドできない |
変数 | final指定された変数は、定数 |
構文
クラスに適用
[アクセス修飾子] final class class名{ }
メソッドに適用
[アクセス修飾子] final 戻り値の型 メソッド名( 引数 ){ }
変数に適用
[アクセス修飾子] final データ型 変数名 = 初期値;
final修飾子を利用したクラスとメソッドのサンプルコード
class SuperA { }
final class SuperB {}
class SuperC { void print( ){ } }
class SuperD { final void print( ){ } }
class ChildA extends SuperA { } // OK
class ChildB extends SuperB { } // NG
class ChildC extends SuperC { void print(){} } // OK
class ChildD extends SuperD { void print(){} } // NG
static修飾子
クラス内に定義したメンバ間のアクセスルール
- クラス内で定義したインスタンスメンバ同士、staticメンバ同士は直接アクセスできる
- クラス内で定義したインスタンスメンバは、クラス内で定義したstaticメンバにアクセスできる
- クラス内で定義したstaticメンバは、クラス内で定義したインスタンスメンバにアクセスできない
サンプルコード
public class Test {
int instanceVal;
static int staticVal;
int methodA() { return instanceVal; } // OK
int methodB() { return staticVal; } // OK
static methodC() { return instanceVal; } // NG
static methodD() { return staticVal; } // OK
static methodE() { // OK
Test obj = new Test();
return obj.instanceVal;
}
}
列挙型
values()とvalueOf()メソッド
メソッド名 | 説明 |
---|---|
static 列挙型 values() | 列挙した値を全て配列で返す |
static 列挙型 valueOf(String name) | 引数で指定された名前を持つ値を全て返す |
Enumクラスの主なメソッド
メソッド名 | 説明 |
---|---|
final String name() | enum定数の名前を返す |
String toString() | enum定数の名前を返す このメソッドは任意でオーバーライドできるが、nameメソッドはオーバーライドできない |
final boolean equals( Object ohter ) | 指定されたオブジェクトがこのenum定数と同じ場合は、trueを返す |
final int hashCode() | enum定数のハッシュコードを返す |
static <T extends Enum<T>> T valueOf( Class<T> enumType,String name ) | 指定された名前をもつ、指定されたenum方のenum定数を返す |
final int ordinal() | 列挙宣言での位置を返す |
列挙型のポイント
- 列挙型の定義ではenumキーワードを使用する
- クラス宣言と同様に、コンストラクタ、メソッド、メンバ変数を定義できる
- コンパイルするとクラスファイルが生成される
- 列挙した値を参照するには、「列挙型名.列挙した値」とする
- newキーワードによるインスタンス化はできない
- 列挙型によって作成されたクラスはfinalクラスであるため、extendsによる継承はできない
- 抽象メソッドの利用やインターフェースの実装は可能
- 列挙型はComparableインターフェースを実装しており、確定数は明記した順番で管理される
Objectクラス
メソッド名 | 説明 |
---|---|
boolean equals( Object obj ) | 自オブジェクトとobjectを比較し、同じオブジェクトであればtrueを返す |
final Class<?> getClass() | このオブジェクトの実行時クラスを返す |
int hashCode() | オブジェクトのハッシュコードを返す |
String toString() | オブジェクトの文字列表現を返す |
equals()メソッドとhashCode()メソッドのオーバーライド
instanceof演算子
左辺で指定した変数が、右辺で指定した型をもっていればtrueを返す
左辺と右辺が同一の型でなくても、右辺がスーパクラスやインターフェースで、左辺がそのサブクラスや実装クラスであればtrueを返す
左辺と右辺が継承関係がまったくない場合は、コンパイルエラーとなる
インターフェース
インターフェースの特徴
- 変数を宣言すると、暗黙的にpublic static final修飾子が付与される
- インターフェースでの抽象メソッドで使用可能なのは、public、abstractのみ
- インターフェースでの具象メソッドでstaticメソッドは、public、private
- インターフェースでの具象メソッドでpublicメソッドの場合は、defaultのみ
- インターフェースでの具象メソッドで非staticメソッドは、privateのみ
staticな具象メソッド
構文
[アクセス修飾子] static 戻り値 メソッド名(引数) { 処理 }
static voide foo() { System.out.println("foo"); }
デフォルトメソッド
構文
[public] default 戻り値 メソッド名(引数) { 処理 }
default void foo() { System.out.println("foo"); }
SE9以降では、privateな具象メソッドも定義できるようになりました
構文
private [static] 戻り値 メソッド名(引数) { 処理 }
private void foo() { System.out.println("foo"); }
インターフェースの継承
構文
[修飾子] class クラス名 implements インターフェース名 { }
public interface Myinterface { } // インターフェース
public class MyClass implements Myinterface { } // 実装クラス
様々な実装クラス
コンパイルエラーになるサンプルコード1
interface A {
void method(); // 抽象method
}
interface X extends A {
@Override
default void method() { System.out.println("X"); }
}
interface Y extends A {
@Override
default void method() { System.out.println("Y"); }
}
class MyClass implements X,Y { } // このクラスが原因でコンパイルエラー
MyClassのmethodメソッドが呼び出された際に、XとYのどちらを呼び出せがいいか分からなくなるためコンパイルエラー
コンパイルエラーになるサンプルコード1を解決するサンプルコード1
class MyClass implements X,Y {
@Override
default void method() { System.out.println("MyClass"); }
}
MyClassで更にオーバーライドすればコンパイル、実行可能です
明示的に呼び出すサンプルコード2
class MyClass implements X,Y {
@Override
default void method() { X.super.method(); }
}
クラスが優先されて呼び出されるサンプルコード3
interface A {
void method();
}
interface X extends A { // Aインターフェースのサブインターフェース
@Override
default void method() { System.out.println("X"); }
}
class Y implements A { // Aインターフェースの実装クラス
@Override
public void method() { System.out.println("Y"); }
}
class MyClass extends Y implements X { }
public class Main {
public static void main( String[] args ) {
MyClass obj = new MyClass();
obj.method();
}
}
実行結果
Y
ネストクラス
java言語ではクラス定義の中に、さらにクラスを定義することができます。これをネクストクラスと呼びます
ネストクラスのルール
staticクラス/非staticクラス
- 外側のクラスと同じ名前(クラス名)は使用できない
- アクセス修飾子(public、private、protected)を使用できる
- abstract修飾子、final修飾子を使用できる
staticクラスのみ
- 非staticメンバ、staticメンバを持つことができる
- 外側のクラスで定義したインスタンス変数にアクセスできない
非staticクラスのみ
- staticメンバを持つことができない
- 外側のクラスで定義したインスタンス変数、static変数にアクセスできる
ネクストクラスのアクセス
構文
非staticクラスの場合
外側のクラス名.非staticクラス名 変数名 = new 外側のクラス名().new 非staticクラス名;
Outer.A a = new Outer.new A();
staticクラスの場合
外側のクラス名.staticクラス名 変数名 = new 外側のクラス名.staticクラス名;
Outer.B b = new Outer.B();
ローカルクラス
ローカルクラスとは、あるクラスのメソッド内に定義したクラスのことです
class Outer {
void method() {
class A { // ローカルクラス
}
}
}
ローカルクラスのルール
- アクセス修飾子(public、private、protected)を使用できない
- static修飾子を使用できない
- abstract修飾子、final修飾子を使用できる
- 外側のクラスのメンバにアクセスできる
- ローカルクラスから外側のクラスのメソッドの引数およびローカル変数にアクセスするには、各変数がfinalでなければならない
匿名クラス
匿名クラスとは、クラス名を指定せずに、クラス定義とインスタンス化を1つの式として記述したクラスのことです
class Outer {
void method() {
new スーパクラス名またはインターフェース名() { // 匿名クラス
}; // セミコロンは必須
]
}
匿名クラスのルール
- アクセス修飾子(public、private、protected)を使用できない
- static修飾子を使用できない
- abstract修飾子、final修飾子を使用できない
- 外側のクラスのメンバにアクセスできる
- 外側のクラスのメソッドの引数および、ローカル変数にアクセスできる(ただし、暗黙的にfinalであること)
Discussion