20200906のJavaに関する記事は5件です。

【Java】二つ以上の引数をsuperに渡す場合の書き方

superって何?

これがそもそもわかっていないと何のこっちゃという感じです。

どうやらイメージ的にはメソッドですかね。

正しいのかどうかはわかりませんが、調べても〜ときに使われますとかそういう説明しか見当たらなかったです。

メソッドだと思えば、引数の書き方がイメージしやすい。

superを使いと何がどうなるのかわからないので、こんな風に書いてエラーになります

public class Oya {
  private String name;
  private int score;

// コンストラクタ
  public Oya(String name, int score) {
    this.name = name;
    this.score = score;
  }

  // 子クラスから変数の値を読み込めるようにするgetter
  public String getName() {
    return this.name;
  }

  // 子クラスから変数の値を読み込めるようにするgetter
  public int getScore() {
    return this.score;
  }
}

public class Ko extends Oya {
  // 子クラスのコンストラクタ
  public Ko() {
    // super(name); // ←ダメ
    // super(score); // ←ダメ
    super(name, score); // メソッドに引数を渡す時の要領で書く
  }

  public void sayHello() {
    // nameはOyaクラスでprivateになっているのでthis.nameなどではアクセスできない
   // Oyaクラスでgetterを書いとけば、メソッドを利用してnameの値を返してくれる
    System.out.println("hello! " + this.getName());  // ←最後のところでOyaクラスのgetNameメソッドを呼び出してnameの値を受け取る
  }
}

public static void main(String[] args) {
  Ko bob = new Ko("bob", 10);
  Ko.sayHello();
}

これでうまくいきました。
super(name, score)という書き方をすればコンパイルエラーがなくなり、ちゃんとコンストラクタが動いたもよう。

super(引数1、引数2)という風に二つ以上の引数を渡す

単にこの書き方が思いつかなかったのと、superの使用例が引数が一つのものしか出てこなかったので、メモとして残しておきます。

自分はsuper(引数)という書き方で一つずつ変数をOyaクラスのコンストラクタに渡すものだと勘違いしていました。

素人記事ですので、間違いがあればご指摘ください。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

今使っているElasticsearchのバージョンはJava11に対応しているのか?

というお話です。
いや、JDK11(OpenJDK)のリリースが2018年9月と2年も前やし、当たり前やろーっ!と思う人もいるかもしれませんが、、
製品によってはそうでない可能性もある(実際、AWSのElastic BeantalkがJava11に完全対応(GA)したのが2020年4月 - この記事を執筆した2020年9月時点の約5ヶ月前とわりと最近だった)ので、念のため調べてみました。

事の発端

事の発端となったのが公式サイトの以下のページ

The Java High Level REST Client requires Java 1.8 and depends on the Elasticsearch core project. ・・・

なぬ? Java1.8だと・・・?
今動かしている環境がJava11だったので、正直焦りました。
このページをさらに読み進めると、

The 6.0 client is able to communicate with any 6.x Elasticsearch node, while the 6.1 client is for sure able to communicate with 6.1, 6.2 and any later 6.x version, ・・・

とあり、バージョン6.0~6.2付近の時点のものであることが読み取れました。
現状使っているElasticsearchのバージョンは7.4.2(AWSのElasticsearch Serviceの使用開始時の最新バージョン:2020/07/23~は7.7に対応)なので、Java11対応しているかも?というわけでいざ、調査。

調査

まずたどりついたのが以下の記事。

現状、テスト中、的な。
2018年9月時点の内容ですからねぇ、さすがに大丈夫やろ、と思いたいところではありますが。

確証とれるまでは続けます。

さらに、調査を進めると、

より、2018年11月バージョン6.5.0よりJava11サポートとなっていることが確認できました。
(しかもありがたいことに日本語。)
けっこう早い段階で対応していたんですね。すごい!

「Oracleから」とあるのが若干気になりましたが、、使用しているElasticsearchの現バージョン(7.4.2)がJava11に対応していることは間違いない、とのことで一件落着~!

結論

Elasticsearch 6.5.0以降であればJava11に対応している、というのが結論です。
それ以前のバージョンをお使いの方でJava11環境使っている方、あるいは移行を考えている方は6.5.0以上へのアップグレードを検討したほうがよさそうですね。

参考

本文中では記載してませんが、参考にしたページたちです。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Spring Bootを試す1(環境構築 ~ Tomcat起動)

はじめに

Spring Bootでサンプルプログラムを書きたいと思います。
参考にするのは、Spring徹底入門です。
こちらで紹介されている会議室予約システムを作っていきます。

Javaのインストール

Javaをインストールしましょう。
バージョンはいろいろありますが、今回はOpenJDK 8でいきます。
WSL2を利用している方は、以下のコマンドでダウンロードできます。

WSL2
$ sudo apt install openjdk-8-jdk

次に環境変数を設定します。
まずは、どこにJavaがインストールされたか確認しましょう。

WSL2
$ dpkg -L openjdk-8-jdk

*** 略
/usr/lib/jvm/java-8-openjdk-amd64
*** 略

いっぱい出ますが、JAVA_HOMEに指定するのは/usr/lib/jvm/java-8-openjdk-amd64でOKです。
パスが分かったので、環境変数を設定します。

WSL2
$ sudo vi /etc/profile

/etc/profileに以下を追記。
export JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64
export PATH=$PATH:$JAVA_HOME/bin
export CLASSPATH=.:$JAVA_HOME/jre/lib:$JAVA_HOME/lib:$JAVA_HOME/lib/tools.jar

次のコマンドでbashの設定内容を反映し、インストールできていることを確認しましょう。

WSL2
$ source /etc/profile
$ java -version
openjdk version "1.8.0_265"
OpenJDK Runtime Environment (build 1.8.0_265-8u265-b01-0ubuntu2~20.04-b01)
OpenJDK 64-Bit Server VM (build 25.265-b01, mixed mode)

これでJavaが使えるようになりました。

Mavenのインストール

続いてMavenのインストールを行います。
ビルドツールとしてはGradleのほうが人気が出ているらしいですが、大人の事情で古き良きMavenを使います。
コマンドはなんとこれだけ。

WSL2
$ sudo apt install maven

インストールの確認をしましょう。

WSL2
$ mvn -v
Apache Maven 3.6.3
Maven home: /usr/share/maven
Java version: 1.8.0_265, vendor: Private Build, runtime: /usr/lib/jvm/java-8-openjdk-amd64
Default locale: en, platform encoding: UTF-8
OS name: "linux", version: "4.19.104-microsoft-standard", arch: "amd64", family: "unix"

Spring-Bootのサンプルを起動する

では、SpringBootのサンプルプロジェクトを作成しましょう。
はじめに適当なディレクトリを作成します。筆者の場合は次のようにしました。

WSL2
$ cd ~
$ mkdir web-app
$ cd web-app

次のコマンドでサンプルプロジェクトを作成します。

WSL2
$ mvn archetype:generate

*** 中略 ***

Choose a number or apply filter (format: [groupId:]artifactId, case sensitive contains): 1672:

いかがでしょう。たくさん英語が出てきてビビりますが、無視して大丈夫です。
mvn archetype:generateは対話的にプロジェクトを作成するコマンドです。
今回利用するサンプルを選択しましょう。spring-bootと入力してみましょう。

WSL2
Choose a number or apply filter (format: [groupId:]artifactId, case sensitive contains): : spring-boot

さっきよりも選択肢が減りました。(筆者の環境では78個)
今回はorg.springframework.boot:spring-boot-sample-tomcat-archetype (Spring Boot Tomcat Sample)を使ってみましょう。
このサンプルだとTomcatが組み込まれているので、Jarをそのまま実行できます。
筆者の環境では68:と表示されていたので、68と入力。(名前を指定してもできるはず)

WSL2
*** 略
68: remote -> org.springframework.boot:spring-boot-sample-tomcat-archetype (Spring Boot Tomcat Sample)
*** 略
Choose a number or apply filter (format: [groupId:]artifactId, case sensitive contains): : 68

またたくさん英語が出ますが、めげないでください。無視でOKです。
次に以下のことを聞かれます。

WSL2
*** 略
Define value for property 'groupId': com.rocorock
Define value for property 'artifactId': mvn-spring
Define value for property 'version' 1.0-SNAPSHOT: :
Define value for property 'package' com.rocorock: :
Confirm properties configuration:
groupId: com.rocorock
artifactId: mvn-spring
version: 1.0-SNAPSHOT
package: com.rocorock
 Y: : y

MavenではgroupIdartifactIdversionpackageの指定が必要です。
パッケージ名とかで利用されます。本質的にはなんでもOKだと思います。
versionpackageはそのままEnterを押せば、勝手に反映してくれます。
今回Mavenの設定項目の説明は掲載しませんが、Mavenについて知りたい方はこちらの本をお勧めします。
Javaビルドツール入門
コンソールに以下の表示が出たら成功です。

WSL2
[INFO] ----------------------------------------------------------------------------
[INFO] Using following parameters for creating project from Archetype: spring-boot-sample-tomcat-archetype:1.0.2.RELEASE
[INFO] ----------------------------------------------------------------------------
[INFO] Parameter: groupId, Value: com.rocorock
[INFO] Parameter: artifactId, Value: mvn-spring
[INFO] Parameter: version, Value: 1.0-SNAPSHOT
[INFO] Parameter: package, Value: com.rocorock
[INFO] Parameter: packageInPathFormat, Value: com/rocorock
[INFO] Parameter: package, Value: com.rocorock
[INFO] Parameter: version, Value: 1.0-SNAPSHOT
[INFO] Parameter: groupId, Value: com.rocorock
[INFO] Parameter: artifactId, Value: mvn-spring
[INFO] Project created from Archetype in dir: /home/tomoya/web-app/mvn-spring
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  02:26 min
[INFO] Finished at: 2020-09-06T16:51:46+09:00
[INFO] ------------------------------------------------------------------------

できたファイルをパッケージ化してみましょう。

WSL2
$ cd mvn-spring
$ mvn package

*** 略

Results :

Failed tests:
  SampleTomcatApplicationTests.testHome:53 expected:<Hello [World]> but was:<Hello [DESKTOP-F147IF8]>
  NonAutoConfigurationSampleTomcatApplicationTests.testHome:82 expected:<Hello [World]> but was:<Hello [DESKTOP-F147IF8]>

Tests run: 2, Failures: 2, Errors: 0, Skipped: 0

[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  4.461 s
[INFO] Finished at: 2020-09-06T16:52:06+09:00
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-surefire-plugin:2.15:test (default-test) on project mvn-spring: There are test failures.
[ERROR]
[ERROR] Please refer to /home/tomoya/web-app/mvn-spring/target/surefire-reports for the individual test results.
[ERROR] -> [Help 1]
[ERROR]
[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
[ERROR]
[ERROR] For more information about the errors and possible solutions, please read the following articles:
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MojoFailureException

BUILD FAILUREと出ました。コンソールを確認してみましょう。

Failed tests:
  SampleTomcatApplicationTests.testHome:53 expected:<Hello [World]> but was:<Hello [DESKTOP-F147IF8]>
  NonAutoConfigurationSampleTomcatApplicationTests.testHome:82 expected:<Hello [World]> but was:<Hello [DESKTOP-F147IF8]>

どうやらテストに失敗しているようです。expected:<Hello [World]> but was:<Hello [DESKTOP-F147IF8]>となっているので、'Hello World'と返すようにコードを直してあげましょう。(なぜサンプルなのにエラーを吐く…)
まずはテストコードを確認します。

SampleTomcatApplicationTests.java
/*
 * Copyright 2012-2014 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.rocorock.tomcat;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.test.IntegrationTest;
import org.springframework.boot.test.SpringApplicationConfiguration;
import org.springframework.boot.test.TestRestTemplate;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;

import static org.junit.Assert.assertEquals;

/**
 * Basic integration tests for demo application.
 * 
 * @author Dave Syer
 */
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = SampleTomcatApplication.class)
@WebAppConfiguration
@IntegrationTest("server.port:0")
@DirtiesContext
public class SampleTomcatApplicationTests {

    @Value("${local.server.port}")
    private int port;

    @Test
    public void testHome() throws Exception {
        ResponseEntity<String> entity = new TestRestTemplate().getForEntity(
                "http://localhost:" + this.port, String.class);
        assertEquals(HttpStatus.OK, entity.getStatusCode());
        assertEquals("Hello World", entity.getBody());
    }

}

assertEquals("Hello World", entity.getBody())がエラーとなっているテストなので、ここのテストが通るように修正します。

HelloWorldService.java
/*
 * Copyright 2012-2013 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.rocorock.tomcat.service;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

@Component
public class HelloWorldService {

    @Value("${name:World}")
    private String name;

    public String getHelloMessage() {
        return "Hello World"; //修正箇所
    }

}

今回はテストを回避するために"Hello World"とベタ打ちしました。
本質的には解決していませんが、とりあえず動くようにならないと始まらないのでこのまま進めます。
もう一度パッケージ化してみましょう。

WSL2
$ mvn package

*** 略
[INFO] Building jar: /home/tomoya/web-app/mvn-spring/target/mvn-spring-1.0-SNAPSHOT.jar
[INFO]
[INFO] --- spring-boot-maven-plugin:1.0.2.RELEASE:repackage (default) @ mvn-spring ---
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  4.288 s
[INFO] Finished at: 2020-09-06T17:00:47+09:00
[INFO] ------------------------------------------------------------------------

今度は成功しました。成功すると新しくtargetフォルダが作成されます。
ここに実行可能なjarが保存されています。早速動かしてみましょう。

WSL2
$ ls
pom.xml  src  target
$ java -jar target/mvn-spring-1.0-SNAPSHOT.jar

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v1.0.2.RELEASE)

2020-09-06 17:01:19.928  INFO 5988 --- [           main] c.r.tomcat.SampleTomcatApplication       : Starting SampleTomcatApplication on DESKTOP-F147IF8 with PID 5988 (/home/tomoya/web-app/mvn-spring/target/mvn-spring-1.0-SNAPSHOT.jar started by tomoya in /home/tomoya/web-app/mvn-spring)
2020-09-06 17:01:19.951  INFO 5988 --- [           main] ationConfigEmbeddedWebApplicationContext : Refreshing org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@414be896: startup date [Sun Sep 06 17:01:19 JST 2020]; root of context hierarchy

楽しい起動スクリプトが表示されます。Tomcatはデフォルトではポート8080で起動するので、アクセスしてみましょう。
ブラウザでhttp://localhost:8080と入力してください。Hello Worldと表示されたら成功です。
コンソール上でCtrl + Cを押してTomcatを止めれば、デモ終了です。

終わりに

会議室予約アプリを作成するといいながら、Tomcatのサンプルを動かして終わりました…
次回以降このサンプルを拡張して開発したいと思います!(挫折したら記事にならないかも)

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Spring バリデーションエラーを@ControllerAdviceで一括ハンドリング

結論

@ControllerAdviceを付与したハンドラクラスを用意すれば、各コントローラのバリデーションエラーのハンドリングを一括で処理できる。

環境

Java 11
SpringBoot 2.3.3

解説

以下、検索パラメータを指定してユーザー一覧を取得するRESTコントローラにて解説する。
リクエストの入力バリデーションを設け、バリデーションエラー検出時には所定のレスポンスボディと併せて400エラーを返すようにする。

※package、import文など省略しています。

コントローラクラス

引数に@Validatedを付与し、バリデーションが実施されるようにする。
エラー時のハンドリングはここでは特にしない。

@RestController
@RequiredArgsConstructor
public class UserController {

    @NonNull
    private final UserService userService;

    @NonNull
    private final GetUsersQueryValidator getUsersQueryValidator;

    @InitBinder
    public void initBinder(WebDataBinder binder) {
        binder.addValidators(getUsersQueryValidator);
    }

    /**
     * 検索条件を指定してユーザー情報を取得
     *
     * @param getUsersQuery 検索条件クエリパラメータ
     * @return 検索されたユーザー情報
     */
    @GetMapping(value = "/users")
    ResponseEntity<List<UserDto>> getUsers(@Validated GetUsersQuery getUsersQuery) {

        SearchUsersCondition searchUsersCondition = new SearchUsersCondition();
        searchUsersCondition.setName(getUsersQuery.getName());
        searchUsersCondition.setLowerLimitAge(getUsersQuery.getLowerLimitAge());
        searchUsersCondition.setUpperLimitAge(getUsersQuery.getUpperLimitAge());

        return ResponseEntity.ok(userService.searchUsers(searchUsersCondition));
    }
}

クエリパラメータクラス

リクエストのクエリパラメータがバインドされるクラス。
各フィールドに@NotBlank@NotNullを付与し、単項バリデーションが実施されるようにしている。

/**
 * ユーザー検索条件を指定するクエリパラメータ
 */
@Data
public class GetUsersQuery {

    /**
     * ユーザー名
     */
    @NotBlank
    private String name;

    /**
     * 下限年齢
     */
    @NotNull
    private Integer lowerLimitAge;

    /**
     * 上限年齢
     */
    @NotNull
    private Integer upperLimitAge;

}

相関バリデータクラス

クエリパラメータの下限年齢が上限年齢を上回っている時にエラーとする。

/**
 * {@link GetUsersQuery}の相関バリデータ
 */
@Component
public class GetUsersQueryValidator implements Validator {

    @Override
    public boolean supports(Class<?> clazz) {
        return GetUsersQuery.class.isAssignableFrom(clazz);
    }

    /**
     * バリデーション実施
     *
     * @param target バリデーション対象
     * @param errors 検出されたエラー
     */
    @Override
    public void validate(Object target, Errors errors) {

        // 上限年齢、下限年齢のいずれかに単項エラーが発生している場合は相関バリデーションは実施しない
        if (errors.hasFieldErrors("lowerLimitAge") || errors.hasFieldErrors("upperLimitAge")) {
            return;
        }

        GetUsersQuery getUsersQuery = GetUsersQuery.class.cast(target);

        int lowerLimitAge = getUsersQuery.getLowerLimitAge();
        int upperLimitAge = getUsersQuery.getUpperLimitAge();

        // 上限年齢が下限年齢を超えていない場合はエラーとする
        if (lowerLimitAge >= upperLimitAge) {
            errors.reject("reverseLimitAge");
        }
    }
}

レスポンスボディ用エラークラス

エラー時はレスポンスボディにこの型のオブジェクトを格納する。

/**
 * リクエストボディにセットするエラー情報
 */
@Data
public class ApiError implements Serializable {

    private static final long serialVersionUID = 1L;

    private String message;
}

例外ハンドラクラス

以下のような、@ControllerAdviceを付与した例外ハンドラクラスを用意する。

/**
 * コントローラで発生した例外のハンドラ
 */
@ControllerAdvice
public class GlobalExceptionHandler extends ResponseEntityExceptionHandler {

    @Autowired
    MessageSource messageSource;

    /**
     * {@link BindException}をハンドリング
     *
     * @param bindException {@link BindException}
     * @param httpHeaders   {@link HttpHeaders}
     * @param httpStatus    {@link HttpStatus}
     * @param webRequest    {@link WebRequest}
     * @return クライアントへのレスポンス
     */
    @Override
    protected ResponseEntity<Object> handleBindException(
            BindException bindException,
            HttpHeaders httpHeaders,
            HttpStatus httpStatus,
            WebRequest webRequest
    ) {
        // レスポンスボディに格納するエラーリスト
        List<ApiError> apiErrorList = new ArrayList<>();

        List<ObjectError> objectErrorList = bindException.getAllErrors();

        for (ObjectError objectError : objectErrorList) {

            // エラーコードからメッセージ取得
            String message = messageSource.getMessage(objectError, webRequest.getLocale());

            // レスポンスボディ用エラーオブジェクトを作成しリストに格納
            ApiError apiError = new ApiError();
            apiError.setMessage(message);
            apiErrorList.add(apiError);
        }

        return new ResponseEntity<>(apiErrorList, httpHeaders, httpStatus);
    }
}

バリデーションエラー発生時はコントローラからエラー情報が格納されたBindExceptionが投げられる。
@ControllerAdviceを付与したクラスには、各コントローラ共通に適用したい処理を実装する。ResponseEntityExceptionHandlerを継承し、handleBindExceptionメソッドをオーバーライドすることで、バリデーションエラー時のレスポンスを自由にカスタムすることができる。

ここでは以下のようにカスタムしている。

  • レスポンスボディをApiError型に指定。
  • objectErrorのエラーコードからエラーメッセージに変換。

エラーコードは以下の形式でobjectErrorに格納されている。

単項バリデーション:「アノテーション名+クラス名(キャメルケース)+フィールド名」
相関バリデーション:「相関バリデータでセットしたエラーコード+クラス名(キャメルケース)」

messages.propertiesを以下のように用意すれば、メッセージへ変換される。

messages.properties

NotBlank.getUsersQuery.name=名前の入力は必須です。
NotNull.getUsersQuery.lowerLimitAge=下限年齢の入力は必須です。
NotNull.getUsersQuery.upperLimitAge=上限年齢の入力は必須です。
reverseLimitAge.getUsersQuery=上限年齢は下限年齢より大きい値を指定してください。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

インターフェースと抽象クラスの違い

インターフェースと抽象クラスの違い

抽象クラス

抽象クラスはabstractメソッドを付ける事で強制出来る、メソッドは通常通り作れる
⇒継承させることで、サブクラスのメソッドを強制的に付ける事が出来る。
 つまり、派生したクラスに同一のメソッドを持たせる事と強制的にメソッドを作らせる事で
 強制力を持たせるクラスが作れる

 チームには、Aというクラスの中にはみんなが使う税率メソッドをつかって共通化されているけど
 地域の税金は、地域によってちがうから個々の派生したクラスでメソッドを作ってね。

インターフェース

⇒インターフェースをimplementしたクラスは、インターフェースの箱に入れる事ができるつまり、インターフェースをimplementしておけば、条件によってAとBと切り替えが出来る。

サンプル(インターフェース)

public interface ControlPanelIf {
    void play();
    void pause();
    void stop();
    void forwardFast();
    void backwordFast();
}
これを実装するクラスは以下のコードになります。

実際はもっと複雑になることが多いですが、サンプルということで書いていきましょう。

public class DvdDeck implements ControlPanelIf {
    @Override
    public void play() {
        System.out.println("DVD再生");
    }

    @Override
    public void stop() {
        System.out.println("DVD再生停止");
    }

    @Override
    public void pause() {
        System.out.println("DVD一時停止");
    }

    @Override
    public void forwardFast() {
        System.out.println("DVD早送り");
    }

    @Override
    public void backwardFast() {
        System.out.println("DVD早戻し");
    }
}
このDVDDeckクラスを使うクラスが以下とします。

public class DeckUser {
    public static void main(String[] args) {
        ControlPanelIf myDeck = createDeck(args[0]);

        myDeck.play();
        myDeck.forwardFast();
        myDeck.pause();
        myDeck.play();
        myDeck.backwardFast();
    }

    private static ControlPanelIf createDeck(String deckType) {

        ControlPanelIf deck;
        if(deckType.equals("DVD") {
            deck = new DvdDeck();
        } else if(deckType.equals("BluRay") {
            deck = new BluRayDeck();
        } else if(deckType.equals("HDD") {
            deck = new HddRayDeck();
        } else {
            deck = new DvdDeck();
        }
        return deck;
    }
}

参考資料
https://www.slideshare.net/graminmakeall/java-43178044?qid=6a49c149-fcb0-4aa8-87d0-2e4e2c18362b&v=&b=&from_search=5

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む