大変お世話になっております。
反逆する武士
uematu tubasaです。
初回投稿日時:2023年10月22日(令和5年10月23日)
さて、本日は政治経済ブログということを捨て去ります。
Javaに関するお勉強の結果報告のような、まとめ記事のような、試験する前に、徹底的に見直すためのブログ記事になります。
はっきり申し上げて、SEOなんて二の次三の次です。
いつもの政治経済系のノリではございませんのでご容赦いただきたく。
勉強してて思ったことは、Java Silverよりも難易度が高いということです。
反逆する武士uematu tubasaってこんなに馬鹿なITエンジニアなの???って罵っていただいても問題ありません。
とあるポンコツITエンジニアが何とか一人前のJavaプログラマになるため、勉強します。
生温かい目で見ていただければ幸いに存じます。
ローカルクラスに関する問題
public class Sample6 {
private String message;
public Test6 test(String value) {
class A implements Test6{
// 注意点:ローカルクラスが参照するローカル変数は
// ローカルクラスの定義よりも前に宣言されていなければならない
@Override
public void excute() {
// コンパイルエラー(value)
// 囲んでいるスコープで定義されたローカル変数値は、
// final または事実上、final である必要があります。以下の行でコンパイルエラーです。
System.out.println(message + value);
}
}
value = "LocalClass";
message = "Hello, ";
return new A();
}
}
public class Main {
public static void main(String[] args) {
new Sample6().test("Java").excute();
}
}
public interface Test6 {
void excute();
}
【問題】上記のソースコードをコンパイルを実行したときの結果を述べなさい。
【回答】コンパイルエラーが発生します。
【解説】ローカルクラス(この場合はA)が参照するローカル変数(この場合value)はローカルクラスの定義よりも前に宣言されていなければならない。
匿名クラスに関する問題
public class Main {
public static void main(String[] args) {
// 匿名クラスとは、名前の無いクラスのこと。
// クラスの実装内容だけを定義したもの。
var sample = new Sample7(10) {
void modify(int num) {
setNum(num);
}
};
sample.modify(100);
System.out.println(sample.getNum());
public class Sample7 {
private int num;
public Sample7(int num) {
this.num = num;
}
public int getNum() {
return num;
}
public void setNum(int num) {
this.num = num;
}
}
【問題】上記のソースコードをコンパイルを実行したときの結果を述べなさい。
【回答】100がコンソール出力される。
【解説】このソースコードでは、Sampleクラスを継承した匿名クラスを定義しています。
この匿名クラスはmodifyというスーパークラスには無かった独自メソッドを定義しています。
modifyメソッドは、setNumメソッドを使ってスーパークラスのフィールドnumの値を100に書き換えています。
したがって、100がコンソール出力されます。
【注意】匿名クラスにおいては、コンストラクタを定義できない。
デフォルトメソッドのオーバーライドに関する問題
public interface A11 {
default void test() {
System.out.println("A");
}
}
public interface B11 {
default void test() {
System.out.println("B");
}
}
public interface C11 extends B11 {
}
public interface D11 extends C11{
}
public class Sample11 implements A11,D11{
@Override
public void test() {
A11.super.test();
// 以下は実装されていないインターフェースなので、
// インターフェース名を記述することができない。
B11.super.test();
Cll.super.test();
// D11というインターフェースのスーパーインターフェースの
// デフォルトのtest(この場合B11で定義されているメソッド)を実行
D11.super.test();
}
}
【問題】上記のソースコードをコンパイルして、実行することができるコードはどれか。
【回答】A11.super.test();とD11.super.test();であり、B11.super.test();とCll.super.test();はコンパイルエラーになります。
【解説】オーバーライドしたメソッドから、インターフェースのデフォルトメソッドを呼び出すとき、呼び出せるのは以下2点のみです。
1、直接関係しているインターフェース
2、そのインターフェースが継承しているスーパーインターフェース
デフォルトメソッドの問題
public interface A12 {
default void test() {
System.out.println("A");
}
}
public class B12 {
public void test() {
System.out.println("B");
}
}
public class C12 extends B12 implements A12{
}
public class Main {
public static void main(String[] args) {
A12 a = new C12();
a.test();
}
}
【問題】上記のソースコードをコンパイルして、実行結果を記述しなさい。
【回答】Bとコンソール出力される。
【解説】A12のtestメソッドが呼ばれそうだが、スーパークラスのメソッドが優先的に呼ばれる。
なぜならば、あくまでもインターフェースは型を提供するのが、目的であり、実装はクラスが提供するべきだから。
インターフェースのprivateメソッドに関する問題
public interface Sample14 {
// 以下はコンパイルエラー
private void a();
private void b() {
}
// 以下はコンパイルエラー
private default void c() {
}
}
【問題】上記のソースコードをコンパイルして、実行結果を記述しなさい。
【回答】コンパイルエラーになる。
【解説】インターフェースは本来、公開する型を定義するためのものです。
インターフェースに定義する抽象メソッドはpublicとみなされます。
処理内容を持たない抽象メソッドをprivateにすることはできません。
インターフェースのprivateメソッドは、あくまでもdefaultメソッドから利用されることを想定していることを忘れないように。
Enumに関する問題
public enum Sample16 {
A("hello"),B("hello"),C("hello");
private final String value;
// enum(列挙型)のコンストラクタはprivateで無ければならない
private Sample16(String value) {
System.out.println(value);
this.value = value;
}
@Override
public String toString() {
return this.value;
}
}
public class Main {
public static void main(String[] args) {
System.out.println(Sample16.A);
}
}
【問題】上記のソースコードをコンパイルして、実行結果を記述しなさい。
【回答】helloが4回コンソール出力される。
【解説】Enumが使用されるとき、列挙子が1つずつインスタンス化される。
したがって、3回「hello」とメソッド
mainメソッドでSystem.out.printlnにSample16.Aを私ているため、toStringメソッドが呼び出され、helloとコンソール出力される。
以上です。