자바의 다형성이란?
자바에서 다형성은 중요한 객체지향 프로그래밍 원칙 중 하나이다. 이는 여러 형태의 객체를 동일한 방식으로 처리하는 것을 가능하게 한다.
다형성의 개념
다형성은 그리스어로 '많은'을 뜻하는 'poly'와 '형태'를 뜻하는 'morph'의 합성어이다. 자바의 같은 객체지향언에서 다형성은 부모 클래스를 상속받는 자식 클래스의 인스턴스가 부모 클래스의 객체로도 사용될 수 있음을 의미한다. 즉, 하나의 변수명이 여러가지 타입의 객체를 참조할 수 있다.
다형성의 사용
자바에서는 상속관계가 있는 클래스에서만 다형성을 사용할 수 있다. 예제에서 "Person"이라는 부모 클래스가 있고, "Student"라는 자식 클래스가 Person을 상속 받고 있다.
class Person{}
class Student extends Person{}
Studnet 객체를 생성하면서 타입을 Person으로 선언할 수 있다. 이렇게하면 Person 클래스의 메소드만 사용할 수 있다.
Person s2 = new Student();
이 경우에 "s2"는 Person 타입으로 선언되었지만, 실제로는 Studnet객체를 참조하고 있다. 이러한 다형성은 코드의 유연성을 높이며, 다양한 타입의 객체를 동일한 방식으로 처리할 수 있게 한다.
다형성의 주의점
다형성을 사용할 때에는 주의해야 할 점이 있다. 부모 타입으로 선언된 객체가 자식 클래스의 메서드를 호출하려면, 해당 메서드가 부코 클래스에도 선언되어야 한다. 이는 자바가 컴파일 시점에 메서드의 호출 가능 여부를 체크하기 때문이다.
Person s2 = new Student();
s2.someMethod(); // 'someMethod' must be declared in Person class as well.
만약 "someMethod"가 Studnet 클래스에만 선언되어 있고, Person 클래스에는 선언되어 있지 않다면 컴파일 에러가 발생한다. 이를 피하려면 Person 클래스에도 해당 메서드를 선언하거나, 객체를 Student 타입으로 선언해야 한다.
예제
class Person{
void eat() {
System.out.println("먹는 중..");
}
}
class Student extends Person{
void study() {
System.out.println("공부 중..");
}
}
public class Oop_polymorphism01{
public static void main(String[] args) {
Person p1 = new Person();
p1.eat();
Student s1 = new Student();
s1.eat();
s1.study();
//다형성 사용
Person p2 = new Student();
p2.eat(); // 가능
// p2.study(); // 불가능, 컴파일 에러
}
}
위 코드에서 "p2.study();는 컴파일 에러를 발생 시키는데, 이는 "p2"가 Person타입으로 선언되었고, Person 클래스에는 study 메서드가 없기 때문이다. 이런 경우를 해결하려면 Person 클래스에도 study 메서드를 선언하거나 "p2"를 Student 타입으로 선언해야 한다.
메모리 영역에서의 동작
자바에서 객체는 힙 메모리 영역에 생성된다. 그리고 이 객체를 참조하는 변수는 스택 메모리 영역에 위치하게된다.
다형성을 통해 "Person p2 = new Student();" 같은 코드를 작성했다고 가정한다면, 이 경우 "new Sudent();" 를 통해 "Student" 객체가 힙 메모리에 생성되고, 이 객체의 참조 값이 "p2"라는 변수에 저장된다. 이때 "p2"는 스택 메모리에 위치하게된다.
그런데 중요한 점은, "p2"가 Person 타입으로 선언되었기 때문에, Person 클래스에 선언된 메서드와 필드만 접근할 수 있따는 점이다. 실제로 "p2"가 참조하는 객체는 Student 객체이지만, Person 에 없는 Studnet의 메서드나 필드는 사용할 수 없다.
메서드를 호출하면, JVM은 해당 객체의 실제 타입을 확인하고 해당 타입에 정의된 메서드를 실행한다. 이를 "동적 메서드 디스패치"라고 한다. 이 때문에, 다형성을 사용하면 다양한 타입의 객체를 하나의 참조 변수를 통해 유연하게 처리할 수 있다.
그러나, 부모 클래스에 정의되지 않는 자식 클래스의 메서드를 호출하려고 하면 컴파일 에러가 발생한다. 이는 컴파일 시점에서 참조 변수의 타입에 따라 접근 가능한 메서드와 필드가 결정되기 때문에, 이를 "정적 바인딩"이라고 한다.
'Java > JAVA 100 문제 풀이' 카테고리의 다른 글
자바 part.4 문제풀이 - 추상 클래스를 이용한 다형성 구현 (0) | 2023.07.27 |
---|---|
자바 part.4 문제풀이 - 자바 다형성 : super와 casting사용 (0) | 2023.07.27 |
자바 part.4 문제풀이 - 인터페이스와 상속 활용하기 (0) | 2023.07.26 |
자바 part.4 문제풀이 - 다중 상속을 가능하게 하는 인터페이스(Interface) (0) | 2023.07.26 |
자바 part.4 문제풀이 - 추상 클래스(Abstract Class)개념, 필요 (0) | 2023.07.26 |