[TIL] Java - 다형성
다형성
다형성은 부모의 타입으로 다양한 형태의 자식 객체를 생성, 참조 할 수 있는 것을 말한다.
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();
라는 메소드 호출은 할수 없다.
- 다형성을 이용하여 Person 참조 데이터 타입을 갖는 Student 객체 student를 생성하면, 컴파일러는 student에 대하여 필드나 메소드 접근을 할 때 참조 데이터 타입인 Person 만 바라보게 된다. 컴파일러는 Student는 알 수가 없는 것이다. 그러므로
객체의 캐스팅
((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);
}
Author And Source
이 문제에 관하여([TIL] Java - 다형성), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@kwonsc/TIL-Java-다형성저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)