特に初学者の場合ですが、interfeaceの使用方法をうまく理解できなかった方は少なからずいるのではないでしょうか。
今回は、interfaceの使用方法の中でもswitch文の条件分岐をする方法を紹介します。
この記事は、
上記の本を参考に作成しました。
コードを綺麗に書きたい、そう考えている方には非常におすすめの本です。
interface(インターフェース)とは?
まずは、そもそもinterfaceとは、
「境界面」、「接点」です。中継役みたいなイメージです。
日常生活の具体例としては、充電ケーブルを考えると理解しやすいかと思います。
充電ケーブルは、特定の機械と電気をつなぐ中継役ですよね。なので、充電ケーブルもインターフェースです。
もう少し深堀すると、充電ケーブルの中にも、
Type-CケーブルやLightningケーブルなど複数あります。
これらのケーブルで充電が可能な機器には、
そのケーブルで充電できるようにするための機能が備わっています。
それぞれの機器には、特定のケーブルで充電できるための機能が実装されているのです。
MacbookにはType-C充電の機能、iPhoneにはLightning充電機能など。
アプリ開発におけるインターフェースも同様のイメージとして考えてください。
ケーブルの例で例えるなら、Type-C充電機能がinterfaceで、Macbookが実装されたクラスに該当します。
特定の機能を開発したいが、共通の基盤が欲しい、
そういったときにinterfaceを使用し、それを実装させることで、基盤を保ちつつ、
機能を実装することが可能になります。
switch文とは?
同じような複数の条件分岐が必要な際に使用されるコードです。
if文が複数行にわたってしまい、
if (hoge == 1) {
...
} else if (hoge == 2) {
...
} else if (hoge == 3) {
...
} else if (hoge == 4) {
...
} ...
...
} else {
...
}
のようになった場合に可読性を上げるために使用されます。
実際に上記のコードを書き換えると、
switch (hoge) {
case 1 :
...
break;
case 2 :
...
break;
case 3 :
...
break;
case 4 :
...
break;
...
default :
...
break;
}
上記のようになります。
眼前こちらのほうが可読性がいいです。
ただし、breakを必ず入れてください。
breakがないと、処理が中断されず、
他の条件のところの処理も行ってしまいます。
(意図的に他の条件の処理も行わせるfall through(フォールスルー)という技もあるようですが、
個人的にはあまり好きではないです)
switch文のinterface化
サンプルコードと詳細説明
以下で紹介していくサンプルコードは、GitHubにも上げています。
見にくい場合は、そちらをご使用ください。
サンプルコードの詳細な説明はコード内のコメントや、次の章で説明しています。
また、今回大切なファイルは、以下の構成に線を引いておきますので、
そこを中心にご覧下さい。
また、以下には設定情報とメインのコード部分とで段落分けしてます。
設定情報を飛ばしたい方は、メインコードよりご覧ください。
構成
- /
- src/main/
- java/com/example/demo/
- common/icommon/
- IAction.java
- controller/animal/
- AnimalController.java
- InterfaceAnimalController.java
- entity/
- AnimalKindsEntity.java
- AnimalNameEntity.java
- AnimalNamePrimaryKey.java
- form/
- AnimalForm.java
- repository/
- AnimalKindsRepository.java
- AnimalNameRepository.java
- service/
- animal/
- AnimalService.java
- animalinterface/
- ianimal/
- IAnimal.java
- kinds/
- Cat.java
- Dog.java
- Monkey.java
- Animal.java
- AnimalClearService.java
- AnimalCommonService.java
- AnimalDisplayService.java
- ianimal/
- animal/
- InterfaceSampleApplication.java
- common/icommon/
- resources/
- template/
- animal.html
- application.properties
- data.sql
- messages.properties
- schema.sql
- template/
- java/com/example/demo/
- build.gradle
- settings.gradle
- …
- src/main/
設定情報など
build.gradle
plugins {
id 'java'
id 'org.springframework.boot' version '3.4.4'
id 'io.spring.dependency-management' version '1.1.7'
}
group = 'com.example'
version = '0.0.1-SNAPSHOT'
java {
toolchain {
languageVersion = JavaLanguageVersion.of(21)
}
}
configurations {
compileOnly {
extendsFrom annotationProcessor
}
}
repositories {
mavenCentral()
}
dependencies {
// Spring Data JPA使用
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'org.springframework.boot:spring-boot-starter-web'
// Thymeleaf使用
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
implementation 'org.springframework.boot:spring-boot-starter-validation'
compileOnly 'org.projectlombok:lombok'
developmentOnly 'org.springframework.boot:spring-boot-devtools'
// h2使用
runtimeOnly 'com.h2database:h2'
annotationProcessor 'org.projectlombok:lombok'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
testImplementation 'org.junit.jupiter:junit-jupiter:5.5.2'
}
tasks.named('test') {
useJUnitPlatform()
}
application.properties
spring.application.name=InterfaceSample
# h2使用
spring.datasource.url=jdbc:h2:mem:testdb
spring.datasource.driver-class-name=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=
# DB初期化
spring.sql.init.mode=always
# jpaのテーブル作成を無効
spring.jpa.defer-datasource-initialization=true
spring.jpa.hibernate.ddl-auto=none
schema.sql
CREATE TABLE animal_kinds (
id INT PRIMARY KEY,
name VARCHAR(50),
feature VARCHAR(50)
);
CREATE TABLE animal_name (
id INT,
kinds_id INT,
name VARCHAR(50),
PRIMARY KEY (id, kinds_id)
);
data.sql
INSERT INTO animal_kinds (id,name,feature) VALUES (1,'ねこ','自由');
INSERT INTO animal_kinds (id,name,feature) VALUES (2,'いぬ','人懐っこい');
INSERT INTO animal_kinds (id,name,feature) VALUES (3,'さる','頭よい');
INSERT INTO animal_name (id,kinds_id, name) VALUES (1,1,'たま');
INSERT INTO animal_name (id,kinds_id, name) VALUES (2,1,'たたま');
INSERT INTO animal_name (id,kinds_id, name) VALUES (3,2,'ぽち');
INSERT INTO animal_name (id,kinds_id, name) VALUES (4,2,'ぽぽち');
INSERT INTO animal_name (id,kinds_id, name) VALUES (5,3,'ジョージ');
INSERT INTO animal_name (id,kinds_id, name) VALUES (6,3,'ジジョージ');
メインコード
挙動を理解しやすくするため、
まずは画面の動きを載せます。
必要ない方は、こちらをクリックし、コード部分からご覧ください。
画面遷移
画面に表示されている動物を選択し、表示ボタンを押すと、
その動物につけている名前(あだ名)を画面に表型式で表示するというシンプルなアプリです。
起動し、http://localhost:8080/animal/index (or http://localhost:8080/animal/interface/index)へアクセス。

いずれかの動物を選択し、表示ボタン押下

画面クリアボタン押下

初期表示ボタン押下

このような画面繊維となります。
使用HTMLファイル↓
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title th:text="動物"></title>
</head>
<style>
body {
font-family: sans-serif;
background-color: #f7f7f7;
padding: 20px;
}
.input-container {
background: #fff;
padding: 20px;
border-radius: 8px;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
max-width: 600px;
margin: auto;
}
h1 {
text-align: center;
color: #333;
margin-bottom: 20px;
}
.animal_radio_wrap {
margin-bottom: 20px;
display: flex;
gap: 10px;
user-select: none;
}
.animal_radio_wrap input,
.animal_radio_wrap label {
cursor: pointer;
}
button {
margin-right: 10px;
padding: 8px 16px;
background-color: #4CAF50;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
transition: background-color 0.3s ease;
}
button:hover {
background-color: #45a049;
}
.error-message {
color: #d8000c;
background-color: #ffdddd;
border: 1px solid #d8000c;
padding: 10px;
border-radius: 4px;
margin-bottom: 20px;
}
table {
width: 100%;
border-collapse: collapse;
margin-top: 20px;
}
th,
td {
border: 1px solid #ddd;
padding: 8px;
text-align: left;
}
th {
background-color: #f2f2f2;
}
tr:hover {
background-color: #f9f9f9;
}
</style>
<body>
<div class="input-container">
<form method="post" th:action="@{${action}}" th:object="${form}">
<h1 th:text="${test}"></h1>
<!-- 全体エラーメッセージの表示 -->
<div th:if="${#fields.hasErrors()}" style="color: red;">
<th:block th:each="error : ${#fields.errors()}">
<p th:text="${error}"></p>
</th:block>
</div>
<div class="animal_radio_wrap">
<th:block th:each="animal_radio : ${animals}">
<input type="radio" th:field="*{animal}" th:value="${animal_radio.key}" th:id="${'animal__' + animal_radio.key}" />
<label th:for="${'animal__' + animal_radio.key}" th:text="${animal_radio.value}"></label>
</th:block>
</div>
<button type="submit" name="action" th:value="${display}">表示</button>
<button type="submit" name="action" th:value="${clear}">画面クリア</button>
<button type="submit" name="action">初期表示</button>
<div th:if="*{kinds_data != null}">
<table>
<thead>
<tr>
<th>種類</th>
<th>特徴</th>
</tr>
</thead>
<tbody>
<tr th:each="kind_data : *{kinds_data}">
<td th:text="${kind_data.name}"></td>
<td th:text="${kind_data.feature}"></td>
</tr>
</tbody>
</table>
</div>
<div th:if="*{not #lists.isEmpty(name_data)}">
<table>
<thead>
<tr>
<th>名前</th>
</tr>
</thead>
<tbody>
<tr th:each="data : *{name_data}">
<td th:text="${data.name}"></td>
</tr>
</tbody>
</table>
</div>
</form>
</div>
</body>
</html>
コード
switch文を使用した場合とinterfaceを使用した場合の2種類を載せます。
RepositoryやEntityなどは、今回あまり関係ないため、載せていません。
これらも気になる方は、GitHubのコードよりご覧ください。
switch文使用
別ページに載せてます↓
interface使用
別ページに載せてます↓
参考書
参考サイト