국비/Java
[11-1] Java 오버라이딩(Overriding), 다형성 맛보기
제발 취업하게 해주세요
2022. 4. 21. 23:39
오버라이딩(Overriding) |
- 상속 받고 있는 부모클래스의 메소드를 자식클래스에서 재정의(재작성) 하는 것 - 부모클래스가 제공하고 있는 메소드를 자식이 일부 고쳐서 사용하겠다는 의미 - 자식클래스의 오버라이드 된 메소드가 우선권을 가져서 호출된다. * 오버라이딩의 성립조건 1. 부모메소드의 메소드명과 동일 2. 매개변수의 자료형, 갯수, 순서가 동일(매개변수명과는 무관) ex) publi cint result(int a, int b){int a + int b;} // 부모 public int result(int a, int b, int c){int a + int b + int c} //자식 갯수가 달라서 오버라이딩xxxxx 이건 오버로딩! 3. 반환형이 동일해야한다 4. 부모메소드의 접근제한자보다 공유 범위가 넓거나 같아야 함 >> 규약의 개념 * @Override * 어노테이션 (annotation) * 일종의 주석 * - 생략 가능 => 명시를 안해도 부모메소드와 형태가 같으면 오버라이딩 된 것으로 판단. * - 어노테이션을 붙이는 이유? * => 실수를 줄이자/ * => 누가 봐도 오버라이딩 * * 개발자들끼리의 약속 * 생략은 가능하지만 작성하는 습관을 들이자! |
* 부모클래스에게 상속받는 것 * => ★★★★★타입(자료형)★★★★★★ * => 메소드, 필드 |
// 부모꺼는 내꺼 내꺼도 내꺼 1. 부모타입 자료형으로 부모 객체를 다루는 경우 Parent p1 = new Parent(); p1.printParent(); // p1.printChild(); // 자식꺼는 내꺼가 아냐 //p1으로는 Parent에만 접근 가능 2. 자식타입 자료형으로 자식 객체를 다루는 경우 Child1 c1 = new Child1(); c1.printChild1(); // 내꺼는 내꺼 c1.printParent(); // 부모님것도 내꺼 //c1으로는 Parent, Child1에 둘 다 접근 가능 3. 부모타입 자료형으로 자식 객체를 다루는 경우 => 다형성이 적용된 개념 Parent p2 = /*(Parent)*/new Child1(); // Child1이 (Parent)로 자동형변환 p2.printParent(); // p2.printChild1(); 자식거는 부모가 사용 x //p2로는 Parent만 접근 가능 // 양쪽 자료형이 다름에도 오류가 나지 않는 이유?? // Parent형으로 자동형변환이 되었으니까 // 상속구조에서는 클래스 형변환이 가능하다!!!!!!!!!!! |
// 부모는 자식으로 형변환이 될까? ((Child1)p2).printChild1(); * 클래스간의 형변환 - "상속구조"일 경우에만 클래스간의 형변환이 가능하다!! * 1.UpCasting * 자식타입 => 부모타입으로 변환 * 생략 가능, 자동형변환 * ex) 자식.부모메소드(); * 2.DownCasting * 부모타입 => 자식타입 * 생략이 불가능하다. * ((자식)부모).자식메소드(); |
다형성을 사용하는 이유는? |
* 배열을 써보자 * 배열의 특징은?? == 한 종류의 자료형인 값들을 묶어서 관리가 가능하다 // 다형성을 배우기 전... // Child1 객체 2개와 Child2 객체 2개를 관리해야 됨 Child1[] arr1 = new Child1[2]; arr1[0] = new Child1(1, 2, 3); arr1[1] = new Child1(4, 5, 6); Child2[] arr2 = new Child2[2]; arr2[0] = new Child2(1, 2, 3); arr2[1] = new Child2(1, 2, 3); |
* 다형성을 접목한 배열 // 부모타입의 객체 배열을 만든 다음 // 자식들을 부모 배열에 묶어보자 Parent[] arr = new Parent[4]; arr[0] = /*(Parent)*/new Child1(1, 2, 3); arr[1] = /*(Parent)*/new Child2(4, 5, 6); arr[2] = /*(Parent)*/new Child1(7, 8, 9); arr[3] = /*(Parent)*/new Child2(10, 11, 12); // PrintParent 메소드 호출 for(int i = 0; i < arr.length; i++) { arr[i].printParent(); } |
* Child1을 Child2로 강제형변환을 한다면?? >> ((Child2)arr[0]).printChild2(); >>>>ClassCastException이 발생 // 클래스간에 형변환이 잘못되었을 경우 발생함 * 원래 Child1인 애를 Child2로 바꾸려니까 에러가 났다 * 클래스간의 형변환은 !!상속!!(부모자식) 관계에서만 가능하다 * 자식-자식 x |
* instanceof 연산자 => true / false : 현재 레퍼런스가 실질적으로 어떤 클래스타입을 참조하는지 확인할 때 사용 ex) arr[ 0 ] instanceof Child1 => 결과는 true or false |
* 동적바인딩 : 프로그램 실행되기 전에는 컴파일 되면서 정적바인딩(자료형의 메소드를 가리킴) 단, 실질적으로 참조하는 자식클래스에 해당 메소드가 오버라이딩 되어 있다면 프로그램 실행 시 동적으로 자식클래스의 오버라이딩 된 메소드를 찾아서 실행 // 오버라이딩 특징 : 오버라이딩 개념이 적용된 메소드 호출 시 원조 메소드보다 새롭게 정의된 메소드가 우선순위가 높기 때문에 먼저 호출됨 // 우리가 앞으로 객체 배열을 쓸 때 오버라이딩을 이용하면 굳이 강제 형변환을 하지 않아도 된다!! |