티스토리 뷰

728x90

저를 포함한 초보자분들에게 도움이 됐으면 좋겠습니다.
초보자분들은 수박 겉핥기 식으로 알고 넘어가지 마시고, 조금이라도 왜 이렇게 프로그램이 돌아가는지 알고 가시는 시간이 됐으면 좋겠습니다.

오늘은 상속 편에서 잠깐 언급했던 오버 라디오에 관련한 내용을 적어볼까 합니다.
오버라이딩, 오버라이드, 하이딩은 서로서로 관련이 많기에 같이 설명해 보고자 합니다.
자 그럼 오버라이딩(Overriding)부터 설명해 보겠습니다.

오버라이딩(Overriding)이란 부모 클래스에서 정의한 메소드를 자손 클래스에서 재정의하여 사용하는 것입니다. 재정의하여 사용하니 메소드의 return, 이름, 매개변수는 같아야 합니다.
예시를 봅시다.

(1) public class parent {
	  public void say() {
		  System.out.println("부모");
	  }
  }
(2) public class son extends parent{
	  public void say() {
		  System.out.println("자손");
	  }
	  public static void main(String[] args) {
		  son myson = new son(); // 객체생성
		  myson.say(); //자손 출력
	  }
  }

(2) 코드를 보시면, son 클래스는 (1) 클래스인 parent를 상속받고 있습니다. 
그럼 생성한 myson 객체는 son, parent의 변수,메소드를 사용할 수 있죠.
하지만 son과 parent 클래스에 이름, 매개변수가 같은 메소드인 say을 두 클래스 모두 가지고 있습니다. 이러한 경우에 오버라이딩(Overriding)이 적용이 되는 것이죠.
이와 같은 경우에 say 메소드를 수행 시켜보면, son에 있는 say가 실행되는 것을 볼 수 있죠.
오버라이딩은 이와 같이 이름,매개변수가 같은 메소드가 부모, 자손 클래스에 모두 있으면 상속을 받는 자손메소드로 사용하는 것이죠.
이유는 간단합니다. 저번에도 말씀드렸듯 상속은 자손 클래스 - 부모 클래스 순서로 엮어주는 것입니다.
say라는 메소드를 실행하면, 자손 클래스 - 부모 클래스 순으로 처음 발견한 곳의 메소드를 수행합니다.
부모 클래스에만 있는 메소드를 사용할 수 있는 이유도 이와 같습니다. 자손 클래스에서 찾고 없으니 부모 클래스로 넘어가 찾아 사용하기 때문이죠.

그다음은 하이딩(hidding / 은닉)입니다.
하이딩은 static으로 정의된 메소드에 수행이 됩니다. 오버라이딩과 하는 일은 같습니다. 
하지만 다른 점이 하나 있습니다. 오버라이딩은 한번 되는 순간 형 변환을 통하여 부모메소드를 실행시켜도 오버라이딩된 메소드가 실행되는 것을 볼 수 있습니다. 예를 보시죠.

(3)public class son extends parent{
	public void say() {
        super.say(); //부모
		System.out.println("자손");
	}

	public static void main(String[] args) {
		son myson = new son(); // son 객체생성
		parent myparent = (parent)myson; // parent객체 생성  --- myson의 형변환
		myparent.say(); //자손
	}
}  최종출력: 부모 자손

(3) 코드와 같이 son 객체를 생성하여 부모의 형태로 변환하여 myparent에 저장을 해주었습니다.
이 상태에서 say()를 실행해 보면, 접근은 parent에 있는 메소드에 접근을 하지만, 결과는 "자손"이라는 출력이 나옵니다. myson.say()와 같죠. 이처럼 오버라이딩이 되면 형 변환으론 부모 메소드에 접근할 수 없습니다. 그럼 어떻게 접근할까요? 3번째 줄에 적혀있는 super라는 키워드가 부모의 재산(변수/메소드)에 접근 가능하도록 해줍니다. 
결국 (3) 코드의 결과는 "부모 자손"이라는 결과를 뽑게 되죠.

하이딩은 다릅니다! 형 변환으로 접근이 가능하죠. 이유는 단순히 숨기기 때문입니다.
예를 보시죠. 달라진 것은 say()메소드 앞에 static 키워드가 붙은 것뿐입니다.(부모/자손 say 둘 다)


(4)public class son extends parent{
	public static void say() {
		System.out.println("자손");
	}

	public static void main(String[] args) {
		son myson = new son(); // son 객체생성
		parent myparent = (parent)myson; // parent객체 생성
		myparent.say(); //부모
	}

(4) 번 코드를 수행하면 어떻게 될까요? 설명드렸듯 static으로 설정된 메소드는 오버라이딩이 되는 것이 아닌 하이딩이 되는 것이기에 "부모"라는 출력이 나옵니다. 부모 메소드 say()에 접근했단 것이죠.
그럼 왜 하이딩(hidding)을 하는 것일까요?? 이 부분은 static에 대해서 알아야 합니다. 여기선 간단하게 설명한 후 끝내도록 하죠. 
static 키워드는 하나만 쓰겠다는 것입니다. 무슨 말인고 하니..
A 클래스 안에 static int a =3; 이 되어있다고 합시다.
A newA = new A(); ,  A newA2 = new A();를 이용해 2개의 객체를 만들었다고 했을 때, 이 객체 안에 들어있는 int a는  A, A2 객체가 공유하고 있는 겁니다. 그래서 A.a=5로 변경을 하면, A2.a는 5가 되듯 공유하고 있는 것이죠. 이렇게 static 키워드는 하나를 공유하여 사용한다는 개념이기에 객체가 생성되기도 전에 미리 만들어져 있죠. 이와 같은 특성 때문에 객체를 만들지 않아도 static은 클래스명.~~로 접근이 가능합니다. 오늘은 이 정도만 설명하겠습니다.

언제든지 접근 가능해야 하는 static의 특성 때문에 hidding(은닉)으로써 super 키워드를 사용하지 않고 접근이 가능하도록 해준 것이죠. 하지만 static은 C의 전역변수 역할을 하기에 객체지향 언어인 java에선 사용을 자제하는 편입니다.

마지막으로 오버 로딩(Overloading)입니다. 오버라이딩은 상속관계 메소드의 이름, 매개변수가 같을 때 일어나지만, 오버 로딩은 메소드 이름이 같고 매개변수가 '다를 때' 일어납니다. 예제를 보시면 명확히 이해하실 수 있습니다.

(5)public class son {	
	public void say() {
		System.out.println("void say");
	}
	public void say(int k) {
		System.out.println("int say");
	}
	public void say(char a) {
		System.out.println("char say");
	}

	public static void main(String[] args) {
		son myson = new son(); // son 객체생성
		myson.say(); //void say
		myson.say('d'); //char say
		myson.say(4); //int say
	}
}

(5) 코드를 보시면 say메소드가 3개 존재합니다. 하지만 각각 매개변수 받는 형태가 다르죠.
이렇게 메소드 이름이 같고 매개변수를 받는 형태가 다른 것을 오버 로딩이라고 합니다.
오버 로딩을 하여 메소드를 수행하게 되면, 매개변수에 맞게 알맞은 메소드를 수행시켜 줍니다.
say()를 했을 땐 알아서 void say를 출력해주고, say('d')를 했을 땐 char say를 출력해 주듯 말이죠.

오늘도 코드적으로 뜯어보기보단 이론적인 설명이었습니다. 개념들 잘 익히시고 static 메소드는 왜 hiding이 되는지 정도만 알아두시면 될 것 같습니다.

다음은.. this, super 와 같은 키워드에 대해서 이야기해 보겠습니다.

반응형
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/12   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31
글 보관함