お久しぶりです。
引越しをして、家具を揃えたりして、忙しかったです。
GWには全く勉強できませんでした。
6月中の合格を目指して、勉強再開しますか!
OCJ-Pでは、オーバーライド関連は嫌と言うほど出題されます。
基本的なことを確実に押さえておくことが大事ですね。
一番簡単なオーバーライドは次のソースです。
//START
public class A {
protected void test(){
System.out.println("A");
}
}
public class B extends A{
public static void main(String[] args){
A a = new B();
a.test();
}
void test(){
System.out.println("B");
}
}
//END
実行したときの結果は、AかBのどちらが出力されますか?
・
・
・
もちろん、Bですね。
ポイントは↓↓
A a = new B();
このところですね。
変数 a は、型はAですが、Bとしての振る舞いをします。
言い換えれば、箱はAですが、中身はBなんです。
だから、Bのtest()が呼ばれます。
よって、Bが出力されるんですね。
public class Sample {
int i1;
void test(){
int i2;
System.out.println(i1);
System.out.println(i2);
}
public static void main(String[] args){
Sample sample = new Sample();
sample.test();
}
}
実行結果はどうなると思いますか?
この問題が、初期化の大きなポイントです。
(答えは最後)
まず、初期化とは1回目の代入をすること。です。
メモリ関連の話をすると、もう少し深くなるのでしょうが、
OCJ-Pではその程度の理解でも十分です。
覚えておくべきことは、初期化の意味ではなくて、
Javaでは『自動で初期化しといてくれる。』
ということ。
ただし!
言語規定 4.5.3 変数の種類 の中にある、
局所変数(メソッド内で宣言した変数。ローカル変数ともいう)はしてくれない。
局所変数は、自動で初期化してくれないので、
必ず自分で初期化する必要があるのです。
ですので、初期化していないまま、
その変数を参照しようとするコードを書くと、
コンパイルエラーが発生するわけです。
つまり、問題の答えは、
System.out.println(i2);
の箇所でコンパイルエラーが発生する。
です。
一行上のSystem.out.println(i1);
では、0と表示されます。
これは、i1はメンバフィールドなので、
Java側で自動的に初期化してくれるから。
int 型の場合、0を自動的に代入してくれるんです。
何を代入しといてくれるかは、
言語規定の4.5.5 変数の初期値 を見て下さい。
int i1;
void test(){
int i2;
System.out.println(i1);
System.out.println(i2);
}
public static void main(String[] args){
Sample sample = new Sample();
sample.test();
}
}
実行結果はどうなると思いますか?
この問題が、初期化の大きなポイントです。
(答えは最後)
まず、初期化とは1回目の代入をすること。です。
メモリ関連の話をすると、もう少し深くなるのでしょうが、
OCJ-Pではその程度の理解でも十分です。
覚えておくべきことは、初期化の意味ではなくて、
Javaでは『自動で初期化しといてくれる。』
ということ。
ただし!
言語規定 4.5.3 変数の種類 の中にある、
局所変数(メソッド内で宣言した変数。ローカル変数ともいう)はしてくれない。
局所変数は、自動で初期化してくれないので、
必ず自分で初期化する必要があるのです。
ですので、初期化していないまま、
その変数を参照しようとするコードを書くと、
コンパイルエラーが発生するわけです。
つまり、問題の答えは、
System.out.println(i2);
の箇所でコンパイルエラーが発生する。
です。
一行上のSystem.out.println(i1);
では、0と表示されます。
これは、i1はメンバフィールドなので、
Java側で自動的に初期化してくれるから。
int 型の場合、0を自動的に代入してくれるんです。
何を代入しといてくれるかは、
言語規定の4.5.5 変数の初期値 を見て下さい。
OCJ-Pで、インターフェース(Interface)関連の問題は、
確実に出るので、インターフェースの使い方はしっかり理解しておきましょう。
注意点を挙げます。
//OK-----------------
Interface A{}
Interface B{}
Interface X extends A,B{}
//--------------------
は可能ということ。
私は上のことを理解していなかったために、
「正しくインターフェースが実装されているソースを選びなさい」
というような問題が出てきたときに、それを選ぶことができませんでした。
Interfaceは、クラス・抽象クラスを継承できません。
//Error-----------------
class A{}
Interface X extends A{}
//---------------------
インターフェースは実装されたクラスをもつことはできないからです。
又、クラス・抽象クラスはインターフェースを継承できません。
実装はできるということもしっかり区別しておきます。
//Error------------------
Interface A{}
class X extends A{}
//----------------------
//OK-------------------
Interface A{}
class X implements A{}
//----------------------
「そんなこと基本じゃん!」という声が聞こえてきそうですが、
いざ試験になったら、自分の記憶に自信が持てないものです。
インターフェースの実装の仕方は必ず出題されるので、
どのパターンは実装・継承できるのか、
区別してきちんと覚えておくことが大切です。
確実に出るので、インターフェースの使い方はしっかり理解しておきましょう。
注意点を挙げます。
//OK-----------------
Interface A{}
Interface B{}
Interface X extends A,B{}
//--------------------
は可能ということ。
私は上のことを理解していなかったために、
「正しくインターフェースが実装されているソースを選びなさい」
というような問題が出てきたときに、それを選ぶことができませんでした。
Interfaceは、クラス・抽象クラスを継承できません。
//Error-----------------
class A{}
Interface X extends A{}
//---------------------
インターフェースは実装されたクラスをもつことはできないからです。
又、クラス・抽象クラスはインターフェースを継承できません。
実装はできるということもしっかり区別しておきます。
//Error------------------
Interface A{}
class X extends A{}
//----------------------
//OK-------------------
Interface A{}
class X implements A{}
//----------------------
「そんなこと基本じゃん!」という声が聞こえてきそうですが、
いざ試験になったら、自分の記憶に自信が持てないものです。
インターフェースの実装の仕方は必ず出題されるので、
どのパターンは実装・継承できるのか、
区別してきちんと覚えておくことが大切です。