OOP におけるポリモーフィズムとは何ですか。 オブジェクト指向プログラミング (OOP): ポリモーフィズム

12.01.2024 サウンドデバイス

わかりました。 ポリモーフィズムは、抽象化、カプセル化、継承などの他の基本的な概念と切り離して考慮すべきではありません。 物体などは公理(これも公理ですが)から付加されます。

実際に、近くにグラス、マ​​グカップ、ケトル、コーヒーメーカー、自転車、スケートボードがあると想像してみましょう。 それらすべてに共通するものは何ですか? まあ、少なくともそれらは存在します。 つまり、これらは作成されたオブジェクトです。 しかし、それらはどのようにして作成されたのでしょうか? 図面によると、おそらくメーカーの工場にあります。 OK、コンストラクターを描画と呼びましょう。 さて、クラスはどうですか? で、それ何? しかし、それは私たちの宇宙には存在しません。この本質は私たちの思考の中にのみ存在する抽象概念です。 現実の世界では、それは存在しませんし、今後も存在しません。それは物理学です - 鳥や哺乳類に遠い親戚がいるかどうかは気にしません - それは自然選択の可能性を提供するだけです。 そして私たち人間は、お互いに親戚を見つけます。

オブジェクトとクラスは整理しましたが、メガネと自転車はどうなるでしょうか? すべてがオブジェクトであることはすでに理解しています。つまり、大まかに言うと、すべてのオブジェクトは、一部の言語で実装されている上位の祖先、スーパークラスから継承できるということです。 しかし、たとえば、スケートボードとグラスの共通点は他に何でしょうか? もちろん、さらに深く考えて、それらはすべて分子でできており、すべて固体でできていると考えることもできます。 しかし、これはすべてナンセンスであり、SRSG であるため、答えは簡単です。何もありません。 つまり、これらはまったく異なる機能を持つまったく異なるオブジェクトです。 さらに、当然のことながら、コンピューターのモデルと階層は物理学や化学とは大きく異なります。 これは正常なことであり、モデルの妥当性の問題は、モデルが不適切な場合にのみ提起され、それまでは、機能するものであれば何でもカットできます。

ここ。 スーパー祖先オブジェクトがあり、すべてのオブジェクトはデフォルトでそこから継承します。 オブジェクトが原子で構成されているという事実が、すべてのオブジェクトに継承されると仮定しましょう。 ただし、すべての追加と編集はポリモーフィズムです。 そこで、原子から車輪を作り、それをボードに取り付けました。これがスケートボードです。 その上に立って転がったり、強くひねって地上 3 メートルを飛んだり、明るい自我を放射するだけです。 一方、ガラスは原子から高密度の容器を成形した場所であり、そこから重力の影響で水が流れ出すことはありません。 また、グラスを直接使用する場合は、水を注ぎ口に傾けて、水が直接胃に流れ込むようにします。 それが本当の男の子の行動で、しゃっくりや溺れる恐怖を心配する必要はありません。つまり、多態性です。

しかし、残りはどうでしょうか? 抽象化、カプセル化、継承もあります。 さて、継承から始めましょう。これが最も近いものです。 グラスとマグカップの共通点は何でしょうか? どちらにも水を注ぐことができますが、マグカップには持ちやすいハンドルが付いています。 つまり、特定の一般的なクラス、つまり容量を思いつくことができます。 しかし、このクラスは何ですか? たとえば、このクラスにガラスを使用すると、すべてのコンテナがデフォルトでガラスになり、その他はすべて変更されたガラスになります。 しかし、便利だと考えて水差しを好む人もいます。たとえば、ひよこが水差しを頭にかぶっている場合もあります。 まあ、彼らにそれを着させますが、どういうわけか彼らは何がより重要で理想的であるかを決定する必要があります。 つまり、達成不可能な理想が主要なものであり、これは抽象クラスと呼ばれます。 つまり、完全な描画が存在しない、作成できないコンテナです。 そして、完全な形に展開されたすべての図面は、容量クラスから継承されたクラスです。

ここで抽象化に進みます。 この階層的な継承は、おそらく OOP の主要なアイデアにつながります。 そこで、水を注ぐことができるすべてのものを別のクラスに取り出して強調表示し、一般的な図面を描きましたが、具体的には完成させず、将来の作成者のための空白を残し、その図面をコンテナと呼びました。 何千年もの間、彼らはすべての世界を発明し、一方が他方よりも優れた独自のコンテナを作成してきました。 もちろん、人によって異なります。 しかし、ガラス分子を毎回特定の方法でグループ化するのは簡単な作業ではありません。 そこで、職人たちはある策略に訴えました。世界中の職人で構成される秘密評議会を設立し、その成果を互いに共有することにしました。 つまり、小さな描画を作成し、たとえばメビウスの輪の形をしたツイストペンなどをクラスとして宣言します。 おそらくそのようなペンは外来生物にのみ便利ですが、図面が作成されており、独自の図面を作成するときに参照できます。 このようにして、「分子を動かしてコンテナを形成する」という低レベルのタスクを、「部品や要素を組み合わせてコンテナを構築する」という低レベルのタスクに抽象化します。 これが抽象化です。

しかし、最後のポイントであるカプセル化に到達します。 それは抽象化と切り離すことができず、実際、それが機能するのは抽象化のおかげです。 カプセル化は、異なる図面を 1 つに接着するために使用される一種の接着剤 (または青いテープ) です。 つまり、パーツを組み合わせて独自のものを作成することがカプセル化です。 さらに、結合するときに、この結合の詳細を記述しない場合があります (つまり、クラス メンバーはプライベートにすることができます)。これにより、この図を使用するユーザーを抽象化するのに役立ちます。 ティーポットを見てみましょう - それは何ですか? これはグラス(またはマグカップ)の底部(あるいは真ん中の内側?)に発熱体が接着されているものです。 発熱体に封入されたオームの法則に従って、それに電流を流すと熱が放出され、水が加熱されます。 コーヒーマシンはどうですか? これは、多くのポンプ、タンク、エアロック、グラインダー、ケトルを備えた、より複雑な装置です。 そしてすべてを接着剤で貼り合わせます。 あるいは青い電気テープかもしれません。 これもまたカプセル化です。

したがって、継承そのものがなければポリモーフィズムが不可能であるのと同様に、カプセル化と継承がなければ抽象化も不可能です。 まあ、ポリモーフィズムもカプセル化なしでは不可能ですが、カプセル化は継承とポリモーフィズムがなければ単に役に立ちません。 これらはパイのある三角形です。 彼らがパイについて嘘をついたのは残念だ。 そして誕生日について。

プログラミングは、コード、データ、関数、アルゴリズムの厳密な構造の形で「生きている」動的な問題に対する解決策を開発するプロセスです。 曖昧なセマンティクスから厳密な構文を形成する手順。 現実世界の問題は、アルゴリズム化におけるよく知られた大きな問題です。目的の解決策を達成するには、問題を正確な構文構造に配置する必要があります。

OOP は、この古代のプログラミング概念を「打破」することを 2 回試みましたが、データ コーディングとアルゴリズムの古典的なスタイルの「足かせ」は依然として強力です。

レベルと資格

コンピューターサイエンスは計算から始まりましたが、情報処理分野への移行の加速度は高まっており、古典的なプログラミングが不可能になり消滅するほどの速度はまだありません。

開発者が主張しないこと、また顧客が実際の問題に対する実際の解決策を要求しないことも客観的です。 どちらの側も、利用可能なツールや使い慣れた機能によって制限されることに慣れています。

OOP ポリモーフィズムの形式、コードのカプセル化とプロパティ (メソッド) の継承のアイデアは、プログラミングの領域にありますが、解決される問題の領域にはありません。

その好例は、PHPOffice/PHPWord ライブラリです。 それを使用するには、開発者の資格が必要で、独自のオブジェクト システムを作成する必要がありますが、現在の顧客のレベル (顧客要件) は、プログラマが独自の開発でカバーする些細な構成です (そうでないと要件を満たすことができません) )。 状況は次のようなものです。

この場合、ライブラリの使用は文書の書式設定のタスクです。たとえば、卒業証書や論文は標準に従って書式設定する必要があります。 顧客は自分の要求を提示し、プログラマーはさらに自分の道を進めました。

ドキュメントの完全な解析が実行され、必要な形式での組み立て、任意のネスト レベルのテーブルの操作、セルの結合と分割、任意の方向への印刷などが行われました。

ポリモーフィズムと OOP

ポリモーフィズムについて、今日非常に人気があり、頻繁に使用されているオブジェクト指向プログラミングのアイデアの開発の歴史を参照するより適切な定義は思いつきませんが、 未実現本質的にはまだそうです。

  • カプセル化。
  • 多態性。
  • 継承。

さらに、抽象化を追加する人もいます。ほとんどの場合、これが実際の主要なポイントであり、OOP の本質を説明するための基礎として使用されます。

したがって、OOP に関する意見には多態性があります。それらは 1 つのことを説明していても、異なる設計になっているか、あるいは逆に、異なることを説明しているものの、4 つの同一の立場に基づいています。

民主主義の原則は情報技術の分野に特有のものではありませんが、それは当然のことであると考えられるべきです。同じものについての多くの意見の組み合わせと共存は、実際のポリモーフィズムです。

ポリモーフィズムの一般的な定義

OOP は、情報技術開発の次の段階です。 これに異論を唱える人はほとんどいませんが、その主な公理と規定は意味論の点で大きく異なるため、その全体性以外では注目に値しません。

  1. プログラミングにおけるポリモーフィズムとは、異なる基礎となるフォーム (データ型) に同じインターフェイスを提供する機能です。
  2. ポリモーフィズムとは、オブジェクトがさまざまな実装を持つことができる機能です。
  3. ポリモーフィズムとは関数の能力です...
  4. 古典的 (C/C++ の作成者による): 「1 つのインターフェイス - 多数の実装」。
  5. パラメトリックポリモーフィズムとは...
  6. ポリモーフィズムは型理論の規定です...
  7. ポリモーフィズムが継承なしでは不可能であるのと同様に、抽象化もカプセル化と継承なしでは不可能です。

これらすべてが同じことを指していることに同意できますが、思考の表現形式、本質、内容は似ていません。 しかし、まだ共通点があります。

エンティティ: 開発者 - 顧客

古典的なプログラム開発は、プログラマーとタスク (クライアント、顧客) の存在を前提としています。 プログラマーは問題を調査し、形式化し、解決策につながるコードを作成します。 顧客は提案されたすべてを拒否するか、その一部のみを拒否して欠点を指摘し、プログラマーは再び仕事をやり直します。

問題解決プロセスのこのサイクルは、2 つの完全に異なるエンティティがここで明らかに組み合わされていることを示唆しています。

  • コンピュータ自体は問題を解決できません。
  • コンピュータが問題を「理解」し、「解決」できるようにするためにはプログラムが必要です。

タスクは顧客の能力の範囲であり、プログラムはタスクをコンピュータの能力、つまりプログラマーの能力の範囲に「適応させる」ためのアルゴリズムです。 後者の役割は、コンピュータをタスクの要件に「適応させる」ことですが、これは不要です。

オファー 抽象的な。 オブジェクトがあります。これは顧客の領域です。 オブジェクトの実装があります。これはプログラマの領域です。 顧客と開発者の間には「技術的な」つながりはありません。 このアイデアは急進的であり、今日まで実装されていませんが、すでに安定して動作しているものがあります。

ウィンドウ、ボタン、その他のオブジェクト

Air Art Technology、Object Magazine、Turbo Vision、Graph Vision の歴史はすでに歴史になっています。 これらの OOP の実装を覚えている人はほとんどおらず、実際には使用されておらず忘れ去られていますが、Windows ウィンドウ インターフェイスは何百万ものユーザーに馴染みがあり、PHP、JavaScript、その他のインターネット テクノロジ言語のオブジェクトは何十万ものコード開発者によって使用されています。そして、Web リソースへの何百万もの訪問者がそれらのことを知っています。

これはおそらく、OOP が開発すべき唯一の正しい方法です。カプセル化、継承、ポリモーフィズムは開発者にとっては重要ですが、ユーザーにとってはそうではありません。 WindowsソフトやTurbo Vision、Graph Visionなどのアプリケーションプログラムのビジュアルデザイン(インターフェース)の開発が主にこのポジションで行われたのが特徴です。

Air Art Technology や Object Magazine などの製品の背後にあるコンセプトは大きく異なりました。 ここで、抽象オブジェクトは情報構造の最初の祖先であり、情報処理コードを抽象レベルでカプセル化します。 ここでは、ウィンドウ、ボタン、および視覚的なデザイン要素のオブジェクトは二次的なものでした。

最初のバージョン (Windows など) では、OOP パラダイム: カプセル化、継承、ポリモーフィズムが抽象祖先のレベルで指定され、コードの実装は、継承ブランチに沿ってそれぞれの特定の子孫のレベルで形成されました。必要な構造とコンテンツに合わせます。

2 番目のオプション (Air Art Technology and Object Magazine) では、抽象オブジェクトのレベルが重要です。 特定の子孫が何を持つかは重要ではありません。重要なことは、その継承ブランチがルート抽象化に至るまですべての親の要件を満たすことです。

オブジェクトとオブジェクトのシステム: アルゴリズム

理想的なオブジェクト指向の概念では、オブジェクトとオブジェクトのシステムのみを操作できます。

現代のプログラミング言語では、オブジェクト (クラス) は通常、オブジェクトの記述とオブジェクトのインスタンスとして理解されます。オブジェクトの記述を使用するために、言語ではプログラマが静的オブジェクトを操作できるようにしますが、動的オブジェクト - 独自の内容と構造を持つ説明ですが、同じ説明方法 (プロパティ) を使用します。

現在の実務では、オブジェクトの概念をツール、つまりプログラミング言語、インターフェイス、データベース アクセス、ネットワーク接続に関連付けていますが、顧客の関心や解決されている問題を示すものは何もありません。

これは単純な OOP に最適です。ポリモーフィズムにより、特にさまざまな設計要素を作成しながら、それらを同じコードで管理できるようになります。 しかし、ここで私たちは問題のオブジェクトについて話しているのではなく、オブジェクト指向分析の対象としてまったく考慮されていません。

プログラマーは、仕事の品質と生産性を向上させる手段として OOP を採用しましたが、「自分の領域」を顧客に少しも譲りませんでした。 OOP の基本概念 (カプセル化、継承、ポリモーフィズム) は開発領域に残り、タスク領域には移植されませんでした。

オブジェクトとオブジェクトのシステム: 問題と解決策

コンピューター - プログラマー - タスク。 中央のリンクは冗長です。 理想的には、(コンピュータ - プログラマ) - タスクという比較的依存性の高い回路が 2 つだけ存在する必要があります。 つまり、ユーザー、顧客、または訪問者は問題を解決するツールを持っています。 顧客はツールがどのように実装されるかは気にしません。

理想的には、これは顧客が何を望んでいるのかを理解し、望むことを実行できる単なるコンピューターです。 それがどのようなものであるか、ローカル プログラム、ブラウザ経由でアクセスできる Web サイト、分散情報処理のための特別なプログラム、顧客用の情報システムなど、それは問題ではありません。

タスクとコンピューターの間に不必要なリンクがないことが重要ですが、最初のリンクは 2 番目のリンクによって理解され、解決されます。 この目標を達成するには、コンピュータと顧客が 1 つのオブジェクト システムによって接続されている必要があり、各オブジェクトの意味、構造、内容は顧客によって決定され、オブジェクトのメソッドとプロパティはプログラマによって実装されます。

顧客が必要とするオブジェクトのシステムを作成する作業と、これらのオブジェクトのメソッドとプロパティを実装する作業が時間的に分離されている場合が理想的です。 オブジェクトのシステム (プログラマ) の実装がその意味論的な内容 (顧客) から離れているほど、プロセスの品質は向上します。

問題を解決する過程で顧客とプログラマが対話することを妨げるものはありませんが、セマンティクスを明確に分離することが重要です。 誰もが自分の仕事に関心を持つべきであり、プログラマーはタスクの範囲を習得する義務はなく、顧客はコードを理解する必要はなく、さらに、当事者は自分たちに関係のないことについて互いにアドバイスし合うべきではありません。

従来のオブジェクト プログラミング

OOP の基本公準であるカプセル化、継承、ポリモーフィズムは、よく知られ需要が高まっている形式であり、コードの品質と信頼性の顕著な向上につながり、プログラマーの作業を大幅にスピードアップし、多くの効果をもたらします。他のポジティブな性質。

しかし、状況は依然として存在しています。古典的なプログラミングはその立場に劣るものではなく、オブジェクト指向のアイデアの多くは古典的なコードで実装されています。

しかし、OOP と再帰の考え方は、古典的な構文演算子の構文、つまりオブジェクト指向スタイルの記述や思考とは何の関係もない通常のコードを構築するロジックに適切な影響を与えました。

リストとキューが変換され、配列の最初と最後の要素の概念が登場し、「for each」ループが登場し、名前付け、使用、実行のための参照オプションが以前よりもさらに普及しました。

実際、変数がその「明確な」面を失ったという事実自体 (変数の型は必要に応じて変更でき、変数を記述する必要はまったくありません) は、実際、古典がずっと前にオブジェクトになったことを示しています。 OOP の基本原則であるカプセル化、継承、多態性を非常に重要な概念として指向し、認識しました。

それは何に基づいていますか: オブジェクトですか、それともシステムですか?

OOP の主な概念的な位置としての抽象化は、オブジェクトの責任範囲 (実装) がどこにあるのか (最初の抽象オブジェクトのレベルか特定の子孫のレベルか) に関係なく、次のような疑問を残します。オブジェクトから、またはシステムから、どこからすべてを始めるべきでしょうか?

オブジェクトを基礎として置いた場合、システムはその内部に存在するため、決してシステムにはなりません。また、それ自体が非常に具体的な始まりの硬直したイメージになります。 ここで、抽象化に伴う問題が発生します。最初のオブジェクトは、解決される問題の主要なものを正確に捉えています。つまり、別の問題に転送できなくなります。

オブジェクトのシステムに基づいた場合、システムのシステムが得られます。 これは、具体的なタスクに関連付けてイメージするのが難しく、どこから開発を始めればよいのかもわかりにくいです。 概して、エンティティ、実装形式、関数内の実際のパラメータの数の違いを伴う OOP の多態性により、最初にあるシステムのアイデアは次のようになります。

  • 問題を解決するためのオプション (メニューなど) について。
  • 初期条件について(さまざまな条件、データでの問題の適用)。
  • 動作モード(テスト、設定、操作)について。

しかし、これと類似のものは、オブジェクトのシステムに基づいて問題の解決策を立てる根拠を与えていません。 多くの場合、単一の開始オブジェクトを定義するだけで十分です。

問題解決プロセスの歴史

OOP の最も重要な原則: ポリモーフィズムと抽象化 - オブジェクトのシステムとして初期オブジェクトを優先します。 鶏が先か卵が先かという議論では、ここでは鶏が勝ちます。

すべてはオブジェクトのシステムではなく、抽象オブジェクトから始まらなければならないことに疑いの余地はありません。 しかし、時間の要素を考慮し、それを最初の抽象的なものから始めて各オブジェクトのレベルに適用すると、オブジェクトとシステムの両方を決定の最初に置くという矛盾したアイデアが生まれます。合理的なものだけです。

プログラミングの古典的な概念が、問題を解決する過程でデータ、データベースの内容、ファイルなどを変更する場合、OOP、ポリモーフィズム、カプセル化、および時間要因の概念では、内容、構造、および時間要素が変更されます。解決される問題のオブジェクトのシステムのプロパティ。

OOP のプログラマは、ファイル、データベース、アルゴリズムの概念にはほとんど興味がありません。これらは詳細です。ここではプログラマはオブジェクトで考えますが、オブジェクトは時間の経過とともに存在し、目的を達成する過程で変化します。

したがって、最初に、オブジェクトのシステムとしてのオブジェクトと、このシステムのロジック、つまり時間スケールが存在します。タスクの起動、最初のオブジェクトの形成、データの入力または収集、次のオブジェクトの形成ですが、最初のオブジェクトの実行を妨げるものはありません。次の解決策に進みます。

オブジェクトの各レベルは、オブジェクトの独立したシステムとして機能します。つまり、それは 1 つのオブジェクトですが、開始されたプロセスと時間の意味のコンテキストでは、時間スケール上のオブジェクトのシステムです。 OOP の完全な実装では、ポリモーフィズム、継承、および時間要素を組み合わせることで、最初のダイナミクスが保証されます。つまり、オブジェクトは時間の経過とともに変化するだけでなく、開発者が意図していないオブジェクト、つまり、オブジェクトの実行によって生成されるオブジェクトも生成される可能性があります。顧客が設計したプロセス中のタスク。

実際の OOP ポリモーフィズムの例

OOP で実行できる問題の複雑さは、従来のバージョンのプログラム作成で可能な問題とは比べものになりません。 もちろん、どんな問題でも通常の方法で解決することはいつでも可能ですが、時間と労力がどれだけ「かかる」かという問題によって、結果が役に立たなくなることがよくあります。

PHPOffice/PHPWord ライブラリは少し前に開発されましたが、その機能を使用するには、ほとんどの場合、独自のオブジェクト システムを作成する必要があります。 たとえば、単純な *.docx ファイル:

は、Office Open XML 形式 (OpenXML、OOXML) の多くのファイルとフォルダーの zip アーカイブです。 各ファイルは XML タグで記述されており、文字、単語、表、リスト、その他の要素を追加、変更、削除すると、ファイルの内容は一連のタグを表し始めますが、多くの場合、それらの要素には完全な要素が含まれるとは限りません。たくさんのタグで書かれています。

このファイルを一連のタグとして想像すると、興味深い図が得られます。

ドキュメントの最初で唯一の段落が多くのタグで表されていることに簡単に気づくことができます。 テーブルとそれに組み込まれたテーブルに関しては、すべての要素の記述量を認識することはできませんが、オブジェクト指向アプリケーションからはアクセスできます。

実際、図では、緑色がタグのテスト出力、黄色がタグのパラメータとタイプ、ベージュがコンテンツです。 作成されたオブジェクトは機械処理を対象としています。 文書ファイルを開く、フォーマットする、記録するという操作のみが可能になります。

このソリューションはシンプルで実用的ですが、実行される機能の量とオブジェクト間の複雑な関係により、実装は人間指向よりもコンピューター指向になります。

OOP エリアの状態

Web サイト管理システムの開発、サーバーのセットアップと管理のテクノロジ、および動的 Web サイトの開発経験により、オブジェクト指向プログラミングは誰でも利用できるようになりました。 問題は、考え方を変えて、順次実行されるコードのコンテキストではなく、オブジェクトのレベルで考えることに慣れる方法です。

通常、古典的なプログラミングからオブジェクト指向プログラミングへの移行には 2 ~ 3 か月かかりますが、コストはそれだけの価値があります。 最新のプログラミング言語、主に PHP と JavaScript の可能性は、最も洗練された開発者を満足させるでしょう。

最新の OOP (ポリモーフィズム、継承、オブジェクト プロパティを形成する機能) は便利で実用的であり、言語構文と補助ツールにより使いやすさとコード効率が保証されます。

オブジェクトのアイデアに関する視点

古典的なプログラミングがどれくらい続くのか、そして OOP がどのように発展するのかを言うのは非常に困難です。 どうやら、ツール開発者は消費者(ユーザー、顧客)のコンテキストを考慮するつもりはないようです。

OOP ツール (ポリモーフィズム、継承、カプセル化、抽象化) は開発者向けです。

現代の情報システムと Web リソースは、現実を反映し、実際のオブジェクトの機能を保証し、プログラミングから遠く離れて自分の分野に完全に没頭している消費者でもアクセスできる非常にシンプルな機能環境を作成するよう努めています。能力。

オブジェクト指向プログラミング(OOP) は、相互に対話するクラスとオブジェクトの使用に基づいてプログラムを作成するアプローチです。

クラス (Java クラス) は、オブジェクトの構造と動作を記述します。 デバイスは一連の特性 (プロパティ) によって記述され、動作はオブジェクトで使用できる一連の操作 (メソッド) によって記述されます。 プロパティやメソッドを追加またはオーバーライドすることで、既存のクラスに基づいてクラスを作成できます。

クラスは、オブジェクトを構築するためのテンプレートを表します。 オブジェクトは、同様の特性と動作のセットを持つプログラム要素です (つまり、同じクラスに基づいて構築された要素です)。 各オブジェクトには特定の状態があり、その状態はすべてのプロパティの値によって決まります。 1 つのプログラム内に複数のクラスが存在でき、異なるクラスのオブジェクトが (メソッドを通じて) 相互に対話できます。

継承、拡張

継承は Java に不可欠な部分です。 継承を使用する場合、基本 (親) クラスのプロパティを継承する新しいクラスが、親が持つすべてのプロパティを持つことが考慮されます。 コードはオペランドを使用します 伸びるの後に基本クラスの名前が続きます。 これにより、基本クラスのすべてのフィールドとメソッドへのアクセスが開かれます。

継承を使用すると、一連の関連要素に共通の特性を定義する汎用の「Java クラス」を作成できます。 次に、それを継承して追加のクラスを作成し、そのクラスに固有の追加の特性を定義できます。

Java で継承される主なクラスはスーパークラスと呼ばれます 素晴らしい。 継承クラスは呼び出されます サブクラス。 したがって、サブクラスは、スーパークラスのすべてのプロパティを継承し、独自の固有の要素を追加する、スーパークラスの特殊化されたバージョンです。

Java クラス「学生 Student」の記述の例を考えてみましょう。これには、姓、名、年齢、グループ番号が含まれます。すでに存在するユーザー User のスーパークラスに基づいて学生クラスを作成します。定義された名、姓、年齢:

パブリック クラス User ( int age; String firstName; String lastName; // コンストラクター public User(int age, String firstName, String lastName) ( this.age = age; this.firstName = firstName; this.lastName = lastName; ) )

ここで、スーパー クラスのプロパティを継承する別のクラス Student を作成します。 クラスを継承するときは、親クラスのコンストラクターもオーバーライドする必要があります。

Public class Student extends User ( int group; // コンストラクタ public Student(int age, String firstName, String lastName) ( super(age, firstName, lastName); ) boolean isMyGroup(int g) ( return g == group; ) )

キーワード 伸びる User クラスから継承していることを示しています。

キーワードスーパー

Student クラスのコンストラクターでは、演算子を通じて親クラスのコンストラクターを呼び出します。 素晴らしい、必要なパラメータのセット全体を渡します。 Java ではキーワード 素晴らしいスーパークラスを表します。つまり、 現在のクラスの派生元のクラス。 super キーワードを使用すると、スーパークラス コンストラクターを呼び出し、サブクラス メンバーによって隠されたスーパークラス メンバーにアクセスできます。

それがどのように起こるかを見てみましょう 継承オブジェクトの作成に関しては、次のようになります。

Student Student = new Student(18, "Kisa", "Vorobyaninov", 221);

まず、Student クラスのコンストラクターが開かれ、次にスーパークラス User のコンストラクターが呼び出され、Student コンストラクターの残りの操作が実行されます。 この一連のアクションは非常に論理的であり、単純なオブジェクトに基づいてより複雑なオブジェクトを作成できます。

スーパークラスには、そのコンストラクターの複数のオーバーロードされたバージョンを含めることができるため、異なるパラメーターを使用して super() メソッドを呼び出すことができます。 プログラムは、指定された引数に一致するコンストラクターを実行します。

キーワードの 2 番目の形式 素晴らしいキーワードのように機能します これこの場合に限り、常にそれが使用されているサブクラスのスーパークラスを参照します。 一般的な形式は次のとおりです。

ここで、メンバーはメソッドまたはインスタンス変数です。 この形式は、サブクラスのメンバーの名前が同じ名前を持つスーパークラスのメンバーを隠している場合に適しています。

Class A ( int i; ) // クラス A から継承 class B extends A ( int i; // 変数名はクラス A の変数 i と一致し、非表示になります B(int a, int b) ( super.i = a; // アクセスクラス A の変数 i へ i = b; // クラス B の変数 i にアクセス ) void show() ( System.out.println("i from superclass is " + super.i); System.out.println(" iサブクラス内は " + i); ) ) class MainActivity ( B subClass = new B(1, 2); subClass.show(); )

その結果、コンソールに次の内容が表示されるはずです。

スーパークラスの I は 1 サブクラスの I は 2

メソッドのオーバーライド、オーバーライド

クラス階層内で、サブクラス メソッドの名前と型シグネチャがスーパークラス メソッドの属性と一致する場合、サブクラス メソッドはスーパークラス メソッドをオーバーライドします。 オーバーライドされたメソッドがそのサブクラスから呼び出される場合、そのメソッドは常にそのメソッドのサブクラスのバージョンを参照します。 また、メソッドのスーパークラス バージョンは非表示になります。

スーパークラスで定義されたオーバーライドされたメソッドのバージョンにアクセスする必要がある場合は、キーワードを使用する必要があります。 素晴らしい.

オーバーライドとオーバーロードを混同しないでください。 メソッドのオーバーライドは、2 つのメソッドの名前と型署名が同一の場合にのみ発生します。 それ以外の場合、2 つのメソッドは単純にオーバーロードされます。

Java SE5で登場したアノテーション @オーバーライド;。 メソッドをオーバーライドする必要がある場合は、@Override を使用します。メソッドをオーバーライドせずに誤ってオーバーロードすると、コンパイラーはエラーをスローします。

Java では、1 つのクラスからのみ継承できます。

カプセル化

コンピュータ サイエンスにおいて、カプセル化 (ラテン語: en capsula) とは、データや関数を 1 つのオブジェクトにパッケージ化することです。

Java におけるカプセル化の基礎はクラスです。 カプセル化とは、オブジェクトのフィールドがクライアントから直接アクセスできないことを意味します。オブジェクトのフィールドは、外部からの直接アクセスから隠されます。 カプセル化は、オブジェクトがそのデータへのアクセスを制御できるようにすることで、オブジェクトのデータを不要なアクセスから保護します。

アクセス修飾子

クラスを記述するときは、アクセス修飾子が使用されます。 アクセス修飾子視点から見ることができる カプセル化それで、そして 継承。 カプセル化の観点から見ると、アクセス修飾子を使用すると、外部からのクラス メンバーへの不要なアクセスを制限できます。

クラスのパブリック メンバーは、他のクラスで使用できる外部機能を構成します。 外部機能から独立したメンバーは通常、実装の詳細にすぎず本質的に普遍的ではない補助メソッドと同様に、プライベートとして宣言されます。 クラスの実装を非表示にすることで、システムの他のコンポーネントのコードを変更せずに、別のクラスの内部ロジックを変更できます。

クラスのプロパティへのアクセスは、そのメソッドを通じてのみ使用することをお勧めします (原則 クラス、「POJO」)を使用すると、フィールド値を検証できます。プロパティへの直接アクセスは追跡が非常に困難であるため、プログラムの実行段階で誤った値が割り当てられる可能性があります。 この原則はカプセル化されたデータの管理を指しており、データの保存方法を迅速に変更できるようになります。 データがメモリではなくファイルまたはデータベースに保存されている場合、この機能をシステムのすべての部分に導入するのではなく、1 つのクラスのいくつかのメソッドのみを変更する必要があります。

カプセル化の原理を使用して作成されたプログラム コードは、デバッグが容易です。 関心のあるオブジェクトのプロパティをいつ、誰が変更したかを調べるには、このオブジェクトのプロパティにアクセスするオブジェクトのメソッドにデバッグ情報出力を追加するだけで十分です。 オブジェクト プロパティへの直接アクセスを使用する場合、プログラマは、対象のオブジェクトが使用されているコードのすべてのセクションにデバッグ情報出力を追加する必要があります。

簡単なロボットの説明の例

public class Robot ( private double x = 0; // 現在の X 座標 private double y = 0; // 現在の Y 座標 private double course = 0; // 現在のコース (度単位) public double getX() ( return x; ) public void setX(double x) ( this.x = x; ) public double getY() ( return y; ) public void setY(double y) ( this.y = y; ) public double getCourse() ( return course; ) // コースの決定 public void setCourse(double course) ( this.course = course; ) // 距離への移動 public void forward(int distance) ( // オブジェクトフィールドへのアクセス X x = x + distance * Math.cos ( course / 180 * Math.PI); // オブジェクトフィールド Y へのアクセス y = y + distance * Math.sin(course / 180 * Math.PI ) // ロボットの座標を出力 public void printCooperatives() ( System.out ); .println(x + "," + y);

提示されたロボットの例では、以下で始まる一連のメソッドが使用されています。 セットそして 得る。 このペアのメソッドは、セッター/ゲッターと呼ばれることがよくあります。 これらのメソッドは、オブジェクトのフィールドにアクセスするために使用されます。 メソッド名は、大文字で始まるフィールド名で終わります。

メソッド内 セット値を仮パラメータを介してプロシージャに渡します。 プロシージャ コードでは、キーワードを使用してオブジェクト/クラス変数に値を割り当てます。 これ.

This.course = コース ...

キーワードの使用 これ必要だから 仮パラメータの名前はオブジェクト変数の名前と一致します。 名前が違っていれば可能性はありますが、 これ使ってはいけません。

ポリモーフィズム

ポリモーフィズムは、継承やカプセル化と並ぶオブジェクト指向プログラミングの基本概念の 1 つです。 ポリモーフィズムという言葉はギリシャ語に由来し、「多くの形式を持つ」という意味です。 オブジェクト指向プログラミングに関連してポリモーフィズムが何を意味するかを理解するには、グラフィック プリミティブのセットの形式で多数のクラスを使用する必要があるベクトル グラフィック エディターを作成する例を考えてみましょう。 四角, ライン, , 三角形、など。 これらの各クラスにはメソッドが定義されている必要があります 描く対応するプリミティブを画面上に表示します。

明らかに、画像を表示するには、画面に表示する必要があるすべてのプリミティブを順番に反復処理し、それぞれのプリミティブで描画メソッドを呼び出すコードを記述する必要があります。

ポリモーフィズムに詳しくない人は、プリミティブ型ごとに個別の配列を作成し、各配列の要素を順番に反復処理して各要素の描画メソッドを呼び出すコードを作成する可能性が高くなります。 結果はおよそ次のコードになります。

// グラフィック プリミティブの配列を定義します Square s = new Square ; 行 l = 新しい行; サークル c = 新しいサークル ; 三角形 t = 新しい三角形; // すべての配列に適切なオブジェクトを入力します。 。 。 // 配列のすべてのセルを反復するループ。 for (int i = 0; i< s.length; i++){ // вызов метода draw() в случае, если ячейка не пустая. if (s[i] != null) s.draw(); } for(int i = 0; i < l.length; i++){ if (l[i] != null) l.draw(); } for(int i = 0; i < c.length; i++){ if (c[i] != null) c.draw(); } for(int i = 0; i < t.length; i++){ if (t[i] != null) t.draw(); }

上記で記述されたコードの欠点は、各タイプのプリミティブを表示するためにほぼ同一のコードが重複することです。 また、グラフィック エディターがさらに最新化され、新しいタイプのグラフィック プリミティブ (テキスト、スターなど) を描画する機能が追加されるため、このアプローチでは既存のコードを変更し、新しい配列の定義を追加する必要があることも不便です。それに含まれる要素処理も同様です。

ポリモーフィズムを使用すると、そのような機能の実装を大幅に簡素化できます。 まず最初に、すべてのクラスに共通の Shape 親クラスを作成しましょう。

パブリック クラス Shape ( public voiddraw() ( System.out.println("Stub"); ) )

この後、Square、Line、Circle、Triangle などのさまざまな子孫クラスを作成します。

パブリック クラス Point extends Shape ( public voiddraw() ( System.out.println("Square"); ) ) public class Line extends Shape ( public voiddraw() ( System.out.println("Line"); ) ) public class Circle extends Shape ( public voiddraw() ( System.out.println("Circle"); ) ) public class Triangle extends Shape ( public voiddraw() ( System.out.println("Triangle"); ) )

子孫では、draw メソッドをオーバーライドしました。 その結果、図に示すようなクラス階層が得られました。

次に、ポリモーフィズムの驚くべき機能を確認してみましょう。

// Shape 配列の定義と初期化 a = new Shape (new Shape(), new Triangle(), new Square(), new Circle()); // 配列要素をループします for(int i = 0; i< a.length; i++) { a[i].draw(); }

次の行がコンソールに出力されます。

空白の三角形四角形円

このようにして、各子孫クラスは、親 Shape クラスから描画メソッドを呼び出すのではなく、独自の描画メソッドを呼び出します。

ポリモーフィズムは型理論の規定であり、これによれば、名前 (変数など) は、共通の親を持つ異なるクラスのオブジェクトを表すことができます。 したがって、多態性名で示されるオブジェクトは、特定の一般的な一連の操作に対して独自の方法で応答できます。

メソッドのオーバーロード、オーバーロード

手続き型プログラミングには、OOP で考慮されているメカニズムとは異なるポリモーフィズムの概念もあります。 手続き型ポリモーフィズムは、同じ名前で渡されるパラメータの数や型が異なる複数のプロシージャまたは関数を作成できる可能性を意味します。 このような同名の関数をオーバーロードと呼び、その現象自体をオーバーロードと呼びます。 関数のオーバーロードも OOP に存在し、メソッドのオーバーロードと呼ばれます。 Java 言語でのメソッドのオーバーロードの使用例は、PrintWriter クラスです。これは、特にメッセージをコンソールに出力するために使用されます。 このクラスには、入力パラメータの型や数が異なる多くの println メソッドがあります。 ここではそのほんの一部を紹介します。

Void println() // 新しい行に移動 void println(boolean x) // ブール変数の値 (true または false) を出力します void println(String x) // 文字列 (テキスト パラメータの値) を出力します

遺伝子多型は、遺伝子の長期的な多様性が存在するが、集団内で最も希少な遺伝子の頻度が 1 パーセントを超えている状態です。 その維持は、遺伝子の絶え間ない突然変異と、それらの絶え間ない組換えによって起こります。 科学者が行った研究によると、遺伝子の組み合わせは数百万通りある可能性があるため、遺伝子多型が広く普及しています。

大量の在庫

新しい環境への集団のより良い適応は、多型の大量供給に依存しており、この場合、進化ははるかに速く起こります。 従来の遺伝的手法を使用して多型対立遺伝子の全体数を推定することは現実的ではありません。 これは、遺伝子型内に特定の遺伝子が存在することが、その遺伝子によって決定される異なる表現型特性を持つ個体を交雑することによって実現されるという事実によるものです。 特定の集団のどの部分が異なる表現型を持つ個体で構成されているかがわかれば、特定の形質の形成が依存する対立遺伝子の数を決定することが可能になります。

すべてはどのように始まったのでしょうか?

遺伝学は前世紀の60年代に急速に発展し始め、ゲル中の酵素が使用され始め、それにより遺伝子多型を決定することが可能になりました。 この方法は何ですか? タンパク質が電場内で移動するのはその助けを借りて行われます。電場は、移動するタンパク質のサイズ、その構成、およびゲルのさまざまな部分の総電荷に依存します。 その後、出現したスポットの位置と数に応じて、特定された物質が特定されます。 集団内のタンパク質多型を評価するには、約 20 以上の遺伝子座を調べる価値があります。 次に、数学的手法を使用して、ホモ接合体とヘテロ接合体の数と比率が決定されます。 研究によると、一部の遺伝子は単型である可能性がある一方、他の遺伝子は異常に多型である可能性があります。

ポリモーフィズムの種類

ポリモーフィズムの概念は非常に幅広く、過渡的なバリアントとバランスの取れたバリアントが含まれます。 これは遺伝子の選択値と、集団に圧力をかける自然選択に依存します。 さらに、遺伝的および染色体的なものである可能性もあります。

遺伝子および染色体多型

遺伝子多型は体内で複数の対立遺伝子によって表されます。その顕著な例は血液です。 染色体は、異常によって発生する染色体内の差異を表します。 ただし、異色領域には違いがあります。 機能障害や死につながる病理が存在しない場合、そのような突然変異は中立です。

遷移多態性

移行多型は、集団内でかつて一般的であった対立遺伝子が、キャリアにより高い適応性をもたらす別の遺伝子に置き換えられるときに発生します (多重対立遺伝子とも呼ばれます)。 特定の品種では、遺伝子型の割合に方向性の変化があり、これにより進化が発生し、そのダイナミクスが実行されます。 産業メカニズムの現象は、過渡的な多態性を特徴付ける良い例と言えます。 それが何であるかを示すのは、産業の発展とともに羽の白色が暗色に変化した単純な蝶です。 この現象はイギリスで観察され始め、80種以上の蝶が淡いクリーム色の花から濃い色の花に変わりました。この現象は、産業の急速な発展により1848年以降にマンチェスターで初めて注目されました。 すでに 1895 年には、95% 以上の蛾の羽が暗い色になりました。 このような変化は、木の幹がより煙っぽくなり、明るい色の蝶がツグミやコマドリの格好の餌食になっているという事実と関連しています。 この変化は、変異型メラニン対立遺伝子によって起こりました。

バランスの取れた多態性

「バランスの取れた多型」の定義は、安定した環境条件にある集団において、さまざまな形態の遺伝子型の数値比に変化がないことを特徴とします。 これは、世代が変わっても比率は同じままですが、一定の値内でわずかに変動する可能性があることを意味します。 過渡的なバランスの取れたポリモーフィズムと比較して、それは何でしょうか? それは主に静的な進化のプロセスです。 1940 年の I. I. Shmalhausen は、これに平衡異形性という名前も付けました。

バランスの取れたポリモーフィズムの例

バランスの取れた多型の明確な例は、多くの一夫一婦制動物における 2 つの性別の存在です。 これは、それらが同等の選択的利点を持っているという事実によるものです。 1 つの集団内のそれらの比率は常に等しいです。 集団内に一夫多妻制が存在する場合、両性の代表者の選択比が破壊される可能性があり、その場合、一方の性の代表者は完全に破壊されるか、異性の代表者よりも大幅に生殖から排除される可能性があります。

別の例は、ABO システムによる血液型です。 この場合、異なる集団における異なる遺伝子型の頻度は異なる可能性がありますが、同時にその恒常性は世代ごとに変わりません。 簡単に言うと、どの遺伝子型も他の遺伝子型に対して選択的優位性を持ちません。 統計によると、最初の血液型を持つ男性は、他の血液型のより強い性別のメンバーよりも平均寿命が長いです。 これに伴い、最初のグループが存在する場合は十二指腸潰瘍を発症するリスクが高くなりますが、穿孔する可能性があり、支援が遅れると死に至る可能性があります。

遺伝子バランス

この脆弱な状態は、発生の結果として集団内で混乱する可能性があり、それらは特定の頻度で各世代で発生するはずです。 研究により、止血系の遺伝子の多型が非常に重要であることが示されており、その解読により、進化の過程がこれらの変化を促進するのか、逆にそれらを阻止するのかが明らかになる。 特定の集団における変異プロセスの過程を追跡すれば、その適応の価値を判断することもできます。 突然変異が選択プロセス中に除外されず、その拡散に対する障害がない場合、この値は 1 に等しくなります。

ほとんどの場合、そのような遺伝子の値は 1 未満であることが示され、そのような突然変異体が繁殖できない場合には、すべてが 0 になります。この種の突然変異は自然選択の過程で一掃されますが、これは実際に行われます。同じ遺伝子の繰り返しの変化を排除するものではなく、選択によって行われる除去を補います。 その後、平衡に達し、突然変異遺伝子が出現したり、逆に消滅したりすることがあります。 これにより、バランスの取れたプロセスが実現します。

何が起こっているかを明確に特徴付けることができる例は、鎌状赤血球貧血です。 この場合、ホモ接合状態にある優性変異遺伝子が生物の早期死に寄与します。 ヘテロ接合性の生物は生き残りますが、マラリア疾患にかかりやすくなります。 鎌状赤血球貧血遺伝子の平衡多型は、この熱帯病の分布地域で追跡できます。 このような集団では、ホモ接合体 (同じ遺伝子を持つ個人) が排除され、ヘテロ接合体 (異なる遺伝子を持つ個人) が有利に選択されます。 集団の遺伝子プール内でマルチベクター選択が行われるため、遺伝子型は各世代で維持され、環境条件に対する生物の適応性が向上します。 鎌状赤血球貧血遺伝子の存在に加えて、多型を特徴付ける他のタイプの遺伝子が存在します。 これは何を与えるのでしょうか? この質問に対する答えは、ヘテローシスと呼ばれる現象になります。

ヘテロ接合性突然変異と多型

ヘテロ接合性多型は、劣性突然変異が存在する場合でも、それが有害である場合でも、表現型の変化が起こらないようにします。 しかし同時に、それらは集団内に高レベルまで蓄積する可能性があり、有害な優性変異を超える可能性があります。

進化の過程

進化のプロセスは継続的であり、その必然的な条件は多態性です。 これは、特定の個体群がその生息地に常に適応していることを示しています。 同じグループ内に住んでいる性別の異なる生物は、ヘテロ接合状態になることがあり、何年にもわたって世代から世代へと伝達されます。 これに加えて、遺伝的多様性が非常に大きいため、表現型の発現が見られない可能性があります。

フィブリノーゲン遺伝子

ほとんどの場合、研究者はフィブリノーゲン遺伝子多型を虚血性脳卒中発症の前兆と考えています。 しかし現在、遺伝的要因と後天的要因がこの病気の発症に影響を与える可能性があるという問題が表面化しつつあります。 このタイプの脳卒中は脳動脈の血栓症によって発症しますが、フィブリノーゲン遺伝子の多型を研究することで、どの疾患を予防できるかに影響を与える多くのプロセスを理解することができます。 現時点では、科学者は遺伝的変化と生化学的血液パラメーターの間の関連性を十分に研究していません。 研究が進めば、病気の経過に影響を与えたり、経過を変えたり、あるいは発症の初期段階で単に予防したりすることが可能になるでしょう。

ポリモーフィズム同じ組成の物質が、外部条件に基づいて、異なる構造を持ついくつかの結晶形 (多形変化) で存在する能力です (単純な物質の場合、この現象は同素性と呼ばれることもあります)。

多形性の現象は、1821 年にドイツの化学者兼鉱物学者 E. Mitscherlich によって初めて発見されました。 多形性は自然界に広く存在し、結晶物質の特徴的な特性の 1 つです。 したがって、内部構造が異なる多型修飾は、異なる特性を持ちます。 したがって、多態性の研究は実践にとって非常に重要です。

多形性を決定する外部条件には、まず温度と圧力が含まれます。したがって、各多形性修飾には、熱力学的に安定 (平衡) 状態で存在し、その外では安定でなくなる独自の温度と圧力の範囲があります。それは準安定状態で存在することができます。 非平衡状態。

炭素、ケイ素、リン、鉄、その他の元素はさまざまな多形変化で存在します。 同じ物質の異なる修飾の物理的特性は大きく異なる場合があります。 たとえば、ダイヤモンドの形 (立方晶系) またはグラファイトの形 (六方晶系) で結晶化する炭素の修飾は、組成の同一性にもかかわらず、物理的性質が互いに大きく異なります。 多形変化が構造の小さな変化を伴う場合、物質の物理的特性はわずかに変化します。 それぞれの特定の物質には 2 つ、3 つ以上の多型修飾が必要です。 さまざまな変更は通常ギリシャ文字で示されます α, β, γ など。最初の文字は通常、高温でも安定な修飾を指します。

高温での修飾が低温での修飾に変化すると、通常、結晶の元の外形は維持されますが、物質の内部構造は変化します。 新たに形成された結晶格子構造に対応しない外部形態の保存は、パラモルフォシスと呼ばれます。 パラモルフォーゼは自然界で知られている β -クォーツ(三方対称)によると α ・石英(六方晶系対称)、アラゴナイト(斜方晶系対称)上の方解石CaCO 3 (三方晶系対称)など。

多形性変換中に起こる構造変化の性質に関係なく、それらは鏡像異方性 (可逆的) 変換とモノトロピック (不可逆的) 変換の 2 つのタイプに区別されます。

ある修飾から別の修飾への可逆的な変換は、一定の圧力と特定の転移温度 (点) で実行されます。この温度では、これらの修飾は平衡状態にあります。 同様に安定であり、エナンチオトロピックと呼ばれます。 これは次のように概略的に示すことができます。

α↔β↔液体

それらの。 α → β 転移はエナンチオトロピックです。 エナンチオトロピック多形変換の例は、SiO 2 の多形形間の変換です。

ポリモーフィズム - 概念とタイプ。 カテゴリ「ポリモーフィズム」2015、2017-2018の分類と特徴。

  • - 個人の多態性

    人間の個体は、多くの共通の特性を持っていますが、同時に種の性質という点では互いに同一ではありません。 彼らは身体的、精神的、社会的に互いに異なります。 その違いとは、身長、肌や髪の色、外見、歩き方などです。


  • - 破壊的では、極端なタイプの保存と中間的なタイプの削除が優先されます。 多態性の保存と強化につながります。

  • - 人類の種内分化。 人類の遺伝的多型の表現としての人種。 人類の種の統一。

    人類の種内分化:ホモ・サピエンスの出現以来、人間の社会性が人間の本質となり、生物学的進化は変化し、広範な遺伝的多型の出現として現れました。 レベルでの遺伝的多様性…。