다형성

growdeveloper ㅣ 2021. 3. 16. 10:41

다형성

다형성은 상속과 깊은 관계가 있다,

객체지향개념에서 다향성이란 '여러 가지 형태를 가질 수 있는 능력'을 의미하며 자바에서는 한 타입의 참조변수로 여러 타입의 객체를 참조할 수 있도록함 으로써 다향성을 프로그램적으로 구현하였다.

 

인터페이스와 상속은 둘 다 다형성이라는 객체지향 프로그래밍의 특징을 구현하는 방식이다.

  • 하나의 객체를 여러 개의 타입으로, 하나의 타입으로 여러 종류의 객체를 여러 가지 모습으로 해석될 수 있는 성격이라고 생각하면 된다.
  • 하나의 객체를 여러 가지 타입으로 선언할 수 있다는 뜻이다. 다형성은 개발자들에게는간단히 말해서 하나의 사물(객체)을 다양한 타입으로 선언하고 사용할 수 있다는 의미로 해석해주면 된다. 일반적으로 어떤 객체가 하나의 분류에만 포함되는 것은 아니다. 대한민국의 국민인 동시에, 남자인 동시에, 서울에 사는 사람 등과 같이 이처럼 다형성은 어떤 사물을 여러 가지 시선으로 바라보는 모습을 생각하면 쉽게 이해할 수 있다.
  • Java에서 다형성은 상속과 인터페이스를 통해 이루어진다.
    다형성의 의미는 하나의 객체를 다향한 시선(타입)으로 바라볼 수 있게 한다는 의미이다. 중요한 것은 다양한 타입으로 본다는 사실 자체가 아니라 다양한 타입으로 객체를 바라보게 되면 호출할 수 있는 메소드 역시 타입에 따라 달라진다는 것이다. 상속의 오버라이딩을 설명하면서 오버라이딩을 하게 되면 컴파일러는 실체 객체의 메소드를 바라보는 것이 아니라, 변수 선언 타입의 메소드를 본다.
  • 인터페이스가 상속보다 다형성에 더욱 유연함을 제공한다.
    인터페이스는 클래스의 선언 뒤에서 여러 개의 인터페이스를 구현할 수 있게 할 수 있다. 이런 이유 때문에 하나의 객체를 여러 개의 타입으로 바라보는 다형성에는 상속보다 인터페이스가 더 큰 유연함을 제공한다고 할 수 있다. 인터페이스가 여러 개 올 수 있다는 의미는 다시 말해'여러가지 타입으로 변수를 선언할 수 있다'라는 것이다.

조상클래스 타입의 참조변수로 자손클래스의 인스턴스를 참조 할 수 있다.

class Parent {
	int x = 100;

	void method() {
		System.out.println("Parent Method");
	}
}

class Child extends Parent {
	int x = 200;


	void method() {
		//super.method();
		System.out.println("Child Method");
	}
	
	void method2() {
		
		System.out.println("Child Method");
	}
}

class Grandson extends Child {
	int x = 300;
	
	void method() {
		//super.method();
		System.out.println("Grandson Method");
	}
}

public class main {

	public static void main(String[] args) {
		
		Parent p = new Child();
		Child c = new Grandson();
		Grandson g = new Grandson();
		
		System.out.println("p.x = " + p.x);
		p.method();

		System.out.println("c.x = " + c.x);
		c.method();
		
		
		System.out.println("g.x = " + g.x);
		g.method();

	}
}
  • Parent P = new Child();
  • Child c = new Grandson();
  • Grandson g = new Grandson();
  • 기본형 변수와 같이 참조변수도 형변환이 가능하다. 단, 서로 상속관계에 있는 클래스 사이에서만 가능하기 때문에 자손 타입의 참조변수를 조상타입의 참조변수로, 조상타입의 참조변수를 자손타입 참조변수로의 형변환이 가능하다. (Child -> Person, Person -> Child)
  • 참조형 변수의 형변환에서는 자손타입의 참조변수를 조상타입으로 형변환하는 경우에는 형변환을 생략할 수 있다.
  • 참조 변수의 형변환은 참조변수의 타입을 변환하는 것이지 인스턴스를 변환하는 것은 아니기 때문에 참조변수의 형변환은 인스턴스에 아무런 영향을 미치지 않는다.

참조변수와 인스턴스의 연결

  • 조상클래스에 선언된 멤버변수와 같은 이름의 인스턴스변수를 자손 클래스에 중복으로 정의 했을 떄, 조상타입의 참조변수로 자손 인스턴스를 참조하는 경우와 자손타입의 참조변수로 자손 인스턴스를 참조하는 경우는 서로 다른 결과를 얻는다.
  • 메서드의 경우 조상 클래스의 메서드를 자손의 클래스에서 오버라이딩한 경우에도 참조변수의 타입에 관계없이 항상 실제 인스턴스의 메서드(오버라이딩된 메서드)가 호출 되지만, 멤버변수의 경우 참조변수의 타입에 따라 달라진다.
  • 메소드 : 실제 인스턴스에 따라
  • 멤버변수 : 참조변수의 타입에 따라.
Parent p = new Child();
Child c = new Grandson();
Grandson g = new Grandson();
		
p.x = 100
Child Method
c.x = 200
Grandson Method
g.x = 300
Grandson Method
  • Parnet 참조 변수는 Child()의 객체를 바라보고 있다. 이때 p의 변수값은 Parent의 값을 가지고 있고 p의 메소드는 Child()에서 정의된 method를 따라간다.
  • 다음과 같이 되는 이유는 리스코프 치환 원칙때문이다 자세한내용은 아래의 링크를 보고 판단하자.

ko.wikipedia.org/wiki/%EB%A6%AC%EC%8A%A4%EC%BD%94%ED%94%84_%EC%B9%98%ED%99%98_%EC%9B%90%EC%B9%99

 

리스코프 치환 원칙

위키백과, 우리 모두의 백과사전. 치환성(영어: substitutability)은 객체 지향 프로그래밍 원칙이다. 컴퓨터 프로그램에서 자료형 S {\displaystyle S} 가 자료형 T {\displaystyle T} 의 하위형이라면 필요한

ko.wikipedia.org

 

 

'자바' 카테고리의 다른 글

JVM 구조  (0) 2021.04.19
스레드  (0) 2021.04.08
추상 메소드  (0) 2021.04.08
클래스와 객체  (0) 2021.03.16
메소드 오버로딩  (0) 2021.03.13