オブジェクト向けプログラミング:さまざまな形式


たけいせい


継承とともにオブジェクト向けの重要な特徴の一つです.継承については十分な理解が必要です.
オブジェクト向けの概念では、多形性とは多様な形状を持つ能力を指すが、Javaでは多形性は一種の参照変数であり、多様なタイプのオブジェクトを参照することができ、プログラミングによって多形性を実現する.
class Person {
	int height;
    int weight;
    int age;
    public void introduce() {}
}

class NoobNoob extends Person{
	@Overrice void introduce() {
		"힘세고 강한 안녕! 내 이름을 묻는다면 나는 늅늅!";
    }
}

public static void main(String[] args){
	Person human = new Person();	// 이건 당연히 되고
    Person noob = new NoobNoob();	// 이렇게 부모 클래스 타입의 변수에,
    								// 자식 클래스 타입의 인스턴스 참조가 가능해요.
}
上記の例で示したように、PersonNoobNoobが継承関係にある場合、親タイプの変数で子クラスインスタンスを参照できます.
しかし、反対は不可能だ.NoobNoob自体にheightageなどの変数はないので、使えば無理でしょうか?したがって、メンバーが存在しないため、サブタイプの参照変数としてメンバーを使用して親タイプのインスタンスを参照することはできません.
NoobNoob noob = new Person();	// Error!

参照変数の変形


しかし、仕方がないわけではありません.基本変数と同様に、参照変数も変換できます.これにより、親インスタンスをサブタイプに変換して、サブタイプ変数の参照に使用できます.このように親タイプの参照変数を子タイプに変換する場合、Down-castingを選択します.
基本型変数の型変換では、小データ型から大データ型への型変換を省略することができ、参照型変数の型変換では、サブタイプの参照変数を親タイプに変換すると、型変換を省略することができる.これがUpcasting Up-castingです反対もあります.
Person person = new NoobNoob();		// Up-casting, 형변환 생략 가능
NoobNoob noob = (NoobNoob)person;	// Down-casting, 형변환 생략 불가
もちろん、この2つのクラスは関係を継承する前提でしか変換できません.エラーが発生します.また,降速を実行する参照変数で誤った変換が行われると,プログラムがコンパイルでない場合にエラーが発生し,プログラムがハングアップする.したがって、instanceof演算子を使用して、まず参照変数が参照する実際のインスタンスのタイプを決定し、次いで成形変換を実行することが望ましい.
class A {}
class B extends A {}
class C extends A {}

A ab = new B();
B b = (B)ab;		// 가능!
C c = (C)b;			// 불가능! 둘은 상속 관계가 아니에요

A ac = new C();
b = (B)ac;			// 런타입 에러! instanceof 키워드로 먼저 체크!

if(ac instanceof B)	// 요렇게!
	b = (B)ac;		
しかしこれで兄が変わればタイプが変わるのでインスタンス構造も変わる成形遷移は、変換インスタンス自体ではなく参照変数のタイプを変換するだけで、影響はありません.概念が違うだけなので安心してください.

instanceof演算子

intanceof演算子を使用して、参照変数が参照するインスタンスの実際のタイプを理解します.
if(ac instanceof B)	// 이렇게!
しかし、instanceofは、インスタンスのすべての親タイプにおいてもtrueを返す.
FireEngine fe = new FireEngine();
if (fe instanceof FireEngine) {
	System.out.println("It's fire engine.");	// 출력!
}
if (fe instanceof Car) {
	System.out.println("It's car.");			// 출력!
}
if (fe instanceof Object) {
	System.out.println("It's object.");			// 출력!
}
では、このように整理できます
いくつかのタイプでは、instanceof演算の結果はtrueであり、検証タイプに変換できます.

参照変数とインスタンスの関連付け


親インスタンスに宣言された変数と同じ名前のインスタンス変数が子インスタンスに定義されている場合、親タイプの参照変数を使用して子インスタンスを参照する場合と、子タイプの参照変数を使用して子インスタンスを参照する場合は、異なる結果が得られます.
メソッドは、参照変数のタイプにかかわらず、実際のインスタンス内のメソッドを呼び出します.メンバー変数のメソッドは、参照変数のタイプに依存します.
もちろん、インスタンス変数が繰り返し定義されていない場合は大丈夫です.だから使うときは注意が必要です.
class Parent { int x = 100; }
class Child extends Parent { int x = 200; }

Parent p = new Child();	// p.x = 100
Child c = new Child();	// c.x = 200
内部変数は、superおよびthis(または宣言されていない)によって区別することができる.
class Child extends Parent{
	void func(){
		super.x // 100
		x		// 200
	}
}

複数のオブジェクトを配列にする


親タイプ[]シェイプのオブジェクト配列は、各インデックスのサブインスタンスを参照できます.
Parent[] p = new Parent[3];
p[0] = new Child();
p[1] = new GrandChild();
p[2] = new BaeDarlnChild();