こんにちは。ECF Tech
ブログ担当 Michiharu.Tです。
Javaプログラミング向け練習問題、オブジェクト指向プログラミング編。今回は抽象化・多態性がテーマです。多態性そのものを問題にする内容ではありませんが、動作確認のMainクラスでは、多態性を活かしたプログラムになっています。ぜひ普段の学習にお役立てください。
一般的なJavaの学習順序に沿ったテーマの一覧(※随時追加)は、こちらのリンクよりご確認頂けます。

Javaのトピックスです。主に初心者向けにプログラミング学習ネタを提供していきます。
問題編
Q001
問題
下の仕様に基づいて、各クラスを作成してください。
(仕様)
ゲームに登場するアイテムを表すItemクラスを抽象クラスとして作成します。
次のフィールド、コンストラクタ、メソッドを作成し、Item.javaとして保存します。
- フィールドの作成
- 名前を表すnameをString型で宣言します。
- 修正値を表すvalueをint型で宣言します。
- コンストラクタの作成
- 引数:
- name:String型
- value:int型
- 処理内容:引数で与えられた値を、同名のフィールドに代入します。
- 引数:
- useメソッドの作成(抽象メソッド)
- 概要:アイテムを使った場合の処理を記述します。
- 引数:なし
- 戻り値:なし
武器を表すBukiクラスを、Itemクラスを継承して作成します。
次のフィールド、コンストラクタ、メソッドを追加し、Buki.javaとして保存します。
- コンストラクタの作成
- 引数:
- name:String型
- value:int型
- 処理内容:
- 渡された2つの引数を用いて、スーパークラスのコンストラクタを呼び出します。
- 引数:
- useメソッドの実装
useメソッドをオーバーライドし、次のように処理をします。- 処理内容:
- 「xxxxでこうげき!!」と表示します。(xxxxはフィールドnameの値が入ります)
- 「敵にyyのダメージ!」と表示します。(yyはフィールドvalueの値が入ります)
- 処理内容:
防具を表すArmorクラスを、Itemクラスを継承して作成します。
次のフィールド、コンストラクタ、メソッドを追加し、Armor.javaとして保存します。
- コンストラクタの作成
- 引数:
- name:String型
- value:int型
- 処理内容:
- 渡された2つの引数を用いて、スーパークラスのコンストラクタを呼び出します。
- 引数:
- useメソッドの実装
useメソッドをオーバーライドし、次のように処理をします。- 処理内容:
- 「xxxxを身に着けた」と表示します。(xxxxはフィールドnameの値が入ります)
- 「守備力がyy上がった」と表示します。(yyはフィールドvalueの値が入ります)
- 処理内容:
提供コード
下記のMain.javaを作成した他のソースファイルと同じフォルダ内に保存して動作確認し、実行結果が得られることを確認してください。
public class Main {
public static void main(String[] args) {
Item[] items = {
new Buki("鉄の剣",20),
new Armor("皮の服",10)
};
for (Item item : items) {
item.use();
}
}
}
実行結果
鉄の剣でこうげき!!
敵に20のダメージ!
皮の服を身に着けた
守備力が10上がった
Q002
問題
下の仕様に基づいて、各クラス・インタフェースを作成してください。
(仕様)
「転送可能」という特徴を表すTransferableインタフェースを作成します。
次の抽象メソッドを作成し、Transferable.javaとして保存します。
- transferメソッドの作成(抽象メソッド)
- 概要:データの転送処理を行ないます
- 引数:なし
- 戻り値:なし
スイッチ(通信機器)を表すSwitchクラスを、Transferableインタフェースを実装して作成します。
次のフィールド、コンストラクタ、メソッドを追加し、Buki.javaとして保存します。
- transferメソッドの実装
- 処理内容:
- 「MACアドレスを使ってデータを転送します」と表示します。
- 処理内容:
ルータ(通信機器)を表すRouterクラスを、Transferableインタフェースを実装して作成します。
次のフィールド、コンストラクタ、メソッドを追加し、Buki.javaとして保存します。
- transferメソッドの実装
- 処理内容:
- 「IPアドレスを使ってデータを転送します」と表示します。
- 処理内容:
提供コード
下記のMain.javaを作成した他のソースファイルと同じフォルダ内に保存して動作確認し、実行結果が得られることを確認してください。
public class Main {
public static void main(String[] args) {
Transferable[] parts = {
new Switch(),
new Router()
};
for (Transferable work : parts) {
work.transfer();
}
}
}
実行結果
MACアドレスを使ってデータを転送します
IPアドレスを使ってデータを転送します
Q003
問題
下の仕様に基づいて、各クラス・インタフェースを作成してください。
(仕様)
お店のクーポン券を表すCouponインタフェースを作成します。
次の抽象メソッドを作成し、Coupon.javaとして保存します。
- discountメソッドの作成(抽象メソッド)
- 概要:引数で受け取った金額から一定の値下げを行ない、値下げの値を返します。
- 引数:amount:int型
- 戻り値:int型
割引クーポンを表すPercentageCouponクラスを、Couponインタフェースを実装して作成します。
次のフィールド、コンストラクタ、メソッドを追加し、PercentageCoupon.javaとして保存します。
- フィールドの作成
- 割引率を表すrateをdouble型で定義します。
- コンストラクタの作成
- 引数:
- rate:double型
- 処理内容:引数で与えられた値を、同名のフィールドに代入します。
- 引数:
- discountメソッドの実装
- 処理内容:
- 引数amountの値にフィールドrateの値をかけ算した結果を返します。(小数点以下は切り捨てます。)
- 処理内容:
定額クーポンを表すVolumeCouponクラスを、Couponインタフェースを実装して作成します。
次のフィールド、コンストラクタ、メソッドを追加し、VolumeCoupon.javaとして保存します。
- フィールドの作成
- 割引額を表すvolumeをint型で定義します。
- コンストラクタの作成
- 引数:
- volume:int型
- 処理内容:引数で与えられた値を、同名のフィールドに代入します。
- 引数:
- discountメソッドの実装
- 処理内容:
- 引数amountの値からフィールドvolumeの値を引き算した結果を返します。
- 処理内容:
レジを表すCasherクラスを作成します。
次のクラスメソッドを作成し、Casher.javaとして保存します。
- paymentメソッド(クラスメソッド)の作成
- 概要:金額とクーポンの情報から、合計額を計算します
- 引数:
- amount:int型
- coupon:Coupon型
- 戻り値:int型
- 処理内容:amountの値を引数として、couponのdiscountメソッドを呼び出します。discountメソッドの戻り値をそのまま返します。
提供コード
下記のMain.javaの①~④の記述に基づき、プログラムを追記します。他のソースファイルと同じフォルダ内に保存して動作確認し、実行結果が得られることを確認してください。
public class Main {
public static void main(String[] args) {
PercentageCoupon coupon1 = new PercentageCoupon(0.3);
VolumeCoupon coupon2 = new VolumeCoupon(1000);
System.out.println(Casher.payment(5000, coupon1));
System.out.println(Casher.payment(5000, coupon2));
//①変数coupon3を宣言します。5割引のクーポンを生成し代入します。
//②変数coupon4を宣言します。1500円引のクーポンを生成し代入します。
//③Casherのpaymentメソッドを呼び出し、5000円に対してcoupon3を適用した結果を表示します。
//④Casherのpaymentメソッドを呼び出し、5000円に対してcoupon4を適用した結果を表示します。
}
}
実行結果
1500
4000
2500
3500
Q004
問題
下の仕様に基づいて、各クラスを作成してください。
(仕様)
クイズを表すQuizクラスを作成します。
次のフィールド、コンストラクタ、メソッドを追加し、Quiz.javaとして保存します。
- フィールドの作成
- 問題文を表すmainをString型で定義します。
- コンストラクタの作成
- 引数:
- main:String型
- 処理内容:引数で与えられた値を、同名のフィールドに代入します。
- 引数:
- displayHeaderメソッドの作成
- 概要:問題の冒頭文を表示します。
- 引数:なし
- 戻り値:なし
- 処理内容:「次の問いに答えなさい」と表示します。(※「」も表示内容です)
- displayMainメソッドの作成
- 概要:問題の本文を表示します。
- 引数:なし
- 戻り値:なし
- 処理内容:フィールドmainの内容を表示します。
選択肢つきクイズを表すMultipleChoiceQuizクラスを、Quizクラスを継承して作成します。
次のフィールド、コンストラクタ、メソッドを追加し、MultipleChoiceQuiz.javaとして保存します。
- フィールドの作成
- 選択肢を表すanswersをString型の配列で定義します。
- コンストラクタの作成
- 引数:
- main:String型
- answers:String型配列
- 処理内容:
- 引数mainの値を用いて、スーパークラスのコンストラクタを呼び出します。
- 引数answersは、フィールドanswersにそのまま代入します。
- 引数:
- displayHeaderメソッドの作成
- 概要:問題の冒頭文を表示します。
- 引数:なし
- 戻り値:なし
- 処理内容:「次の問いについて、正しいものを4つの中から選びなさい」と表示します。(※「」も表示内容です)
- displayMainメソッドの作成
- 概要:問題の本文を表示します。
- 引数:なし
- 戻り値:なし
- 処理内容:
- フィールドmainの内容を表示します。
- フィールドanswersの各要素を、「x:yyyyyy」の形式で表示します。
xは1から始まる連続番号
yyyyyyはanswersの各要素です。
穴埋めクイズを表すBlankQuizクラスを、Quizクラスを継承して作成します。
次のフィールド、コンストラクタ、メソッドを追加し、BlankQuiz.javaとして保存します。
- フィールドの作成
- 空欄の数を表すblankCountをint型で定義します。
- コンストラクタの作成
- 引数:
- main:String型
- blankCount:int型
- 処理内容:
- 引数mainの値を用いて、スーパークラスのコンストラクタを呼び出します。
- 引数blankCountは、フィールドblankCountにそのまま代入します。
- 引数:
- displayHeaderメソッドの作成
- 概要:問題の冒頭文を表示します。
- 引数:なし
- 戻り値:なし
- 処理内容:「次の文の空欄を埋めなさい。」と表示します。(※「」も表示内容です)
- displayMainメソッドの作成
- 概要:問題の本文を表示します。
- 引数:なし
- 戻り値:なし
- 処理内容:
- フィールドmainの内容を表示します。
- フィールドblankCountの数だけ、「x:. __」と表示します。
xは1から始まる連続番号
クイズを表示するためのQuizViewerクラスを作成します。
次のクラスメソッドを作成し、QuizViewer.javaとして保存します。
- クラスフィールドの作成
- 問題番号を表すcountをint型で定義します。
- showQuizメソッドの作成(クラスメソッド)
- 概要:問題を表示します。
- 引数:quiz:Quiz型
- 戻り値:なし
- 処理内容:
- フィールドcountを1加算します。
- 「<第x問>」と表示します。(xはフィールドcountの値が入ります。)
- 引数quizのdisplayHeaderメソッドを呼び出します。
- 引数quizのdisplayMainメソッドを呼び出します。
- 改行します。
提供コード
下記のMain.javaを作成した他のソースファイルと同じフォルダ内に保存して動作確認し、実行結果が得られることを確認してください。
public class Main {
public static void main(String[] args) {
Quiz q1 = new Quiz("最も面積の広い都道府県はどこですか?");
String[] answers = {"青りんご","さくらんぼ","みかん","ぶどう"};
Quiz q2 = new MultipleChoiceQuiz("赤色の果物はどれですか", answers);
Quiz q3 = new BlankQuiz("( )は( )年に鎌倉幕府を設立した。", 2);
QuizViewer.showQuiz(q1);
QuizViewer.showQuiz(q2);
QuizViewer.showQuiz(q3);
}
}
実行結果
<第1問>
「次の問いに答えなさい」
最も面積の広い都道府県はどこですか?
<第2問>
「次の問いについて、正しいものを4つの中から選びなさい」
赤色の果物はどれですか
1:青りんご
2:さくらんぼ
3:みかん
4:ぶどう
<第3問>
「次の文の空欄を埋めなさい。」
( )は( )年に鎌倉幕府を設立した。
1. ______________
2. ______________
解答編
それでは、解答編です。
Q001
(Item.java)
public abstract class Item {
String name;
int value;
Item(String name, int value) {
this.name = name;
this.value = value;
}
public abstract void use();
}
(Buki.java)
public class Buki extends Item{
Buki(String name, int value) {
super(name, value);
}
public void use() {
System.out.println(this.name + "でこうげき!!");
System.out.println("敵に" + this.value + "のダメージ!");
}
}
(Armor.java)
public class Armor extends Item {
Armor( String name, int value) {
super(name,value);
}
public void use() {
System.out.println(this.name + "を身に着けた");
System.out.println("守備力が" + this.value + "上がった");
}
}
Q002
(Transferable.java)
public interface Transferable {
public void transfer();
}
(Switch.java)
public class Switch implements Transferable {
public void transfer() {
System.out.println("MACアドレスを使ってデータを転送します");
}
}
(Router.java)
public class Router implements Transferable{
public void transfer() {
System.out.println("IPアドレスを使ってデータを転送します");
}
}
Q003
(Coupon.java)
public interface Coupon {
public int discount(int amount);
}
(PercentageCoupon.java)
public class PercentageCoupon implements Coupon {
double rate;
public PercentageCoupon(double rate) {
this.rate = rate;
}
public int discount(int amount) {
return (int)(amount * rate);
}
}
(VolumeCoupon.java)
public class VolumeCoupon implements Coupon{
int volume;
public VolumeCoupon(int volume) {
this.volume = volume;
}
public int discount(int amount) {
return amount - volume;
}
}
(Casher.java)
public class Casher {
public static int payment(int amount, Coupon coupon) {
int ret = coupon.discount(amount);
return ret;
}
}
Q004
(Quiz.java)
public class Quiz {
private String main;
public Quiz(String main) {
this.main = main;
}
public void displayHeader() {
System.out.println("「次の問いに答えなさい」");
}
public void displayMain() {
System.out.println(main);
}
}
(MultipleChoiceQuiz.java)
public class MultipleChoiceQuiz extends Quiz{
String[] answers;
public MultipleChoiceQuiz(String main, String[] answers) {
super(main);
this.answers = answers;
}
public void displayHeader() {
System.out.println("「次の問いについて、正しいものを4つの中から選びなさい」");
}
public void displayMain() {
super.displayMain();
for (int i = 0; i < answers.length; i++) {
System.out.println( (i+1) + ":" + answers[i] );
}
}
}
(BlankQuiz.java)
public class BlankQuiz extends Quiz {
int blankCount;
public BlankQuiz(String main, int blankCount) {
super(main);
this.blankCount = blankCount;
}
public void displayHeader() {
System.out.println("「次の文の空欄を埋めなさい。」");
}
public void displayMain() {
super.displayMain();
for (int i = 0; i < blankCount; i++) {
System.out.println( (i+1) + ". ______________" );
}
}
}
(QuizViewer.java)
public class QuizViewer {
public static int count;
public static void showQuiz(Quiz quiz) {
count++;
System.out.println("<第" + count + "問>");
quiz.displayHeader();
quiz.displayMain();
System.out.println();
}
}
おわりに
本日は以上となります。最後までご覧くださりありがとうございます。初学者の方が多態性の動作イメージをつかむ一助になれば幸いです。ひきつづき、問題の提供をしていければと思っています。今後もよろしくお願いいたします。
合同会社イー・シー・エフでは、子ども向けプログラミングなどの教育講座を実施しています。プログラミング教室の案内や教育教材の情報、また関連するご相談・問い合わせにつきましては下記よりご確認ください。
