Java 입문 - 상속/다형성

2 분 소요

상속 (inheritance)

  • 클래스들이 갖는 공통기능을 일반화하는 설계 방법

  • 부모클래스 (parent class) ⇒ 자식클래스 (sub-class or child class) 관계

  • sub “is a” super : 올바른 상속 관계 (학생 is a 사람 O, 강아지 is a 사람 X)

  • 계층구조 (tree 구조)

  • 단일 상속 허용 (부모클래스는 하나만 가능)

  • root class (최상위 부모클래스): java.lang.Object

    • 모든 클래스는 자동으로 상속을 받음
    • 주요 재정의 사용메서드
        • toString(): String
        • equals(Object): boolean
        • hashCode(): int
  • 부모클래스 선언방법

    [modifiers] class 부모클래스이름 {}
    
  • 자식클래스 선언방법

    [modifiers] class 자식클래스이름 extends 부모클래스이름 {}
    
    • 부모의 모든 멤버를 자동으로 상속받음
    • 부모의 private 멤버는 상속은 이루어지지만 접근권한으로 인해서 자식이 사용/변경 불가
    • 부모의 생성자는 상속이 되지 않고, 대신 자식객체의 생성자에서 부모의 생성자를 명시적으로 지정 가능
  • 메모리 로딩 시점: 부모 멤버 로딩 (부모 생성자 수행) ⇒ 자식 멤버 로딩 (자식 생성자 수행)

  • super 키워드

    • 부모 객체를 지칭하는 참조변수

    • super.부모멤버변수명

    • super(parameters)

      ⇒ this contructor와 같이 사용 불가

      ⇒ 자식 객체의 생성자에서 부모의 생성자를 명시적으로 지정시 사용

      ⇒ 자식객체의 생성자에서 부모의 생성자를 명시적으로 지정하지 않으면 javac가 자동으로 부모의 기본생성자를 호출 지정: super();

      ⇒ 부모의 생성자에 기본생성자가 반드시 존재해야만 자식객체의 생성자에서 명시적으로 부모의 생성자 지정하지 않아도 됨

다형성 (polymorphism)

  • 다형성

    • 하나의 기억공간에 여러개의 데이터를 담을 수 있는 기억공간
    • 하나의 메서드 이름으로 아규먼트를 다르게 수행
    • 일반화시킨 기능을 자식클래스에서 변경 가능
  • 변수타입 : 단일변수, 매개변수, 반환타입, 배열타입

    • 부모타입의 변수는 자식객체를 참조(저장) 가능

    • 하지만 부모타입이므로 자식객체의 멤버는 접근이 불가

    • 자식객체가 상속받은 메서드를 재정의 한 경우에는 재정의한 메서드는 부모타입이어도 실제 자식객체가 재정의한 메서드로 자동 호출 수행됨 ⇒ Virtual Method Invocation

    • 실제 자식 객체타입으로 형변환을 통해서 실제 메모리에 로딩된 자식객체의 멤버 접근 가능

      Member dto = new GeneralMember("", "", "", ..., 5000);
      dto.setMileage(1000); 	// error: 자식 멤버는 부모타입 참조시에 접근 불가
          		
      GeneralMember g = (GeneralMember)dto;
      g.setMileage(1000);		// success: 실제 자식객체로 형변환을 통해서 자식의 마일리지 멤버 접근 가능함
          
      SpecialMember s = (SpecialMember)dto; 
      // 컴파일 성공, 실행시 형변환 예외 발생함(ClassCastException) => 문제
          
      // 형변환 하기 전에 실제 객체의 instance 여부를 검증한 후에 형변환 : 오류 방지(안정성)
      // if(참조변수명 instancof 클래스이름) => boolean
      if (dto instanceof GeneralMember) {
      	GeneralMember g = (GeneralMember)dto;
      	g.setMileage(1000);
      } else if (dto instanceof SpecialMember) {
      	SpecialMember s = (SpecialMember)dto;
      	s.setManager("송중기");
      } else if (dto instanceof AdminMember) {
      	AdminMember a = (AdminMember) dto;
      	a.setPosition("부장");
      } else {
      	System.out.println("오류처리");
      }
      
  • 메서드 : 중복정의 (overloading), 재정의(overriding)

    • 중복정의 (overloading)

      • 연산자 : + (숫자 덧셈, 문자열 연결), &(조건식 논리연산, 숫자 bit연산 and), (조건식 논리연산, 숫자 bit연산 or)
      • 메서드 : System.out.println(), println(“hello”), println(mileage), println(new 클래스이름());
      • 생성자 : 기본생성자, 아규먼트 다르게 다중 정의
      • 규칙:
        • 이름 동일
        • 아규먼트 다름
        • 반환타입, 접근권한 상관없음
    • 재정의 (overriding)

      • 전제조건 : 상속

      • 부모 클래스로 일반화시킨 메서드의 기능을 자식이 필요에 의해서 수행로직 변경

      • 규칙 :

        • 동일 형식을 사용해야 함: 반환타입 메서드이름(아규먼트 갯수, 순서, 타입)

        • 접근권한 : 확장은 가능하지만 축소는 불가

        • 예외(Exception) : 축소는 가능하지만 확대는 불가

Annotation

  • JDK 1.5 부터 추가
  • javac, java 부가적인 정보 태그 (주석은 아님)
  • java 표준 & 사용자 정의 존재(프레임워크 등에서 많은 어노테이션 태그 정의 사용)
  • @Override
    • 재정의 규칙 체크하는 어노테이션
    • 메서드 선언문 앞에 위치 : javac 컴파일 시점에 체킹, 규칙 미준수시 오류발행 (컴파일 되지 않음)

댓글남기기