blog

"MoreThanJava "4日目:オブジェクト指向の基本

"このJava基礎チュートリアルシリーズは、「新しい仲間が早く、質の高い学習ができる」ことを目指し、様々な知識を組み合わせた上でJavaの基礎を総復習するものです。 もちろん、古い友人も新しい友人も関...

Apr 26, 2020 · 25 min. read
シェア
  • "MoreThanJava "は"Learning, more than CODE "を推進し、この一連のJava基礎チュートリアルは、様々な知識を組み合わせた後、Javaの基本を総復習し、 "新しい友人が迅速かつ高品質で学ぶのを助ける "ことを目的としています。
  • もちろん 、新旧の友人に関係なく、 私はあなたが それから利益を得ることができると信じています。あなたはそれが "良い "と 思う場合は、 "注目+メッセージ+共有 "を歓迎し、記事の最後にリンクへの完全なアクセス権を持って、あなたのサポートは私が前進するための最大の原動力です!

オブジェクト指向設計の概要

オブジェクト指向プログラミング(OOP)は、1900年代の「構造化」または手続き型プログラミング技法に取って代わり、今日支配的なプログラミング・パラダイムです。Javaはオブジェクト指向なので、Javaを使いこなすにはOOPに精通していなければなりません。

抽象化の理解

抽象化とは、複雑なメカニズムをオブジェクトの中に隠し、オブジェクトとの対話に必要な情報だけを残すことです。

この点を説明するために、通常の日に 「リフト」を 使うことを想像してみてください。

オフィスビルにお勤めの方であれば、これが日課になっているかもしれません。上か下のボタンを押して、ドアがスライドして開くのを待ちます。それが終わると、壁の一面にボタンパネルがある「ボックス」に入り、必要なボタンを押します。エレベーターが目的の階に到着したら、他の人の横をすり抜けて外に出ます。

リフトを使うには、正しいボタンの押し方を知っていればいいのです。

そしてリフトの背後には、プーリー・システム、機械、配線、ショックアブソーバー、安全システムなど、リフトを支える様々なものが隠れています。 心配する必要はありません...

エレベーターは、対応するボタンパネルを備えた「鉄の箱」で、「交通システム」全体をうまく抽象化したもの。

オブジェクトとは

簡単に言えば、オブジェクトは現実世界を抽象化したものです。

オブジェクトとは?物体ではないものとは?これは何千年もの間、哲学者たちを悩ませてきた問いです。ルネ・デカルトは、人間が世界をオブジェクト指向で見ていることを観察しました。人間の脳は世界を物体という観点から認識し、思考や記憶は物体と物体間の関係に整理されます。

オブジェクトはテンプレートのようなものです。

アリストテレスはおそらく、 魚や 鳥の 概念を発展させ、 タイプの 研究を掘り下げた最初の哲学者でしょう。すべての物体はユニークであると同時に、同じ特徴や行動を持つ物体が属するクラスの一部でもあります。

型をとって、その型を使っていろいろなものを作ることができるようなもので、それぞれに "個性 "がありながら、基本的なパターンは同じなんです:

オブジェクトの特徴

銀行口座」を物体に抽象化することは可能ですが、それは物質でできているわけではありません。

あなたのアカウントは物質ではありませんが、性質を持って います。

それで十分でしょう?実際、これらの特徴にはすべて名前がついています:

  • 对象具有 アイデンティティ
  • オブジェクト 状態
  • 对象具有 振る舞い

これはオブジェクトの一般的な説明です。 オブジェクト指向のソフトウェアを書き始めるとき、このリストがオブジェクトの形を決めるのに役立つことがわかるでしょう。

プログラミング言語における抽象化プロセス

すべてのプログラミング言語は抽象化メカニズムを提供します。解決できる問題の複雑さは、抽象化の種類と質に直接依存すると言えます

"タイプ "とは、"何が抽象化されているか "という意味です。.

アセンブリ言語は、基礎となる機械語をわずかに抽象化したもので、その後に続く「命令型」言語の多くは、アセンブリ言語をさらに抽象化したものです。

これらの言語は、アセンブリ言語を大幅に改良したものですが、その抽象化の主な要因は、解決すべき問題の構造ではなく、コンピュータの構造に基づいて問題を考える必要があることです。

"

従来の構造化プログラミングでは、一連のプロセスを設計することで問題を解決します。これらのプロセスが定義されたら、今度はデータを格納する適切な方法について考え始めます。

パスカル言語の設計者であるニクラウス・ヴィルトの著書『アルゴリズム+データ構造=プログラム』が、このような理由から命名されました。

Wirthのこの本のタイトルでは、アルゴリズムが先で、データ構造が後であることが重要で、これはプログラマーがどのように仕事をするかを明確に示しています。まず、データをどのように操作するかを決定し、次に、操作できるようにデータの構造をどのように整理するかを決定します。

一方、OOPはこの順序を逆にし、データを操作するアルゴリズムを考える前に、まずデータを優先します。

このため、プログラマーは マシン モデルと 実際に解決すべき問題のモデルとの 間に 相関関係を確立する必要があります。

このようなマッピングの作成は手間がかかり、プログラミング言語固有の機能ではないため、プログラムを書くのが難しく、メンテナンスにコストがかかるだけでなく、副産物として「プログラミング・メソッド」という産業全体を生み出しています。

オブジェクト指向思考のブレークスルー

マシンをモデル化するもう一つの方法は、解決すべき問題に対してマシンをモデル化することです。

LISPやAPLのような初期のプログラミング言語は、「世界を説明する」ために特定の視点を選びました。 PROLOGは、すべての問題を決定連鎖に変換します。制約プログラミングに基づく言語や、グラフィカルなシンボルを操作することでプログラミングを行う言語も生まれました。

これらのアプローチは、解決しようとする 特定のタイプの問題に対しては 良い解決策ですが、特定の領域を 超えると 十分ではありません。

オブジェクト指向のアプローチは、問題空間の要素を表現するツールをプログラマに提供することで、さらに一歩近づきます。

この表現は非常に一般的であり、プログラマーが特定のタイプの問題に制限されることはありません。問題空間のいくつかの基本要素は、解空間の「オブジェクト」に抽象化されます。この考え方の本質は、新しいタイプのオブジェクトを追加することで、プログラムが特定の問題に適用できるようになるということです。

したがって、解決策を記述したコードを読んでいるときは、問題の定式化も読んでいることになります。これは、解決策の言語よりもはるかに柔軟で強力な言語の抽象化です。つまり、OOPは、解決策を実行するコンピュータの観点ではなく、問題の観点で問題を記述することを可能にするのです。

オブジェクト指向ソフトウェアにおける最も重要なブレークスルーの1つは、 オブジェクト指向の自然な脳の思考方法にマッチした方法でソフトウェアを組織化できるようにすることでした。メインメモリ内のビットデータを変更するマシン命令を直接使用する代わりに、属性を持ち、他のオブジェクトと相互作用できるオブジェクトを使用することが望ましいのです。もちろん、マシンレベルでは何も変わっていません。ビットデータは依然としてマシン命令によって操作されていますが、少なくともマシン命令について考える必要はもうありません!

"

小規模な問題では、プロセスに分解する開発アプローチの方が望ましい場合もあります。オブジェクト指向は、より大規模な問題に適しています。単純なWebブラウザを実装するためには、グローバルなデータセットを操作する必要のあるプロシージャが12個ほど必要になるかもしれません。

オブジェクト指向の設計スタイルを使えば、必要なクラスはほんの一握りで、それぞれが平均して1つのメソッドを含むだけかもしれません。これは明らかにプログラマーにとって習得しやすく、バグを見つけやすいものです。

OOP

以上のように、今日、オブジェクト指向プログラミングは避けて通れないものとなっています。では、どのようにしてそれが現実のものとなったのかを見てみましょう。

1900年代当時、コンピューターグラフィックスは存在しませんでした。 Ivan Edward Sutherland 当時、アメリカのコンピュータ科学者はSketchPadというドローイングアプリケーションを実装しました。

デザイナーのために特別に開発されたもので、スタイラスを使って三角形、四角形、円形などの簡単な幾何学図形をコンピューターで描くことができます。このプログラムは、 コンピュータ支援設計CADの 出発点でもあります。

これは、オブジェクト指向プログラミングの 創設パラダイムの ひとつとなりました。

アイヴァンのプログラミングでは、今でいう「オブジェクト」を使って現実の幾何学的形状を表現していたので、これらの形状はデザイナーにとって完全に理解できるものでした!

無限の変数や関数があるわけではなく、関係性における特定の要素のグループ化と管理を記述し、操作するための具体的な幾何学があるのです。

これらはすべて、現代では正確な名前がついています。

OOP の正規化

アイヴァンのプロジェクトや他のプロジェクトは、ここ数年のプログラミング言語 Simulaに 影響を与えました。オブジェクト指向の考え方をプログラミング言語に直接導入したのは、この言語が初めてでした。

ゼロックスは 1920年代にパーソナルコンピュータの開発に取り組みました。GUIとマウスを操作することで、誰でも簡単に使えるコンピュータを作りたかったのです。

画面上のすべての要素を表現し、それらの表示と操作のロジックをサポートするために、アラン・ケイ率いるチームは、 シミュラに触発され、多くの情報源によれば、今日使用されているオブジェクト指向プログラミングの概念の形式化を示す SmallTalk 言語を作成しました!

OOP Javaの普及

上記のようなアプローチは、その年に普及し、次のような偉大なオブジェクト指向言語の出発点となりました:

  • C ++は 、C言語のオブジェクト指向バージョンです。CとC++は、特に非常に特殊な業界で、今でも広く使われています。

おわかりのように、プログラミングの進歩は目を見張るものがあります

"

オブジェクト指向設計特有の効率性はどこから来るのでしょうか?

  • その影響の一部は、複雑なシステムをより明確に表現できるようになったことにあります;
  • おそらく最も重要な理由は、誰かに構造を与えるとき、その人に無制限の特権を与えたいと思うことはほとんどないということです。型マッチングだけでは十分とは言えません。あるオブジェクトは保護するが、他のオブジェクトは保護しないというのも、あまり合理的ではありません。

カプセル化を正しく実施することは、状態の抽象化だけでなく、プログラミングにおける状態指向のメタファーを排除することにもつながります。

Part 2. クラスとオブジェクトの概要

  • イメージ出典:https://javatutorial.net/java-oop

簡単に言うと、クラスはオブジェクトの設計図またはテンプレートであり、オブジェクトはクラスのインスタンスです。

この説明は概念を概念で説明するようなものですが、少なくともこの文から、クラスは抽象的な概念であり、オブジェクトは具体的なものであることは明らかです。

オブジェクト指向プログラミングの世界では、すべてがオブジェクトであり、オブジェクトはプロパティと振る舞いを持ち、それぞれのオブジェクトはユニークで、オブジェクトはクラスに属していなければなりません。共通の特徴を持つ多数のオブジェクトの静的および動的な特徴を抽出すると、 「クラス 」と呼ばれるものを定義することができます。

クラスの定義

クラスを使ってほとんどのものをモデル化することができます。子犬を表す簡単なクラスを書きたいとしましょう。

ほとんどのペット犬について知られていることは?-- 名前と年齢があり、吠えて食べます。ほとんどの子犬はこれら2つの情報と2つの行動を持っているので、Dogクラスはこれらを含むことになり、クラスはこのようになります:

コードの実装はおそらく次のようになるでしょう:

public class Dog {
    //  
    private String name;
    private Integer age;
    //  
    public Dog(String name, Integer age) {
        this.name = name;
        this.age = age;
    }
    // フィールド・アクセサ
    public String getName() {
        return name;
    }
    // フィールド・アクセサ
    public Integer getAge() {
        return age;
    }
    // 方法 - 叫
    void bark() {
        System.out.println("ワンワンワン!");
    }
    // 方法 - 吃东西
    void eat() {
        System.out.println("A " + age + "岁大的名叫 " + name + " 犬が食べている!");
    }
}

犬クラスの解剖学

上記のDogクラスについて、以下のセクションで詳しく説明します。まずはこのクラスのメソッドから見ていきましょう。 上のソースコードを見てわかるように、このクラスにはコンストラクタが1つとメソッドが4つあります:

public Dog(String name, Integer age)
public String getName()
public Integer getAge()
public void bark()
public void eat()

このクラスのメソッドはすべて public とマークされています。public というキーワードは、どのクラスのどのメソッドでもこれらのメソッドを呼び出せることを意味します。

次に、Dogクラスのインスタンスには、操作するデータを保持するインスタンス・フィールドがあることに注意してください:

private String name;
private Integer age;

private キーワードは、Dog クラス自身のメソッドだけがこれらのインスタンス・フィールドにアクセスできるようにし、他のクラスのメソッドはこれらのインスタンス・フィールドを読み書きできないようにします。

"

:インスタンス・フィールドにpublicを付けることは可能ですが、これは悪い習慣です。publicはデータ・フィールドを変更し、プログラム内のどのメソッドでも読み取ったり変更したりできるようにするもので、 カプセル化を完全に破壊します。 強度フィールドはprivateにすることを強くお勧めします。

名前フィールドはString型のオブジェクトで、年齢はInteger型のオブジェクトです。これは非常に一般的なことで、クラスには通常特定のクラス型のインスタンス・フィールドが含まれています。

コンストラクタから始める

同じクラス名でパブリックなパーミッションを持つメソッドDog()は コンストラクタと呼ばれますので、見てみましょう:

public Dog(String name, Integer age) {
    this.name = name;
    this.age = age;
}

Dogクラスのオブジェクトを構築する際には、コンストラクタが実行され、インスタンス・フィールドが望ましい初期状態に初期化されます。

例えば、Dogクラスが以下のコードで作成された場合:

new Dog(" , 1)

にデータを設定します:

name = " 
age = 1

コンストラクタが他のメソッドと異なる重要な点があります。コンストラクタは常に new キーワードと共に呼び出されます。既に存在するオブジェクトに対して、そのプロパティをリセットする目的でコンストラクタを呼び出すことはできません。例えば

dogInstance.Dog(" , 2);  // ERROR

コンストラクターについては、まだまだ語れることがたくさんありますが、とりあえず覚えておいてください:

  • イメージソース:https://.net/java-oop
  • 各クラスは複数のコンストラクタを持つことができます;
  • コンストラクタには、1つ、1つ、または複数のパラメータを指定できます;
  • コンストラクタは戻り値を持ちません;
  • コンストラクタは常に new 演算子で呼び出されます。

カプセル化の利点

最後に、非常にシンプルなgetName/getAgeメソッドを詳しく見てみましょう。

public String getName() {     return name; } public Integer getAge() {     return age; }

これらは典型的なアクセサ・メソッドです。これらはインスタンスフィールドの値のみを返すので、 フィールドアクセサとも呼ばれます。

名前フィールドと年齢フィールドにアクセスするために別々のメソッドを書くよりも、publicフィールドとしてマークし、どのメソッドでもアクセスできるようにする方が簡単ではないでしょうか?

上記の例では分かりにくいので、この点を説明するために、もっと面白い例を挙げましょう。

2つのクラスがあると仮定して、男はお金を稼ぐために懸命に働いて、時々残高を確認し、この時、男のお金を盗むことに特化した泥棒が来て、泥棒を捕まえて、男が泥棒を捕まえた後に盗まれた、この時、泥棒のお金が個人所有であるため、男は泥棒を捕まえて歯を食いしばりましたが、お金を取り戻すためのわずかな方法もありません!

カプセル化はセキュリティを向上させるだけでなく、オペレーションを簡素化し、 結束力を高めます。

例えば、とても大きなシステムを書いたとしましょう:

public int age;

おそらく、あなたのプログラムには次のような記述があるでしょう:

instance.age = 10;

この時、突然このフィールドのデータ型やその他の統一処理を変更するように要求され、場所を変更する必要がありますが、愚かではないですか?

カプセル化のもう一つの利点はモジュール化です。これにより、散在しているコードを集めて統一することが容易になります。

"

デザインパターンの主要な原則の1つである ディミトリの法則は 、カプセル化という特定の要件です。

例えば、イヤホンのジャックは音の出力を提供する動作のインターフェイスであり、このジャックに対応するイヤホンのマークがあるかどうか、丸いかどうか、音が鳴るかどうかだけを気にすればよく、内部のCPUがどのようにオーディオ情報を計算するか、様々なコンデンサがどのように連携するかについては、全く気にする必要はありません。

クラスの作成と使用

クラスを定義するのはオブジェクト・テンプレートを定義するだけであり、テンプレートに基づいて実際のオブジェクト・インスタンスを作成するには、new キーワードを使用してオブジェクトのコンストラクタを呼び出す必要があります:

Dog dog = new Dog(" , 1);

上記のコードでは、Dog型のインスタンスを作成し、変数dogを通してそのインスタンスを指しています。

最初のDogはdog変数の型を示し、2番目のDogはDogクラスのコンストラクタを呼び出します。 Java 10では 、初期値から型が推測できる場合、varキーワードを使って型を指定せずにローカル変数を宣言できます。例えば

var dog = new Dog(" , 1);

これはDogという型名を何度も書かなくて済むので良いのですが、パラメータやフィールドの型は明示的に宣言する必要があり、この使い方はメソッド内のローカル変数にしか使えません。

クラス内の共通メソッドを使用するには、. を使ってクラスのメソッドを連結して呼び出すことができます:

dog.eat();  // 调用该实例的 eat() 方法

Javaではオブジェクトの操作に参照を使用します

各プログラミング言語には、メモリ内の要素を操作する独自の方法があります。プログラマーは、どのような種類のデータが処理されるかに注意を払わなければならないことがあります。要素を直接操作するのか、それとも特別な構文に基づく何らかの間接表現でオブジェクトを操作するのか。

Javaではすべてがオブジェクトとして扱われるため、決まった構文を使うことができます。すべてがオブジェクトとして扱われますが、操作される識別子は実際には オブジェクトへの「参照」 です。

このリモコンを持っている限り、テレビに接続し続けることができます。誰かがチャンネルを変えたり、音量を下げたりしたいとき、実際に操作されるのはリモコンで、そのリモコンがテレビを操作します。

テレビを調整しながら部屋を歩き回りたいなら、テレビを持ち歩く代わりにリモコンを持ち歩けばいい......。

また、リモコンはテレビがなくても自立します

つまり、参照があるからといって、必ずしもそれに関連するオブジェクトを持つ必要はないのです。ですから、単語や文章を操作したい場合は、 String オブジェクトを作成します:

String s;

しかし、ここで生成されるのはオブジェクトではなく参照です。この時点でsにメッセージを送ると、実行時エラーが返されます。これは、sがこの時点では実際には何にも関連付けられていないからです。

したがって、参照が作成されたらすぐに初期化するのが安全です。

String s = "abcd";

これはJava言語の特徴を利用したもので、文字列を引用符で囲んだテキストで直接初期化することができます。

null

上で学んだように、オブジェクト変数にはオブジェクトへの参照が含まれます。参照にオブジェクトが関連付けられていない場合、実際には特別な値 null を指します。

未知の名前のような特殊なケースに対処するための便利な仕組みのように聞こえます。しかし、NULL値には細心の注意が必要です!Null値にメソッドを適用すると、NullPointExceptionがスローされます。

String s = null;
System.out.println(s.length());  // NullPointException

これは非常に深刻なエラーです!プログラムが例外を「キャッチ」しなければ、プログラムは終了してしまいます!通常、プログラムはこのような例外をキャッチしませんが、プログラマーが最初から例外を持ち込まないことを頼りにしています。

クラスを定義する際には、どのフィールドがnullになる可能性があるかを明確にしておくとよいでしょう。この例では、nameフィールドとageフィールドがnullになることは想定されていません。

これには2つの解決策があります。

Tolerant "メソッドは 、NULL引数を適切な非NULL値に変換します:

if (n == null) {
    name = "unknow";
} else {
    name = n; 
}

Java 9では 、Objectsクラスがこれを行う便利な方法を提供しています:

name = Objects.requireNonNullElse(n, "unknow");  // 効果は上のコードと同じである

strict "メソッドは 単にnull引数を拒否します:

name = Objects.requireNonNull(n, "The name cannot be null!");

NullPointerException 上記のコードをDogクラスのコンストラクタに追加し、誰かがNULL名でDogクラスを構築した場合、例外がスローされます。一見、これは良いアイデアとは思えませんが、いくつかの利点があります:

  1. 例外レポートには、この問題の説明が記載されます;
  2. そうでなければ、例外が別の場所に現れる可能性があり、実際に問題を引き起こしたコンストラクタのパラメータを追跡するのが難しくなります;

第3部 オブジェクト指向の4つの特徴

  • イメージ出典:"https://flashgene.com/archives/51745".html

オブジェクトには、カプセル化継承ポリモーフィズムという3つの大きな特徴があります。 抽象化 」も含めて、オブジェクト指向の4つの特徴と呼ぶことを支持する意見もあります。それはそれで間違ってはいないと思います。

抽象化

抽象化は、ファセットオブジェクト思考の最も基本的な能力の1つです。正しく厳密なビジネス抽象化、モデリング、分析能力は、その後のカプセル化、継承、ポリモーフィズムの基礎となり、ソフトウェア構築の礎となります。

パッケージング

上記の「 男と泥棒 」の例のように、カプセル化はセキュリティを向上させ、実装の詳細を隠すのに役立つだけでなく、オブジェクトの機能的な結合の一形態でもあります。

カプセル化はオブジェクト指向の世界をシンプルにし、オブジェクト間の関係もシンプルになり、「ドアの前の雪を掃く」でいいでしょう。特に今日のインテリジェントな時代には、カプセル化の要件はますます高くなって、例えば、 小愛の同級生 さて、唯一の外部インタフェースは、コマンドと関連データの実装の内部の詳細を隠し、大幅に使用コストを削減するだけでなく、効果的に内部データのセキュリティを保護する音声入力です。

継承

継承では、 クラスの論理的な階層を作り、継承ツリーを形成します。このようなプロパティやメソッドを持っているのは 犬だけ ではありません! 自然界にはこのような行動をする動物がたくさんいます。では、Animalオブジェクトを抽象化してみましょう:

Animalクラスを継承する限り、Animal親クラスが記述するプロパティとメソッドを持つことになります。このため、ビジネス上の変動という客観的な条件下で、ソフトウェアを直接再利用したり、間接的に再利用したり、特定のベースモジュールによって拡張したりすることができます。

継承は、退屈なコードの世界をより階層化し、拡張可能にし、ポリモーフィズムの構文的基礎を築きます。

しかし、相続にはいくつかの 欠点があります:

  1. イメージソース:https://.com/archives/.html
  2. 継承は カプセル化を破壊し、その実装はサブクラスには透過的です;

ポリモーフィズム

ポリモーフィズムは、上記の3つのオブジェクト指向の特徴に基づいています。 実行時の実際のオブジェクトタイプに応じて、同じメソッドが異なる実行結果を生成し、同じ動作が異なる表現を持つことができます。

ちょっと学術的すぎるので、わかりやすくするために例を挙げてみましょう。たとえば、水のコップがあり、私はそれが暖かいかどうかわからない、冷たいまたは熱い、しかし、私はそれに触れるとき、私はこのアクションのカップに触れることを知っている、水の異なる温度については、異なる結果を得るでしょう、これは多形性です。

自然界におけるこの最たる例は、炭素の仲間です。恋人の誕生日パーティで炭素のかけらをあげると言ったら、もちろん彼女は喜ばないでしょうが、実際は5カラットのダイヤモンドなのです。ダイヤモンドは、絶え間ない進化の過程における炭素の多形的な現れなのです。

厳密に言えば、ポリモーフィズムはオブジェクト指向の特徴ではなく、継承という行為から派生した進化的な能力です。

エッセンシャルレビュー

  1. クラスとオブジェクト - クラスとは / オブジェクトとは / OOPの起源と発展 / オブジェクト指向に関連するその他の概念
  2. クラスの定義 - 基本構造 / プロパティとメソッド / コンストラクタ
  3. オブジェクトの操作 - オブジェクトの作成 / オブジェクトのメッセージング
  4. オブジェクト指向の4つの柱 - 抽象化/カプセル化/継承/ポリモーフィズムの簡単な紹介
  5. 基本練習-ドッグ・クラスの定義/クロック・クラスの定義/グラフィック・クラスの定義

演習

練習1:デジタル時計を記述するクラスを定義します。

public class Clock {
    private Integer hour;
    private Integer minute;
    private Integer second;
    public Clock(Integer hour, Integer minute, Integer second) {
        this.hour = hour;
        this.minute = minute;
        this.second = second;
    }
    /**
     * 時計の歩き方
     */
    public void run() {
        second += 1;
        if (second.equals(60)) {
            second = 0;
            minute += 1;
            if (minute.equals(60)) {
                minute = 0;
                hour += 1;
                if (hour.equals(24)) {
                    hour = 0;
                }
            }
        }
    }
    /**
     * 現在時刻を表示する
     * @return
     */
    public String showCurrentTime() {
        return String.format("現在の時刻は%d :%d :%d秒", hour, minute, second);
    }
    /**
     * 内部テスト
     * @throws InterruptedException - 使用 Thread.sleep() 需要手动检测该异常, 这里节约篇幅直接抛出
     */
    public static void main(String[] args) throws InterruptedException {
        Clock clock = new Clock(23, 59, 58);
        while (true) {
            clock.run();
            System.out.println(clock.showCurrentTime());
            // 让当前线程睡 1s
            Thread.sleep(1000);
        }
    }
}

練習2:平面上の点を記述し、その点を移動して別の点までの距離を計算するメソッドを提供するクラスを定義します。

public class Point {
    private Integer x;
    private Integer y;
    public Point() {
        this.x = 0;
        this.y = 0;
    }
    public Point(Integer x, Integer y) {
        this.x = x;
        this.y = y;
    }
    /**
     * 指定した場所に移動する
     */
    public void moveTo(Integer x, Integer y) {
        this.x = x;
        this.y = y;
    }
    /**
     * 指定した距離を移動する
     */
    public void moveBy(Integer dx, Integer dy) {
        this.x += dx;
        this.y += dy;
    }
    /**
     * 別の点までの距離を計算して返す
     */
    public Double distanceTo(Point other) {
        int dx = this.x - other.x;
        int dy = this.y - other.y;
        return Math.sqrt(dx ^ 2 + dy ^ 2);
    }
    /**
     * 現在の座標情報
     */
    public String currentLocation() {
        return String.format("現在点の水平座標:%d,垂直座標%d", x, y);
    }
    /**
     * 内部テスト
     */
    public static void main(String[] args) {
        Point point1 = new Point(3, 5);
        Point point2 = new Point();
        System.out.println(point1.currentLocation());
        System.out.println(point2.currentLocation());
        point2.moveTo(-1, 2);
        System.out.println(point2.currentLocation());
        System.out.println(point1.distanceTo(point2));
    }
}
  1. Javaコアテクノロジー 第1巻
  2. Javaコア技術 第1巻
  3. Javaプログラミングのアイデア。
  4. Swiftによるオブジェクト指向プログラミングの学習で知識を深める - "https://openclassrooms.com/en/courses/4542122"-deepen-your-Swiftを使ったオブジェクト指向プログラミングを学んで知識を深めましょう。
  5. Deepen your knowledge by learning Object Oriented Programming with Swift - "https://.com/en/courses/4542122"-deepen-your-knowledge-by-learning-object-oriented-programming-oop-with-swift
  6. Think like a computer: the logic of programming - "https://.com/en/courses/5261691"-think-like-a-computer-the-logic-of-programming
"

    あなたがこの記事がよく書かれていると思う場合は、 ここで見るためにあなたの才能のためにどうもありがとうございました、 "私は3つの心を持っていない "何かを 考え、

    創作するのは簡単なことではありません。皆さんのサポートと評価が、私の創作への最大のモチベーションです!

    Read next

    最初から最後まで高度な並行プログラミング

    volatileのメリットとデメリットは?\n使用上の注意点は?\n3.デッドロックとは何ですか?デッドロックになる状況とは?\n上記の質問について、まだ疑問がある方は各自で復習してください。\n本章のまとめ\nこの章を終えることで、V

    Apr 26, 2020 · 11 min read