[TIL] Java - 다형성

KwonSC·2021년 11월 9일
0

TIL - Java

목록 보기
3/5
post-thumbnail

다형성

다형성은 부모의 타입으로 다양한 형태의 자식 객체를 생성, 참조 할 수 있는 것을 말한다.

Student student = new Student(); // 대신
Person student = new Student(); // 를 사용하면

Person[] people = {new Person(), new Student(), new Teacher(), ...}; // 배열관리를 통해 동일 작업을 쉽게 할수있다.

동적 바인딩

컴파일 할 때 호출하는 메소드와 실행 할 때 호출하는 메소드가 유동적으로 적용되는 것을 말한다.

  • 참조 데이터 타입이 부모 클래스인 Person 이라고 하더라도, 메소드의 실행은 실제 생성된 객체의 메소드로 실행된다.
  • 위와 같이 코드를 실행할 때 참조 데이터 타입이 아닌 객체 타입의 메소드를 실행하는 것을 동적 바인딩이라고 한다.

  • Java언어에서의 다형성과 동적 바인딩의 특성때문에 에러가 발생
    • 다형성을 이용하여 Person 참조 데이터 타입을 갖는 Student 객체 student를 생성하면, 컴파일러는 student에 대하여 필드나 메소드 접근을 할 때 참조 데이터 타입인 Person 만 바라보게 된다. 컴파일러는 Student는 알 수가 없는 것이다. 그러므로 student.study(); 라는 메소드 호출은 할수 없다.

객체의 캐스팅

((Student)student).study(); // 해결!
((Teacher)teacher).study(); // 해결!
  • () 괄호를 이용하여 캐스팅을 해주면 각 클래스가 가지고 있는 메소드 호출이 가능하다.
Student s2 = (Student) student;
s2.study(); // 코드가 실행 가능할까?

  • 참조 데이터 타입을 Student로 바꿔 주었으므로, study() 메소드를 부르는 것에 문제가 없다. 이코드를 그림으로 나타내면 위와 같다. 동일한 객체이지만, 서로 다른 변수가 이 객체를 가리키고 있다. 대신, student는 Person을 참조하고 있고 s2는 Student를 참조하고 있다.

instanceof 연산을 통한 객체 판별

  • A instance of B 의 의미
    • A가 B의 자식이거나 같은 class 타입이면 true
    • A가 B의 부모이면 false
    • A의 참조 데이터 타입과 B의 부모가 동일하면 false
    • 부모/자식 관계에 속하지 않는 것끼리 instanceof 하면 컴파일 에러
    • true는 검사한 타입으로 형변환을 해도 아무 문제가 없다는 뜻이고 false는 형변환이 불가능하거나 문제가 생긴다는 것을 뜻한다.
    • 주로 조건문에 사용한다

인터페이스

인터페이스는 구현되지 않은 메소드로 구성되어 있다.

  • 인터페이스의 내부는 아래와 같은 구조로 되어있다.
public interface 인터페이스명 { // 인터페이스 선언
    public final static Data_Type 상수명 = 상수의_값; // 상수 선언
    public Return_Type 메소드명(파라미터1, 파라미터2, ...); // 추상 메소드 선언
}
  • 인터페이스 내부에 선언하는 변수는 무조건 public final static 이다.

    • final static 키워드가 붙는 변수는 상수이다.
    • 상수는 값을 변경할 수 없으므로, 반드시 선언 시에 값을 대입해 주도록 한다.
  • 인터페이스 내부에 선언 하는 메소드는 몸체가 없는 추상 메소드이다.

  • 인터페이스를 구현하는 클래스에서 implements를 이용하여 구현

    • 인터페이스에 선언된 모든 추상 메소드를 구현해야 한다.
public class 클래스명 implements 인터페이스명 {
    // 인터페이스에 선언된 메소드 구현
}

내부, 익명 클래스

  • 내부 클래스(Inner Class) 란?

    • 클래스 안에 선언된 클래스이다.
    • 특정 클래스 내에서만 주로 사용되는 클래스를 내부 클래스로 선언한다.
    • 내부 클래스에서 외부 클래스의 멤버들을 쉽게 접근할 수 있다.
public class OuterClass { // 외부 클래스
    class InnerClass {} // 내부 클래스
}
  • 내부 클래스의 종류는 선언위치에 따른 종류와 같다. 유효범위와 성징로 변수와 유사하므로 비교해보면 이해하기 쉽다.

    • 인스턴스 클래스

      • 외부 클래스의 멤버변수 선언위치에 선언되며 인스턴스 멤버처럼 다루어진다.
      • 외부 클래스의 인스턴스 멤버들과 관련된 작업에 사용될 목적으로 선언된다.

    • 중첩 클래스

      • 외부 클래스의 멤버변수 선언위치에 선언되며 static 멤버처럼 다루어진다.
      • 외부 클래스의 static 변수, 메소드에서 사용될 목적으로 선언된다.

    • 지역 클래스

      • 외부 클래스의 메소드 안에 선언되며, 메소드 내부에서만 사용된다.
      • 인스턴스 클래스의 특징을 그대로 유지한다.

    • 익명 클래스

      • 클래스의 이름이 정의되어 있지 않다.
      • 클래스의 선언과 생성을 동시에 하기 때문에 일회용 클래스이다.


콜백

  • 콜백(callback)은 다른 코드의 인수로써 넘겨주는 실행 가능한 코드를 말한다.
  • 콜백을 넘겨받는 코드는 이 콜백을 필요에 따라 실행할 수 있다.
  • 자바에서는 콜백을 구현하기 위해서 인터페이스를 사용한다.
public class Sum {
    interface OnMaxNumListner { // 인터 페이스 정의
        void onMaxNumber(int number); // Sum 클래스 내부에 onMaxNumLisnter를 정의한다. 클래스를 따로 정의해도 크게 상관은 없다.
    }
    void setOnMaxNumListner(OnMaxNumListner listner) { //콜백함수 등록
        this.listner = listner;
    }
}
public static void main(String[] args) {
    OnMaxNumListner listner = new OnMaxNumListner() { // OnMaxNumListner를 구현한 익명 클래스
        @Override
        public void onMaxNumNumber(int number) {
            System.out.println(number);
        }
    }
    
    Sum sum = new Sum();
    sum.setOnMaxNumListner(listner);
}

0개의 댓글