본문 바로가기

Java/Java 정리

상속 (Inhereritance)

*****상속*****

JAVA 의 클래스 간 관계

has a 관계  ==>  멤버

is a 관계 ==  > 상속 

상속은 extends 키워드를 사용하여 부모클래스의 정보를 자식 클래스에서 사용하게 된다.

UML에서 상속 관계는 실선 화살표 심볼이다.

문법 => public class 자식클래스명 extends 부모클래스명{}

부모 클래스에도 또 부모클래스가 있는데, Object 클래스(최상위 클래스)가 있다. 인스턴스 object와 다름.(대, 소문자)

=> A클래스가 B 클래스의 부모 클래스면, 실제로는 은연으로 extends Object 클래스가 삽입된다.

 ex) public class A (extends Object) {}; <- 소괄호 안은 은연으로 생략돼있음

 

상속은 단일상속만 지원한다. 단, 상속 불가한 경우가 있다.

1. 부모 생성자 -> 자식은 부모 생성자를 상속 받을 수 없다.

2. private -> private는 애초에 자기 자신(멤버)만 쓸 수 있기 때문에 상속 관계에서도 자식클래스에서 사용할 수 없다.

3. UML 표기법은 실선 화살표, 코드로는 extends 키워드를 이용한다. 부모 A < ㅡ 자식 B

4. 타입으로 따지면 부모가 더 큰 타입, 자식은 작은 타입

*******5. 항상 new 한 자식 클래스보다 부모의 기본 생성자를 먼저 생성한다.(자식 클래스가 부모 클래스의 생성자를 사용할 순 없지만, new 자식 클래스로 힙에 생성을 할 경우 부모 기본 생성자가 자동으로 생성되어 안에 내용을 실행한다.

-> 부모 클래스를 생성하는 코드가 자동으로 삽입됨. 그렇다고 new 부모클래스()는 아니다.

new 부모클래스()의 경우는 다른 클래스에서 사용하는 것이고, 자식에서는 super() 형식으로 부모 생성자를 호출하기 위해서 자동으로 삽입된다. super(); ==> 부모의 기본 생성자 호출 코드

 

*** 모든 클래스의 자식생성자 첫 라인에서 부모 생성자를 호출하는 코드가 자동으로 삽입된다. ==> super(); ***

    만약 super()를 명시적으로 작성한다면 반드시 첫 라인에서 작성할것. -> 이렇게 안하면 에러 난다.

   

*** 어떠한 클래스에서든 자기 자신(멤버)쪽에서 초기화 하는 것이 객체지향 관점에서 보기 좋다.***

-> 부모 클래스의 매개변수를 자식클래스에서 초기화를 해도 문법상 문제 없으나, 객체지향적으로  옳지 않다

 

상속을 쓰는 이유는 중복 코드의 발생을 최소화하기 위해서다.

1) 상속 x ==> 중복 코드 발생 높아짐

2) 상속 o ==> 중복 코드를 최소, 재사용성이 높아진다. => 부모 클래스에서 한 번만 만들어주면 되기 때문에

 

상속 공부 계속..

 

*** 오버라이딩***

부모 클래스는 포광적인 개념의 클래스.

부모 클래스의 메서드를 자식클래스에서 똑같은 동작으로 사용할 순 있지만, 가령 강아지는 '쩝쩝' 고양이는 '냠냠' 먹는게 다른 것처럼 먹은 동작의 메서드를 부모클래스에서 갖고 있다고 할 때, 자식 클래스에서 부모클래스의 메서드를 재정의하여 사용한다.

개념: 부모의 메서드를 자식이 재정의 가능한 방법으로서, 자식에서 수정된 메서드를 의미한다.

규칙: 부모 => 접근지정자 리턴타입 메서드명(파라미터1,2,3...){}

         자식 =>        변동         동일         동일             동일 

위 규칙에서 자식클래스의 접근지정자의 경우 부모클래스의 접근지정자와 같거나 확대 가능하다. 나머지 리턴타입, 메서드명, 파라미터 변수는 부모클래스의 메서드와 동일해야 한다.    

 --> 확대 순 private -> default -> protected -> public  ==>  부모가 public 이면 자식은 무조건 public,  부모가 default면  그 이상. 

단!!! 부모가 private면 자식 클래스는 못쓴다.. 자식 클래스는 부모 클래스의 private 및 생성자 접근 불가(super로 접근 가능) 또한 default 접근 지정자 역시 부모와 자식의 패키지가 다르면 접근이 안된다.

 

 

*this 키워드 및 super 키워드

this =  상속 무관, this는 heap 메모리에 있는 자신 참조시 사용

super = 상속 전제, super는 heap 메모리에 있는 부모 참조시 사용

this의 예 ==> this.멤버

                      this([값 ...])   ==> 자신 클래스의 오버로딩 생성자 호출

super의 예 ==> 부모 생성자 호출 -> super([값]);

                          부모 멤버 호출  -> super.멤버

 

*다형성(polymorphism)

-상속 전제

-개념: 큰 타입의 참조변수가 같거나 작은 타입을 참고할 수 있는 기능

    ex) X 변수 = new X();

          X 변수 = new X'();  -> X랑 X'는 다름 X와 X'는 상속 관계여야 한다. X는 큰 타입, X'는 작은 타입

위와 같은 다형성은 재사용성을 높히기 위함 -> 변수 하나로 여러가지 인스턴스를 받을 수 있다. 가능한 이유는 상속 관계이기 때문에.

ex) Pet 부모 클래스 Cat, Dog 자식 클래스

Pet p = new Cat();

       p = new Dog(); 로 처리 할 수 있음.

단, 자식클래스의 종속적인 부분에 대해서는 접근이 불가하다. (부모클래스에서 있는 정보만 가능 ==> 자식 클래스에서만 갖고 있는 변수를 예로 들 수 있음)

해결 방안

1. 원래 타입대로 형변환을 해주면 된다.

Dog d = (Dog)p;

 

상속 구조에서 부모 클래스와 자식 클래스를 비교할땐 반드시 부모클래스를 맨 마지막에 비교해줘야 한다.

why?  if 문으로 예를 들면 if는 참일 때 실행문을 동작시킨다. 그런데 부모를 먼저 비교하게 되면 항상 참이므로, 자식들을 비교할 것도 없이 if 문이 종료되어버리기 때문이다.

'Java > Java 정리' 카테고리의 다른 글

컬렉션 프레임워크 - HashSet  (0) 2022.10.21
제어자 (modifier)  (0) 2022.08.21
패키지(Package)  (0) 2022.08.21
인터페이스 (Interface)  (0) 2022.08.21
추상(Abstract)  (0) 2022.08.21