Chapter 11. たけいせい

51005 ワード

たけいせい


オブジェクト指向の概念では、多形性は「複数のタイプを1つのタイプとして扱うことができる技術」を意味し、Javaでは複数のタイプのオブジェクトを1つのタイプの参照変数として参照することができる.すなわち、親タイプの参照変数は、子クラスのインスタンスを参照することができる.
作成したインスタンスを処理するには、インスタンスタイプに一致するタイプの参照変数のみを使用し、関係を継承するクラスは、サブクラスタイプのインスタンスを作成するときに親タイプの参照変数を使用します.
Parent.java
01 package poly.sample;
02
03 public class Parent {
04     protected int num;
05
06     public void display() {
07         System.out.println("부모 클래스 메소드");
08     }
09 }
polysample.Child.java
01 package poly.sample;
02
03 public class Child extends Parent {
04     private int x = 100;
05
06     public Child() { }
07
08     public void out() {
09         System.out.println("부모의 protected num vlfem : " + num);
10         System.out.println("자식 클래스 메소드");
11     }
12
13     @Override
14     public void display() {     
15         System.out.println("상속 받아 재정의한 메소드");
16     }
17 }
test.poly.TestPolymorphism.java
01 package test.poly;
02
03 import poly.sample.*;
04
05 public class TestPolymorphism {
06     public static void main(String[] args) {
07         Child c = new Child();
08         c.display();
09         c.out();
10         System.out.println();
11
12         Parent p = new Child();
13         p.display(); // Overriding 된 perent 멤버이므로 접근 가능
14         // p.out(); // 컴파일 에러. Parent 타입으로 Child 멤버에 접근 할 수 없음.
15     }
16 }
------
100
상속 받아 재정의한 메소드
자식 클래스 메소드
자식 클래스 메소드
Child c = new Child();Parent p = new Child();c.x->アクセス可能p.x->サブオブジェクトメンバー、アクセス不可.c.display(); -> アクセス可能p.display();->スーパーサブオブジェクトにアクセスできるメソッドc.out();->アクセス可能p.out;->サブオブジェクトメンバーにアクセスできません

パラメータの多形性


メソッドのパラメータに多形性を適用すると、同じメソッドの過負荷数を減らすことができます.
メソッドパラメータのオーバーロードの例を見てみましょう.
test.poly.TestPolyArgument.java
01 package test.poly;
02
03 public class TestPolyArgument {
04     public static void main(String[] args) {
05         Buyer b = new Buyer();
06         b.buy(new Chair());
07         b.buy(new Desk());
08     }
09 }
10
11 class Fumiture {
12     private int price; // 제품 가격
13     public Fumiture(int price) {
14         this.price = price;
15     }
16 }
17
18 class Chair extends Fumiture {
19     public Chair() {
20         super(100); // 부모 클래스의 생성자 호출
21     }
22     @Override
23     public String toString() {
24         return "Chair";
25     }
26 }
27
28 class Desk extends Fumiture {
29     public Desk() {
30         super(200);
31     }
32
33     @Override
34     public String toString() {
35         return "Desk";
36     }
37 }
38
39 class Buyer {
40     private int money = 500;
41
42     public void buy(Fumiture f) {
43         if(money < f.price) {
44             System.out.println("잔액부족!");
45             return;
46         }
47         money -= f.price;
48         System.out.println(f + "구매성공! 잔액 : " + money + " 만원");
49      }
50 }
------
Chair 구매성공! 잔액 : 400Desk 구매성공! 잔액 : 200
例のクラスBuyerのbuyメソッドに注意してください.パラメータのタイプとして、Fumiture変数fを受け入れています.親タイプFumitureのため、サブクラスChairとDeskはいずれも1つの方法を使用できます.Chair、Deskをパラメータとして使用する場合は、次の方法が必要になります.
01 class Buyer
02     int money = 500;
03     // Chair 구매메소드
04     void buy(Chair c) {
05         if(money < c.price) {
06             System.out.println("잔액부족!");
07             return;
08         }
09         money -= c.price;
10         System.out.println(c + " 구매성공! 잔액 : " + money + " 만원");
11     }
12     // Desk 구매 메소드
13     void buy(Desk d) {
14         if(money < d.price) {
15             System.out.println("잔액부족!");
16             return;
17         }
18         money -= d.price;
19         System.out.println(d + " 구매성공! 잔액 : " + money + " 만원");
20     }
21 }

instanceof演算子


パラメータタイプのクラスで親クラスを宣言して、サブクラスで使用可能なすべてのクラスが各クラスに対して異なる操作を実行する機能が必要な場合は、instanceof演算子を使用して各オブジェクトの実際のタイプを理解できます.
主に条件式で使用され、boolean値を返す演算子instanceofの構文は次のとおりです.
if(참조변수 instanceof 검사할 타입명(클래스명) { }
instanceofの演算結果がtrueの場合、チェックのタイプを使用して変換できることを示します.
test.instance.TestInstanceOf.java
01 package test.instance;
02
03 public class TestInstancOf {
04     public static void main(String[] args) {
05         Chair c = new Chair();
06
07         if(c instanceof Chair) {
08             System.out.println("Chair 객체입니다.");
09         }
10
11         if(c instanceof Fumiture) {
12             System.out.println("Fumiture 객체입니다.");
13         }
14
15         if(c instanceof Object) {
16             System.out.println("Object 객체입니다.");
17         }
18
19         System.out.println("실제 타입 : " + c.getClass().getName());
20     }
21 }
22
23 class Fumiture { }
24
25 class Chair extends Fumiture { }
------
Chair 객체입니다.
Fumiture 객체입니다.
Object 객체입니다.
실제 타입 : Chair
生成されたinstanceはChairタイプであるが,ObjectタイプとFutureタイプのinstanceof演算結果ともにtrue値が得られた.ChairはFumitureクラスを継承していますが、すべてのクラスはObjectクラスのサブクラスです.つまり、チェックしたタイプ(親)に変換できます.
.getClass().getName());参照変数が指すインスタンスのクラス名を文字列として返すObjectクラスのメソッドです.すべてのクラスがObjectクラスを継承しているため、このメソッドを使用できます.
パラメータのタイプから親クラスを取得し、instanceof演算でどのサブクラスタイプをチェックし、実際のクラスタイプに変換します.その場合は、明確に角を選びます.ロールを選択すると、親タイプで使用できない子タイプ(オブジェクトの実際のタイプ)固有のメソッドを使用できます.
01 class Buyer {
02     int money = 500;
03     void buy(Fumiture f) {
04         if(f instanceof Chair) {
05             Chair c = (Chair)f;
06             c.chairMethod(); // Chair 클래스에 선언된 메소드
07         }
08         else if(f instanceof Desk) {
09             Desk d = (Desk)f;
10             d.deskMethod(); // Desk 클래스에 선언된 메소드
11         }
12     }
13 }

抽象クラス


抽象クラスとは、宣言されたが実装されていない未完了メソッド(抽象メソッド)が含まれている場合、クラスの前にabstractキーを付ける未完了クラスを指します.
クラスとしてオブジェクトを作成することはできませんが、新しいクラスを作成すると親クラスに移動し、継承されたクラスにルールを提供するための新しいクラスを作成するテンプレートになります.
public abstract class 클래스이름 {
    // 필드, 생성자, 메소드 작성
    // 미완성된 추상 메소드 선언
}
クラスの前にabstractキーを付けると、オブジェクトを作成できない以外は抽象クラスが生成されます.これは通常のクラスと変わりません.

抽象メソッド


メソッドは、アクセス制御者、戻りタイプ、名前、パラメータからなる宣言セクションとメソッドの機能を定義する実装セクションに分けられます.抽象メソッドには実装部分("")はありません.
접근제한자 abstract 리턴타입 함수이름 ();
抽象クラスで抽象メソッドを提供する理由は、抽象クラスを継承して作成された子孫クラスが、最初の宣言と同じメソッドを使用するためです.実施部を編成しなければならないため、強制性がある.

抽象クラスの作成


inherit.sample.Person.java
01 package inherit.sample;
02
03 public abstract class Person {
04     private String name;
05
06     public Person() { }
07     public void setName(String name) { this.name = name; }
08     public String getName() { return name; }
09     public abstract void out(); 
10 }
Student.java
01 package inherit.sample
02
03 public class Student extends Person {
04     private String subject
05
06     public Student () { super(); }
07     public Student(String subject) {
08         super();
09         this.subject = subject;
10     }
11
12     public Student(String name, String subject) {
13         super(name);
14         this.subject = subject;
15     }
16
17     @Override
18     public void out() { // 상속받은 부모의 추상 메소드는 반드시 오버라이딩 해야 함
19         System.out.println(getName() + " 학생입니다");
20         System.out.println(subject + "를 수강합니다");
21     }
22 }  
Professor.java
01 package inherit.sample;
02
03 public class Professor extends Person {
04     private String major;
05
06     public Professor() { super(); }
07
08     public Professor(String major) {
09         super();
10         this.major = major;
11     }
12
13     public Professor(String name, String major) {
14         super(name);
15         this.major = major;
16     }
17
18     @Override
19     public void out() {
20         System.out.println(getName() + " 교수입니다");
21         System.out.println(major + "를 전공합니다");
22     );
23 }
inherit.test.AbstractEx.java
01 package inherit.java
02
03 public class AbstractEx {
04     public static void main(String[] args) {
05         Student stu = new Student("홍길동", "자바");
06         Professor prof = new Professor("김춘추", "컴퓨터과학");
07
08         stu.out();
09         prof.out();
10     }
11 }
------
홍길동 학생입니다
자바를 수강합니다
김춘추 교수입니다
컴퓨터과학를 전공합니다

インターフェイス


抽象メソッドのみからなる抽象クラスをインタフェース(interface)に分割し、抽象クラスに比べて抽象化の程度が高く、一般メソッドやメンバー変数がメンバーとして機能しないようにします.
また、定数(public static finalフィールド)のみがメンバーです.
インタフェースは複数の継承に制限がないため、インタフェースによって複数の抽象メソッドを作成することでコードの強制性を強化できます.複数のクラスで使用される同じ定数の場合、インタフェースで定数を定義して共有することで、重複を減らすことができます.

インタフェースの作成


抽象メソッドを作成するにはabstractキーワードを表示する必要がありますが、インタフェース内のすべてのメソッドは抽象メソッドであるため、public abstractキーワードを省略できます.ただし、混同される可能性があるため、public sbstractはすべてのインタフェースの抽象メソッドにマークされます.
public interface 인터페이스이름 {
    // 상수 또는 추상 메소드
}

インタフェースの継承


クラスの継承は単一の継承のみであり、インタフェースは複数の継承であってもよい.
public interface 인터페이스 extends 인터페이스1, 인터페이스2, ... {
    // 상수 또는 추상 메소드
}
抽象メソッドの実装と再定義は、インタフェースを継承する子孫クラスで実装する必要があります.

インタフェース実装


インタフェースを持つ抽象メソッドを実装するには、実装キーを使用して子孫クラスにインタフェースを継承する必要があります.継承された子孫クラスは、インタフェースの抽象メソッド(インプリメンテーション:メソッドボディを追加し、コードを記述する)を実装する必要があります.
public class 클래스이름 implements 인터페이스 {
    // 일반 클래스 정의
    // 인터페이스 추상 메소드 구현
}

インタフェースの利点


インタフェースを使用して、定義する方法(プログラム機能)を標準化および強制できます.また,方法化機能をどのように分類するかを考える必要がなく,実装するだけで開発時間を短縮できる.通常のクラス継承を使用してサブクラス間の関係を確立するよりも、簡単に関係を確立できます.