午後問題の歩き方 | Java プログラミング問題の楽勝パターン(2)オブジェクト指向


2020-01-09 更新

前回の記事では、「 C 言語と Java のどちらかを選択する予定だ」という人に、

「試験当日の問題次第ですが、生半可に Java ができるというレベルでは、Java を選ばない方が無難かもしれませんね」

というアドバイスをしました。

午後問題の歩き方|
Java プログラミング問題の難易度(1)Java基本構文

ただし、「ぜひ Java を選んでください!」とアドバイスしたくなるような問題もあります。

それは、 継承や多態性などのオブジェクト指向がテーマの問題 です。オブジェクト指向が苦手でないなら、きっと楽勝のはずです。

実際の問題を見てみましょう。

info 編集部注: 本記事では読みやすいよう、シンタックスハイライトを入れています。実際の試験では白黒です。ご注意くださいませ。

 

抽象クラスや抽象メソッドを知っていれば楽勝

以下は、平成 29 年度 春期 午後 問 11「電気料金プランの比較」 の設問 1 の一部です。

プログラムの説明は省略しますが、空欄 a に入るものを解答群から選んでください。

 

[プログラム 1]

'[ 空欄a ]' class TierTable {
   final double[][] pairs;
  
  TierTable(double... tiers) {
    if (tiers, length % 2 == 1) {
      throw new IllegalArgumentException("不正な長さ: " + tiers, length);
    }
    double[][] a = new double[tiers, length / 2][]; 
    for (int i = 0; i < tiers, length; i += 2) {
      a[ '[ 空欄b ]' ] = new double[] { tiers[i], tiers[i + 1] };
    }
    this.pairs = a;
  }
  abstract double map(double amount);
}
a に関する解答群

ア abstract  イ final  ウ private
エ protected  オ public  カ static

 

TierTable クラスには、abstract double map(double amount); という抽象メソッドがあります。

抽象メソッドを持つクラスは、インスタンスを生成できないので、class の前に abstract を指定して抽象クラスにしなければなりません。

したがって、正解は、選択肢アです。

いかがですか。「えっ! こんなに簡単でいいの?」と言いたくなるような問題でしょう。

 

ただし、そう思えるのは、オブジェクト指向の概念である抽象クラスや抽象メソッドを知っているからです。

 

継承を知っていれば楽勝

以下は、同じ年度の問題の設問 2 の一部です。プログラムの説明を読んで、空欄eに入るものを解答群から選んでください。

 プログラム 6 は,割引プランを表すためのクラス DiscountPlan である。 DiscountPlan は,クラス RatePlan を拡張し,上位クラスである RatePlan のメソッド getPrice で求めた電気料金から割引率を求め,割引を適用した金額を電気料金として計算する。プログラム中の       に入れる正しい答えを,解答群の中から選べ。

[プログラム 6 ]

class DiscountPlane '[ 空欄e ]' Rateplan {
   private final TierTable discountTiers;
  
   Discount Plan(String name, double basicCharge,
                 TierTable pricingTiers, TierTable discountTiers) {
     super (name, basicCharge, pricingTiers);
     this. discountTiers = discount Tiers;
   }
  
   int getPrice (double amount) {
     int price = '[ 空欄f ]'.getPrice(amount);
     return (int) (price * '[ 空欄g]' );
   }
}
e に関する解答群

ア extends  イ implements  ウ imports
エ public  オ throws

 

プログラムの説明に「 DiscountPlan は、クラス RatePlan を拡張し」と示されています。これは、「 RatePlan クラスを継承して DiscountPlan クラスを定義する」という意味です。

Java では、継承 を extends(拡張する) というキーワードで示します。したがって、正解は、選択肢アです。

これも、「えっ! こんなに簡単でいいの?」と言いたくなるような問題でしょう。

 

ただし、そう思えるのは、オブジェクト指向の概念である継承を知っているからです。( 2 回目)

 

PR

 

継承におけるコンストラクタの取り扱いを知っていれば楽勝

今度は、平成 26 年度 春期 午後 問 11「雑誌記事のオンライン購読サイト」 の設問 1 の一部です。プログラムの説明は省略しますが、空欄 b に入るものを解答群から選んでください。

 

[プログラム 5 ]

class PaidMember extends Member {
   PaidMember(String name) {
     '[ 空欄b ]';
   }
  
   boolean testAndMark(Article article) {
     return '[ 空欄d ]';
   }
}
b に関する解答群

ア new User(name)  イ super()  ウ super(name)
エ super.name = name  オ this()  カ this(name)
キ this.name = name  ク User(name)

 

class PaidMember extends Member { } という構文から、Member クラスを継承して PaidMember クラスを定義しています。

PaidMember クラスの中にある PaidMember(String name) { } は、クラス名と同名のメソッドなので、コンストラクタ です。

多くの場合に、コンストラクタ では、引数の値をフィールドに格納する処理が行われます。

ここでは、引数 name を何らかのフィールドに指定するはずです。ところが、PaidMember クラスには、フィールドがありません。

なぜでしょう。

 

フィールドは、継承元の Member クラスにあるからです。

 

それでは、継承元の Member クラスのフィールドに 引数 name の値を渡すには、どうしたらよいでしょう。

選択肢をヒントにして考えてみましょう。

super(name); という構文で、継承元のクラスのコンストラクタを呼び出せばよいことに気づくはずです。正解は、選択肢ウです。

 

これも、オブジェクト指向の概念である継承と、継承におけるコンストラクタの取り扱いを知っていれば、楽勝の問題です。

 

クラスの継承とインターフェイスの実装の違いを知っていれば楽勝

続いて、平成 24 年 秋期 午後 問 11「スレッドを利用したタイマ」 の設問 1 の一部です。ここでも、プログラムの説明は省略しますが、空欄 c に入るものを解答群から選んでください。

 

[プログラム 1]

public interface TimerAction {
   public void onStart(Timer timer, long instant);
   public void onAlarm(Timer timer, long instant);
   public void onCancel(Timer timer, long instant);
}

 

[プログラム 3]

import java.util.Date;

public class TimerTest '[ 空欄c ]' TimerAction {
   Timer longTimer, shortTimer;
  
   private void test() '[ 空欄d ]' InterruptedException {
     longTimer = Timer.createTimer("long timer", '[ 空欄e ]', 4);
     shortTimer = Timer.createTimer("short timer", '[ 空欄e ]', 2);
     shortTimer.close();
     longTimer.close();
   }
  // 中略
}
c, d に関する解答群

ア expands  イ extends  ウ implements
エ subclasses  オ throw  カ throws

 

TimerAction は、クラスではなくインターフェイスです。クラスは extends キーワードで継承しますが、インターフェイスは implements キーワードで実装する ものです。

ここでは、TimerTest クラスが TimerAction インターフェイスを実装します。したがって、空欄 c に入るのは、選択肢ウの implements です。

 

ついでに、空欄 d に入るものも選んでみましょう。

public void test() の後に空欄 d があり、その後に InterruptedException という例外クラスが指定されています。

これは、「 test() メソッドが InterruptedException 例外を投げる」という表現です。したがって、空欄 d には、選択肢カの throws が入ります。

 

この空欄 d は、オブジェクト指向に直接関係していませんが、Javaの例外に関する構文を知っていれば、楽勝のはずです。こういう問題も出るのです。

 

インターフェイスを使った多態性を知っていれば楽勝

最後に、もう 1 つだけ楽勝の問題を紹介しましょう。

以下は、平成 23 年度 春期(特別試験)午後 問 11「追加可能な文字列インターフェイスの 2 種類の実装」 の一部です。

プログラムを示しませんが、AppendableCharSequence インターフェイスと、それを実装した ArrayAppendableCharSequence クラス、および ListAppendableCharSequence クラスがあります。

同じインターフェイスで定義されたメソッドを、2つのクラスが実装(メソッドの処理内容をそれぞれのクラスに合わせて記述)しているのです。

これは、多態性 です。

 

以下に示したプログラムの空欄 e には、引数 a に、ArrayAppendableCharSequence クラスのインスタンスと、ListAppendableCharSequence クラスのインスタンスの、どちらでも指定できるデータ型を入れることになります。

それは、AppendableCharSequence インターフェイスです。

同じインターフェイスを実装したクラスのインスタンスは、そのインターフェイスをデータ型とすることができます。

 

これは、多態性を使ったプログラムで定番の表現です。知っていれば、楽勝! 楽勝です!

 

[プログラム 4 ]

public class Test {
   static final int[] TIMES = {
     5000, 10000, 50000, 100000
   };
  
   public static void main(String[] args) {
     for (int n : TIMES) {
       measureTime(n, new ArrayAppendableCharSequence());
       measureTime(n, new ListAppendableCharSequence());
     }
   }
  
   static void measureTime(int n, '[ 空欄e ]' a ) {
     long start = System.currentTimeMillis();
     for (int i = 0; i < n; i++) {
       a.append((char) (i % 26 + 'a'));
     }
     long end = System.currentTimeMillis();
     System.out.printf("%s: %d [times ] %d [ms]%n",
                       a.getClass().getName(),
                       n, end - start);
   }
}
e に関する解答群

ア AppendableCharSequence
イ ArrayAppendableCharSequence
ウ ListAppendableCharSequence
エ ListAppendableCharSequence.Bucket
オ Object
カ String

 

今回の記事では、「オブジェクト指向が苦手でないなら楽勝」という問題を紹介しましたが、C言語 より Java の方が常に楽勝なわけではありません。

C 言語と Java のどちらかを選択する予定の人は、試験当日の問題の内容を見て、慎重に判断してください。

中途半端に Java に手を付けてから「やっぱり C 言語に変えよう」とならないように、くれぐれも注意してください。時間を大幅にロスしてしまうからです。

 

それでは、またお会いしましょう!

 

label 関連タグ
午前試験の『免除』制度を活用しよう 午前免除試験が最大 2 回受験できる
IPA 認定 e ラーニング 独習ゼミ
最大 20 % OFF
早割キャンペーン中!!
alarm早割キャンペーン中!!

詳しく見てみるplay_circle_filled
label これまでの『午後問題の歩き方』の連載一覧 label 著者

『プログラムはなぜ動くのか』(日経BP)が大ベストセラー
IT技術を楽しく・分かりやすく教える“自称ソフトウェア芸人”

大手電気メーカーでPCの製造、ソフトハウスでプログラマを経験。独立後、現在はアプリケーションの開発と販売に従事。その傍ら、書籍・雑誌の執筆、またセミナー講師として活躍。軽快な口調で、知識0ベースのITエンジニアや一般書店フェアなどの一般的なPCユーザの講習ではダントツの評価。
お客様の満足を何よりも大切にし、わかりやすい、のせるのが上手い自称ソフトウェア芸人。

主な著作物

  • 「プログラムはなぜ動くのか」(日経BP)
  • 「コンピュータはなぜ動くのか」(日経BP)
  • 「出るとこだけ! 基本情報技術者」 (翔泳社)
  • 「ベテランが丁寧に教えてくれる ハードウェアの知識と実務」(翔泳社)
  • 「ifとelseの思考術」(ソフトバンククリエイティブ) など多数