2018년 9월 8일 토요일

Java클래스의 다형성 - 3 하이딩

이전시간에 클래스의 다형성 1, 2에 대해서 알아보았다.

지금까지 알아본 클래스의 다형성이란
상속하는 클래스에서 부모클래스의 클래스 타입형으로 객체를 생성하는데, 이때 객체를 부여한 클래스는 자식 클래스로서 부모클래스의 멤버 변수 / 메소드에(오버라이딩 제외)만 접근할 수 있도록 제한을 두었다.
또한 클래스 타입이 인터페이스로 생성한 객체의 오버라이딩 되어있는 메소드 사용해보기도 했었다.

이번에는 하이딩이라고 하는 자바 클래스 다형성이 될 수 없게끔 하는 방법을 소개하겠다.
이 하이딩이라고 하는걸 모르기전에는 다음과 같은 코드를 잘 못 이해했었다.

예제 - 자바 다형성 이해하기

  1. package org.java.project1.subproject2;
  2. interface Calculator{
  3.     public void _execute();
  4. }
  5. class Op implements Calculator{
  6.     int left;
  7.     int right;
  8.     public Op(int left, int right){
  9.         this.left = left;
  10.         this.right = right;
  11.     }
  12.     public void _execute(){
  13.         System.out.println("오버라이딩 될 메소드입니다.");
  14.     }
  15.     public static void execute(Op o){
  16.         o._execute();
  17.     }
  18. }
  19. class Plus extends Op{
  20.     public String name;
  21.     public Plus(int left, int right, String name){
  22.         super(left, right);
  23.         this.name = name;
  24.     }
  25.     public void _execute(){
  26.         int result = this.left + this.right;
  27.         System.out.println(this.name + "의 계산결과 : " + result);
  28.     }
  29. }
  30. class Minus extends Op{
  31.     public String name;
  32.     public Minus(int left, int right, String name){
  33.         super(left, right);
  34.         this.name = name;
  35.     }
  36.     public void _execute(){
  37.         int result = this.left - this.right;
  38.         System.out.println(this.name + "의 계산결과 : " + result);
  39.     }
  40.     // @Override 오버라이딩 명시를 해주면 에러가 발생한다.
  41.     public static void execute(Calculator c){   // 인자값으로 부모와는 다르게, 클래스 타입 Calculator를 입력받게한다.
  42.         System.out.println("hi, i`m hidding!");
  43.         c._execute();
  44.     }
  45. }
  46. public class project2{
  47.     public static void main(String[] args){
  48.         Op minus = new Minus(52"뺄셈");
  49.         Op plus = new Plus(15"덧셈");
  50.         Calculator c_minus = new Minus(31"뺄셈2");
  51.         Calculator cal = new Op(12);
  52.        
  53.         Minus realMinus = new Minus(77"뺄셈1");
  54.         Op.execute(minus);
  55.         Op.execute(realMinus); // 객체가 속해있는 클래스에서의 execute()가 아닌 전역에서의 즉, 최초실행된 Op내부의 execute()가 실행되는 것이다.
  56.        
  57.         Op.execute(plus);
  58.         cal._execute();
  59.     }
  60. }

▶ 실행결과
뺄셈의 계산결과 : 3
덧셈의 계산결과 : 6
오버라이딩 될 메소드입니다.




 이 코드를 설명하기전에 우리는 static이 오버라이딩 되지않는다는 것을 알고있어야한다.
왜? 그 이유는 컴파일 관련된 내용인데, 간단하게 이야기를 하면 자바 컴파일이 실행될때
static은 전역변수로서, 런타임시 컴파일 시작과 동시에 선언된 타입의 메소드를 호출하게 된다 . 즉, 다형성의 오버라이딩과 같이 클래스에 있는 메소드를 실제 객체가 생성한 메소드를 호출하는것이 아닌 본래의 선언된 타입의 메소드를 호출함. 즉, static은 전역변수로서의 역할을 수행한다고 보면된다.

위에서의 코드는 조금 이해하기 힘들 수도 있다. 자바의 하이딩이라고 하는건데, 클래스에 static으로 선언된 메소드를 오버라이딩하는것과 같이 선언해주는데, 클래스를 인스턴스화 하여 호출시에 최초 선언한 클래스의 static메소드가 실행하게 된다. 즉, 객체에 해당하는 클래스에서 호출하는것 같지만, 실제로는 전역 static메소드가 실행되는것이다.

위 코드를 설명하면, 다음 2가지를 살펴볼수있다.

1) 53번줄 자바의 다형성을 이용해서 minus는 Minus에 속해있으나 부모인 Op에 제한시켜놓았다.

2) 59번줄은 본인 클래스에 속하도록 평범한 인스턴스화 방식이다.

그런데, 두 가지다 Minus클래스 내부의 static 으로 선언된 execute()에 접근은 할 수 없다. 바로 위에 설명한 하이딩 기법으로, 자바 런타임때의 static은 최초 선언된 것을 찾아서 호출하기 때문이다.

이제 우리는 하이딩기법, 자바런타임때의 static을 호출하는 방식을 알게되었다.

다음시간에는 예외처리에 대해서 살펴보겠다. 


댓글 없음:

댓글 쓰기

[Java] N-I/O(Non-Blocking) 파일 읽기 쓰기 - GatheringByteChannel, ScatteringByteChannel, ByteBuffer 사용.

우리는 지금까지 다음과 같이 살펴보았다. 1.  InputStream / OutputStream : 입, 출력 스트림을 바이트로 처리하여 읽기, 쓰기. 2.  FileInputStream / FileOutputStream : 입, 출력 스트림을 ...