基本情報技術者試験の過去問と解説
[TOP] [午前分野別] [午後分野別] [キーワード索引] [令和元年秋午前] [令和元年秋午後]

平成26年 春期 基本情報技術者 午後 問11
問11   Java

問11 次の Java プログラムの説明及びプログラムを読んで,設問1,2に答えよ。

〔プログラムの説明〕

 雑誌記事のオンライン購読サイトをモデルとしたプログラムである。記事には, 無料記事と有料記事がある。サイトの利用者は,誰でも無料記事を閲覧できる。利用者は, 名前を登録することで登録会員となり,無料記事に加え,有料記事を1日に1本だけ無料で 閲覧できる。登録は無料である。登録会員は,購読料を支払うことで有料会員となり, 全ての記事を無制限に閲覧できる。

 このプログラムは,次のクラスから成る。

(1) クラス Article :記事を表す。

 各記事には,記事識別子(id)が割り当てられる。各記事は,見出し (headline),本文(body)及び無料記事を表すフラグ(free)から成る。 記事識別子と記事は,1対1に対応し,同一記事に対して Article のインスタンスは 高々1個しか存在しない。

@ 静的メソッド create:引数で与えられた記事識別子及び記事のデータから Article のインスタンスを生成し,登録する。記事識別子に重複はないものとする。

A 静的メソッド getArticle:引数で与えられた記事識別子から 登録されている記事である Article のインスタンスを返す。記事識別子に誤りはないものとする。

B 静的メソッド getIds:登録されている全記事の記事識別子の集合を返す。

C メソッド isFree:無料記事であれば true を返す。そうでなければ,false を返す。

D その他,記事のデータを返すメソッドが用意されている。

(2) 抽象クラス User:利用者を表す。

@ コンストラクタ:引数で与えられた利用者名をもつインスタンスを生成する。

A メソッド getName:利用者名を返す。

B 抽象メソッド testAndMark:引数で与えられた記事が閲覧可能かどうかを調べ, 閲覧可能であれば true を返す。そうでなければ,false を返す。 このメソッドが true を返したとき,サイトは利用者に記事を表示するものとし, 必要に応じて記事が閲覧済みであることを記録する。

(3) クラス Guest:未登録の利用者(ゲスト)を表す。

@ コンストラクタ:利用者名を“ゲスト”とするインスタンスを生成する。

A メソッド testAndMark:引数で与えられた記事が無料記事であれば true を返す。 そうでなければ,falseを返す。

(4) クラス Member:登録会員を表す。

@ コンストラクタ:引数で与えられた利用者名をもつインスタンスを生成する。

A メソッド testAndMark:引数で与えられた記事が無料記事であれば,true を返す。 有料記事の場合は,今日最初の有料記事の閲覧のとき,又は今日閲覧済みの有料記事と 同一であるときは,true を返す。それら以外のときは,false を返す。 加えて,今日最初の有料記事の閲覧のときには,閲覧済みの記事として今日の日付とともに記録する。

B メソッド today:今日の日付(ローカル時間)を 1970 年1月1日からの日数で返す。

(5) クラス PaidMember:有料会員を表す。

@ コンストラクタ:引数で与えられた利用者名をもつインスタンスを生成する。

A メソッド testAndMark:全ての記事に対して true を返す。

(6) クラス SubscriptionSite:上記クラスのテスト用プログラムである。メソッド main を 実行すると,図1の結果が得られる。

 なお,Member 及び PaidMember のコンストラクタに与える利用者名の衝突は,ないものとする。

ゲスト:記事「 PC 入門」PC 初心者…
ゲスト:記事「スマホ特集」<閲覧不可>
ゲスト:記事「アプリガイド」使えるアプリ…
登録会員A:記事「 PC 入門」PC 初心者…
登録会員A:記事「スマホ特集」最新のスマホ…
登録会員A:記事「アプリガイド」使えるアプリ…  
有料会員B:記事「 PC 入門」PC 初心者…
有料会員B:記事「スマホ特集」最新のスマホ…
有料会員B:記事「アプリガイド」使えるアプリ…

図1 メソッド main の実行結果

〔プログラム1〕

import java.util.Map.;
import java.util.Set;
import java.util.TreeMap;

class Article { private static final Map<String, Article> ARTICLES = new TreeMap<String, Article>(); private final String id, headline, body; private final boolean free; private Article(String id, String headline, String body, boolean free) { this.id = id; this.headline = headline; this.body = body; this.free = free; } static Article create(String id, String headline, String body, boolean free) { Article article = new Article(id, headline, body, free); ARTICLES.put(id, article); return article; } static Article getArticle(String id) { return ARTICLES.get(id); } static Set<String> getIds() { return ARTICLES.keySet(); } String getId() { return id; } String getHeadline() { return headline; } String getBody() { return body; } boolean isFree() { return free; } }

〔プログラム2〕

abstract class User {
   private final String name;

   User(String name) {
      this.name = name;
   }

   String getName() {
      return name;
   }

   abstract boolean testAndMark(Article article);
}
〔プログラム3〕
class Guest extends User {
   Guest() {
      super("ゲスト");
   }

   boolean testAndMark(Article article) {
      return ;
   }
}
〔プログラム4〕
import java.util.TimeZone;

class Member extends User {
   private static final long MILLIS_PER_DAY = 24 * 6Ø * 6Ø * 1ØØØL;
   private Article browsedArticle;            // 閲覧済みの有料記事
   private long browseDate = Long.MIN_VALUE;  // 記事を閲覧した日付

   Member(String name) {
      ;

   }

   boolean testAndMark(Article article) {
      if (article.isFree()) {
         return true;
      }
      long today = today();
      if (browseDate  today) {
         return browsedArticle == article;
      }
      // 閲覧済みの有料記事と日付を記録
      browsedArticle = article;
      browseDate = today;
      return true;
   }

   private long today() {
      long time = System.currentTimeMillis(); // 現時刻(協定世界時)
      TimeZone tz = TimeZone.getDefault();
      time += tz.getOffset(time);             // ローカル時間に変換
      return time / MILLIS_PER_DAY;
   }
}
〔プログラム5〕
class PaidMember extends Member {
   PaidMember(String name) {
      ;
   }

   boolean testAndMark(Article article) {
      return ;
  }
}
〔プログラム6〕
public class SubscriptionSite {
   public static void main(String[] args) {
      User[] readers = {
         new Guest(),
         new Member("登録会員A"),
         new PaidMember("有料会員B")
      };
      Article.create("ØØØ1", "PC入門", "PC初心者…", true);
      Article.create("ØØØ2", "スマホ特集", "最新のスマホ…", false);
      Article,create("ØØØ3", "アプリガイド", "使えるアプリ …", true);
      for (  ) {
         for (  ) {
            Article article = Article.getArticle(id);
            String body;
            if (reader.testAndMark(article)) {
               body = article.getBody();
            } else {
               body = "<閲覧不可>";
            }
            System.out.printf("%s: 記事「$s」%s%n",
               reader.getName(), article.getHeadline(), body);
         }
      }
   }
}
設問1 プログラム中の に入れる正しい答えを, 解答群の中から選べ。

a,d に関する解答群

ア !article.isFree()       イ article.isFree()

ウ false             エ this.article != article

オ this.article == article    カ this.article == null

キ true

b に関する解答群

ア new User(name)       イ super()       ウ super(name)

エ super.name = name     オ this()        カ this(name)

キ this.name = name      ク User(name)

c に関する解答群 ア !=      イ <      ウ ==      エ >      オ instanceof e,f に関する解答群 ア int i = Ø; i < Article.getIds().size(); i++

イ int i = Ø; i < readers.length; i++

ウ Member reader : readers

エ PaidMember reader : readers

オ String id : Article.articles

カ String id : Article.getIds()

キ User reader : readers

解答 a ←クリックすると正解が表示されます

解答 b ←クリックすると正解が表示されます

解答 c ←クリックすると正解が表示されます

解答 d ←クリックすると正解が表示されます

解答 e ←クリックすると正解が表示されます

解答 f ←クリックすると正解が表示されます

基本情報技術者試験


設問2 プログラム6で記事識別子 "ØØØ3" の記事の無料記事を表すフラグの値を false にしてプログラムを実行したとき,“<閲覧不可>”は何回出力されるか, 正しい答えを,解答群の中から選べ。ここで,プログラム中の には正しい答えが 入っているものとし,プログラムは日をまたいで実行しないものとする。

解答群

ア 0回       イ 1回       ウ 2回

エ 3回       オ 4回       カ 5回

解答 ←クリックすると正解が表示されます

[←前の問題] [次の問題→] [問題一覧表] [分野別] [基本情報技術者試験TOP ]