[JAVA] 객체 지향 핵심 - 가상메서드, 다형성

WOOK JONG KIM·2022년 8월 31일
0

패캠_java&Spring

목록 보기
5/103
post-thumbnail

메서드 호출 및 실행 원리

  • 메서드(함수)의 이름은 주소값을 나타냄
  • 메서드는 명령어의 set 이고 프로그램이 로드되면 메서드 영역(코드 영역)에 명령어 set이 위치
  • 해당 메서드가 호출 되면 명령어 set 이 있는 주소를 찾아 명령어가 실행됨
  • 이때 메서드에서 사용하는 변수들은 스택 메모리에 위치 하게됨
  • 따라서 다른 인스턴스라도 같은 메서드의 코드는 같으므로 같은 메서드가 호출됨
  • 인스턴스가 생성되면 변수는 힙 메모리에 따로 생성되지만, 메서드 명령어 set은 처음 한번만 로드 됨
public class TestMethod {

	int num;
	
	void aaa() {
		System.out.println("aaa() 호출");
	}
	
	public static void main(String[] args) {
		
		TestMethod a1 = new TestMethod();
		a1.aaa();
		
		TestMethod a2 = new TestMethod();
		a2.aaa();
	}

}

가상 메서드 원리

  • 가상 메서드 테이블(vitual method table)에서 해당 메서드에 대한 address를 가지고 있음
  • 재정의된 경우는 재정의 된 메서드의 주소를 가리킴

잘 안 와닿아서 , 이해를 위해 찾아본 내용!

출처 : https://plas.tistory.com/29

클래스는 데이터 필드와 그에 대한 메소드 정의

예를 들어 사람 클래스 -> 이름,나이,성별,주소 가짐

메소드로 자기소개(intro)를 하거나 집에 가거나(goHome) 나이를 먹는다(getOlder)

  • 즉 메소드란 그 사람의 데이터로 무슨 일을 하거나 필드의 값을 바꾸는 것 이다.

  • 메소드는 주어(객체)가 있고 그 객체(this)의 데이터로 메소드를 수행한다.

상속을 통해서 사람 클래스에서 특수한 부류의 사람을 나타낼 수 있다.

사람을 상속한 클래스로 학생이나 직장인이 있을 수 있다.

예를 들면 학생 클래스는 사람이 가지는 데이터 이외에 학교와 학년을 가진다. 그리고 직장인이라면 직장과 업무 등을 가진다.

학생 및 직장 클래스는 사람의 필드와 메소드를 물려받는데 단순히 사람을 소개할때와는 다르게 부가적인 내용을 더 붙인다

이때 학생이 슈퍼클래스인 사람의 intro()메소드를 오버라이드 한다고 얘기한다.

class 학생 extends 사람 { 
	String 학교; 
	int 학년; 
	@Override 
	void intro() { 
		super.intro(); 
		System.out.println(학교+학년); 
	} 
} 

가상 메서드란?

가상함수는 오버라이드된 함수를 호출하는 방식에 관한 이야기로 객체지향의 중요한 특징 중 하나인 다형성의 측면에서 볼 수 있다.

다형성동일한 코드로 경우에 따라 다른 동작을 하게 되는 것을 말한다.

가상함수의 다형성은 슈퍼클래스의 참조가 상속한 객체를 모두 가리킬 수 있다는 업캐스팅을 이용하여 슈퍼클래스를 오버라이드한 메소드 여러 개를 표시할 수 있는 것을 의미한다.

사람 person;
if ( ... )
	person = new 학생();
else if (...)
	person = new 직장인();
person.intro();   // 다형성에 의한 호출

person.intro();라고 할 때 person 변수가 가리키는 객체는 사람, 학생, 직장인일 수 있다.

코드 상으로는 동일하게 사람의 intro() 호출인 것처럼 보이지만 실제로 실행될 때 코드는 객체가 사람이면 사람의 intro(), 학생이면 학생의 intro(), 직장인이면 직장인의 intro()가 호출된다. 이것을 가상함수 호출이라고 한다


다형성(polymorphism) 이란?

  • 하나의 코드가 여러 자료형으로 구현되어 실행되는 것
  • 같은 코드에서 여러 다른 실행 결과가 나옴
  • 정보은닉, 상속과 더불어 객체지향 프로그래밍의 가장 큰 특징 중 하나임

  • 다형성을 잘 활용하면 유연하고 확장성있고, 유지보수가 편리한 프로그램을 만들수 있음

다형성 활용 예시

package ch06;

import java.util.ArrayList;

class Animal{
	
	public void move() {
		System.out.println("동물이 움직입니다. ");
	}
	
}

class Human extends Animal{
	@Override
	
	public void move() {
		System.out.println("사람이 두 발로  움직입니다. ");
	}
	
	public void readBook() {
		System.out.println("사람이 책을 읽습니다. ");
	}
	
}

class Tiger extends Animal{
	@Override
	public void move() {
		System.out.println("호랑이가 네발로   움직입니다. ");
	}
	
	public void hunting() {
		System.out.println("호랑이가 사냥을 합니다. ");
	}
}

class Eagle extends Animal{
	@Override
	public void move() {
		System.out.println("독수리가 하늘을 날아 다닙니다 ");
	}
	
	public void flying() {
		System.out.println("독리가 양날개를 쭉 펴고 날아다닙니다 ");
	}
}


public class AnimalTest {

	public static void main(String[] args) {
		
		Animal hAnimal = new Human();
		Animal tAnimal = new Tiger();
		Animal eAnimal = new Eagle();
		
//		AnimalTest test = new AnimalTest();
//		test.moveAnimal(hAnimal);
//		test.moveAnimal(tAnimal);
//		test.moveAnimal(eAnimal);
		
		ArrayList<Animal> animalList = new ArrayList<>();
		animalList.add(hAnimal);
		animalList.add(tAnimal);
		animalList.add(eAnimal);
		
		for(Animal animal : animalList) {
			animal.move();
		}
	}

	
	public void moveAnimal(Animal animal) {
		animal.move();
        /* 여기서 flying, hunting, readbook 같은 메서드를 사용하고 싶다면
         다운캐스팅 해야함! */
	}

}

앞서 설계한 멤버십 등급에 골드 등급 추가 후 결과 출력
(다형성 잘 보여줌)

package ch06_gold;

import java.util.ArrayList;


public class CustomerTest {

	public static void main(String[] args) {
		
		ArrayList<Customer> customerList = new ArrayList<Customer>();
		
		Customer customerLee = new Customer(10010, "이순신");
		Customer customerShin = new Customer(10020, "신사임당");
		Customer customerHong = new GoldCustomer(10030, "홍길동");
		Customer customerYul = new GoldCustomer(10040, "이율곡");
		Customer customerKim = new VIPCustomer(10050, "김유신");
		
		customerList.add(customerLee);
		customerList.add(customerShin);
		customerList.add(customerHong);
		customerList.add(customerYul);
		customerList.add(customerKim);
		
		System.out.println("====== 고객 정보 출력 =======");
		
		for( Customer customer : customerList){
			System.out.println(customer.showCustomerInfo());
		}
		
		System.out.println("====== 할인율과 보너스 포인트 계산 =======");
		
		int price = 10000;
		for( Customer customer : customerList){
			int cost = customer.calcPrice(price);
			System.out.println(customer.getCustomerName() +" 님이 " +  + cost + "원 지불하셨습니다.");
			System.out.println(customer.getCustomerName() +" 님의 현재 보너스 포인트는 " + customer.bonusPoint + "점입니다.");
		}
	}
}
profile
Journey for Backend Developer

0개의 댓글