こんにちは!Java がなぜそのように設計されているのか疑問に思ったことはありますか? クラスを作成するという意味では、それらに基づいて、オブジェクト、クラスにはメソッドなどが含まれます。しかし、なぜプログラムが他のものではなくクラスとオブジェクトで構成されるような言語の構造になっているのでしょうか? なぜ「オブジェクト」という概念が発明され、前面に押し出されたのでしょうか?すべての言語がこのように機能するのでしょうか? そうでない場合、Java にどのような利点がありますか? ご覧のとおり、たくさんの質問があります :) 今日の講義でそれぞれに答えてみましょう。
Kristen Nygaard と Ole Johan Dahl - Simula のクリエイター
Simula はプログラミング標準からすると古い言語であるように見えますが、Java との「家族」的な関係は肉眼で見ることができます。おそらく、そこに書かれたコードを読んで、それが何をするのかを一般的な言葉で説明するのは簡単でしょう :)
OOP の原則:
オブジェクト指向プログラミング (OOP) とは何ですか
もちろん、Java がオブジェクトとクラスで構成されているのには理由があります。これは作成者の気まぐれではなく、さらには発明でもありません。オブジェクトに基づいた言語は他にもたくさんあります。最初のそのような言語は Simula と呼ばれ、1960 年代にノルウェーで発明されました。とりわけ、Simula では「クラス」と「メソッド」の概念が導入されました。Begin
Class Rectangle (Width, Height); Real Width, Height;
Begin
Real Area, Perimeter;
Procedure Update;
Begin
Area := Width * Height;
OutText("Rectangle is updating, Area = "); OutFix(Area,2,8); OutImage;
Perimeter := 2*(Width + Height);
OutText("Rectangle is updating, Perimeter = "); OutFix(Perimeter,2,8); OutImage;
End of Update;
Update;
OutText("Rectangle created: "); OutFix(Width,2,6);
OutFix(Height,2,6); OutImage;
End of Rectangle;
Rectangle Class ColouredRectangle (Color); Text Color;
Begin
OutText("ColouredRectangle created, color = "); OutText(Color);
OutImage;
End of ColouredRectangle;
Ref(Rectangle) Cr;
Cr :- New ColouredRectangle(10, 20, "Green");
End;
コード例は記事「Simula - OOP の 50 年」から引用しています。ご覧のとおり、Java とその祖先は互いにそれほど違いはありません :) これは、Simula の登場が新しい概念であるオブジェクト指向プログラミングの誕生を示したという事実によるものです。Wikipedia では、OOP について次の定義を示しています。オブジェクト指向プログラミング (OOP) は、プログラムをオブジェクトのコレクションとして表現することに基づいたプログラミング方法論です。各オブジェクトは特定のクラスのインスタンスであり、クラスは継承階層を形成します。私の意見では、それは非常に成功しています。あなたは最近 Java を学習し始めましたが、その中には馴染みのない単語はほとんどありません :) 現在、OOP は最も一般的なプログラミング手法です。Java 以外にも、OOP 原則は聞いたことがある多くの一般的な言語で使用されています。これらは、C++ (コンピューター ゲーム開発者によって積極的に使用されています)、Objective-C と Swift (Apple デバイス用のプログラムを作成します)、Python (機械学習で最も需要が高い)、PHP (最も人気のある Web 開発言語の 1 つ)、 JavaScript (JavaScript で何ができないかを簡単に言います) やその他多数。実際のところ、OOP の「原則」とは何でしょうか? さらに詳しくお話しましょう。
OOP の原則
これが基本です。オブジェクト指向プログラミング パラダイムを形成する 4 つの主な機能。それらを理解することが、プログラマーとして成功するための鍵です。原則 1. 継承
幸いなことに、あなたは OOP の原則の一部をすでによく理解しています。:) 私たちはすでに講義で何度か継承に遭遇しており、それに取り組む時間もありました。 継承は、既存の (親) クラスに基づいて新しいクラスを記述できるようにするメカニズムです。この場合、親クラスのプロパティと機能が新しいクラスに借用されます。継承はなぜ必要であり、継承によってどのようなメリットがあるのでしょうか? まずはコードの再利用です。親クラスに記述されたフィールドやメソッドは、子孫クラスでも使用できます。すべてのタイプの自動車に 10 個の共通フィールドと 5 個の同一のメソッドがある場合、それらを親クラスに置くだけで済みますAuto
。子孫クラスでも問題なく使用できます。確かな利点: 量的 (コードが少なくなる) と、結果として定性的 (クラスがはるかにシンプルになる) の両方。同時に、継承メカニズムは非常に柔軟であり、子孫に欠落している機能 (特定のクラスに固有の一部のフィールドや動作) を個別に追加できます。一般的に、普通の生活と同じように、私たちは皆、ある意味では両親に似ていますが、いくつかの点では両親とは異なります:)
原則 2. 抽象化
これは非常に単純な原理です。抽象化とは、オブジェクトの主な最も重要な特徴を強調することを意味し、逆も同様で、二次的で重要ではない特徴を破棄することを意味します。車輪の再発明ではなく、クラスに関する古い講義の例を思い出してみましょう。会社の従業員のファイル キャビネットを作成しているとします。従業員オブジェクトを作成するために、 クラス を作成しましたEmployee
。企業ファイルに記載する際にどのような特徴が重要ですか? 氏名、生年月日、社会保障番号、納税者番号。しかし、このタイプのカードでは、彼の身長、目、髪の色が必要になる可能性は低いです。会社は従業員に関するこの情報を必要としません。そこで、クラスにはEmployee
変数String name
、int age
、int socialInsuranceNumber
を設定しint taxNumber
、目の色など不要な情報は捨てて抽象化します。しかし、代理店向けに写真モデルのカタログを作成すると、状況は劇的に変わります。ファッションモデルを説明するには、身長、目の色、髪の色が非常に重要ですが、TIN 番号は必要ありません。したがって、クラス内に変数、、Model
を作成します。 String height
String hair
String eyes
原則 3: カプセル化
私たちはすでにそれに遭遇しています。Java におけるカプセル化とは、データへのアクセスとその変更機能を制限することを意味します。ご覧のとおり、これは「カプセル」という単語に基づいています。この「カプセル」には、誰にも変更されたくない重要なデータが隠されています。人生における簡単な例。あなたには姓と名があります。あなたが知っている人は皆、彼らを知っています。しかし、彼らはあなたの姓名を変更するアクセス権を持っていません。このプロセスはパスポート管理局で「カプセル化」されていると言えるかもしれません。そこでは姓名を変更できるだけで、変更できるのはあなただけです。他の「ユーザー」はあなたの姓名への読み取り専用アクセス権を持っています:) 別の例は、あなたのアパートのお金です。部屋の真ん中に目立つところに置いておくのは得策ではありません。どの「ユーザー」(あなたの家を訪れる人)も、あなたのお金の番号を変更することができます。それらをピックアップ。それらを金庫にカプセル化した方がよいでしょう。あなただけが特別なコードを使用してアクセスできます。すでに扱ったことがあるカプセル化の明らかな例としては、アクセス修飾子 (private
などpublic
) とゲッターセッターがあります。age
クラスフィールドがカプセル化されていない場合はCat
、誰でも次のように記述できます。
Cat.age = -1000;
また、カプセル化メカニズムにより、セッター メソッドを使用してフィールドを保護することができage
、年齢が負の数にならないようにチェックを入れることができます。
原則 4. ポリモーフィズム
ポリモーフィズムは、複数の型を同じ型であるかのように扱う機能です。この場合、オブジェクトの動作は、オブジェクトが属するタイプに応じて異なります。少し複雑に思えますか? 今すぐそれを理解しましょう。最も単純な例、動物を見てみましょう。Animal
1 つのメソッド -voice()
と、その子孫の 2 つ -Cat
と を含むクラスを作成しましょうDog
。
public class Animal {
public void voice() {
System.out.println("Voice!");
}
}
public class Dog extends Animal {
@Override
public void voice() {
System.out.println("Bow-wow!");
}
}
public class Cat extends Animal {
@Override
public void voice() {
System.out.println("Meow!");
}
}
次に、リンクを作成しAnimal
、それにオブジェクトを割り当ててみましょうDog
。
public class Main {
public static void main(String[] args) {
Animal dog = new Dog();
dog.voice();
}
}
どのメソッドが呼び出されると思いますか? Animal.voice()
またはDog.voice()
?クラスメソッドは次のように呼ばれますDog
: Woof-woof! 参照を作成しましたAnimal
が、オブジェクトは次のように動作しますDog
。必要に応じて、猫、馬、その他の動物のように振る舞うこともできます。主なことは、一般的な型の参照をAnimal
特定の子孫クラスのオブジェクトに割り当てることです。すべての犬は動物であるため、これは論理的です。これが、「オブジェクトはその型に応じて異なる動作をする」と言ったときの意味です。オブジェクトを作成する場合Cat
-
public static void main(String[] args) {
Animal cat = new Cat();
cat.voice();
}
このメソッドはvoice()
「ニャー!」を出力します。「複数のタイプを同じタイプであるかのように扱える能力」とはどういう意味ですか? これも非常に簡単です。動物のための美容室を作成していると想像してみましょう。私たちのヘアサロンはすべての動物をカットできる必要があるため、カットする動物という shear()
パラメーターを使用してメソッド (「カット」)を作成します。Animal
public class AnimalBarbershop {
public void shear(Animal animal) {
System.out.println("The haircut is ready!");
}
}
これで、shear
オブジェクトCat
とオブジェクトの両方をメソッドに渡すことができるようになりましたDog
。
public static void main(String[] args) {
Cat cat = new Cat();
Dog dog = new Dog();
AnimalBarbershop barbershop = new AnimalBarbershop();
barbershop.shear(cat);
barbershop.shear(dog);
}
以下にその明確な例を示します。このクラスは、AnimalBarbershop
型を同じ型であるかのCat
ように処理します。Dog
同時に、彼らはCat
異なるDog
行動をし、声の使い方も異なります。
GO TO FULL VERSION