: 여러가지 형태를 가져 다양한 동작을 할 수 있는 능력이고, 상속과 함께 객체지향의 가장 중요한 특징 중 하나이다.
자바에서의 다형성
: 자바에서는 한 타입의 참조변수로 여러 타입의 객체를 참조할 수 있도록 했다. List를 예로 생각해보면, List 참조변수로 ArrayList, LinkedList 타입을 받을 수 있다.
참조변수와 형변환
1
2
3
4
5
6
7
8
9
10
11
class UserRepository {
// ...
}
class UserJdbcRepository extends UserRepository {
// ...
}
UserRepository userRepository = new UserJdbcRepository(); // A. 다형성
UserJdbcRepository userJdbcRepository = new UserRepository(); // B. Error
- A에서 부모 참조변수 타입을 갖는
userRepository
는 자식 클래스userJdbcRepository
에만 존재하는 멤버를 사용 할 수 없다. 부모 클래스에 있는 멤버에만 접근 가능하고 런타임에는 자식 클래스의 멤버로 맵핑된다. - B에서 자식 클래스를 참조변수 타입으로 갖게 했고, 이 경우 실제 인스턴스인 부모 클래스에 없는 멤버에 접근하려 할 수 있기 때문에 컴파일 에러가 발생한다.
- 멤버변수의 경우 (부모와 자식 클래스에 중복된 경우에) 참조변수의 타입의 변수를 따른다. (위의 A의 경우
userRepository
로 정의한 객체의 멤버변수를 따른다.)
자바에서의 형변환
1
2
3
4
5
6
UserRepository userRepository = new UserJdbcRepository();
// 위는 아래와 같다.
UserJdbcRepository userJdbcRepository = new UserJdbcRepository();
UserRepository userRepository = (UserRepository) userJdbcRepository;
- 형변환은 참조변수의 타입을 변환하는 것이기 때문에 인스턴스에는 아무런 영향이 없다. 다만, 참조하고 있는 인스턴스에서 사용할 수 있는 멤버의 범위(개수)를 조절하는 것이다.
Instanceof
인스턴스의 타입을 알기 위한 연산자
1 2 3
SessionedUser sessionedUser = new SessionedUser(); if(sessionedUser instanceof User) { /* */ } // true if(sessionedUser instanceOf Object) { /* */ } // true
Object: 자바에서 모든 클래스의 조상 클래스. toString(), equals()
와 같은 기본적인 메소드 제공
다형성
1
2
3
4
5
6
User users[] = new User[3];
users[0] = new AUser();
users[1] = new BUser();
users[2] = new CUser();
users.forEach(User::foo);
- 위의 배열
users
에 대한 loop를 돌면서 무언가를 수행하면 중복된 메소드 대해서는 자식의 메소드를 수행한다. 중복된 멤버변수의 경우 부모가 가진 멤버 변수를 참조한다.
Reference)
자바의 정석 3판