[JAVA] 오버라이딩된 멤버 변수와 메소드가 다르게 움직이는 이유

inheritance, overriding, member variable, method

Posted by iheese on April 20, 2022 · 4 mins read

Parent.java

public class Parent{
	String name="Parent";
    
    public void showInfo(){
    	System.out.println("부모 클래스 입니다.");
    }
}

Child.java

public class Child extends Parent{
    String name= "Child";
    
    public void showInfo(){
    	System.out.println("자식 클래스입니다.");
    }
}

  • 부모 클래스를 상속 받고 자식 클래스는 멤버변수, 메소드를 오버라이딩했다.

Main.java

public class Main {
	public static void main(String[] args){
	Parent parent =new Child();
		System.out.println(parent.name);
		parent.showInfo();
		//Parent
		//자식 클래스입니다.
	}
}

  • 묵시적 형 변환을 통해 변수를 선언했을 때 오버라이딩된 메소드와 멤버 변수가 접근할 수 있는 범위가 달랐다.
  • 묵시적 형 변환된 변수에서 오버라이딩된 멤버변수는 부모의 멤버 변수만 접근할 수 있었고 메소드는 자식의 메소드만 사용할 수 있었다.


  • 이에 대한 해답은 Variable Hiding 이라는 현상을 통해 이해할 수 있었다.
  • Variable Hiding : 자식의 변수와 부모의 변수가 같은 이름일 때 자식의 변수가 부모의 변수를 감추는 것을 의미한다.
public class Parent{
	String name = "Parent";
    
}

public class Child extends Parent{
    String name = "Child";
   
}

public class Main {
		 //Variable Hiding
		Child child = new Child();
		System.out.println(child.name); //Child 
		Parent parent = new Parent();
		System.out.println(parent.name); //Parent
		Parent parent2 = new Child();
		System.out.println(parent2.name); //Parent
}
  • 묵시적 형 변환된 변수에는 오버라이딩이 적용되지 않는다.


java가 메소드와 변수에 이런 방식을 적용한 이유는 뭘까?

  • Variable Hiding은 변수에만 적용되는 반면에 Overriding은 메소드에만 적용된다.

변수 오버라이딩을 허용하게 되면 부모로부터 상속받은 메소드에 영향을 줄 수 있기 때문이다.

class Parent{
	int var;
	
	public int plus() {
		return ++var;
    }

	public int multi() {
        return var=var*var;
    }
} 


class Child extends Parent {
	String var;
}

  • 위 같은 예시에서 보면 변수를 오버라이딩하게 되면 타입이 바뀌게 되면서 메소드의 영역까지 모두 사용할 수 없게 된다.
  • 컴파일 시 오버라이딩된 메소드는 호출될 때 가상 메소드에 새롭게 생성되어 부모 클래스의 메소드를 대체하게 된다. 이를 런타임 다형성이라 한다.
  • 컴파일 시 변수는 위 같은 이유로 자식 클래스 변수로 대체되지 않고 기존의 변수를 유지하게 된다. 즉 런타임 다형성을 따르지 않게 된다.


결론

  • 같은 이름으로 오버라이딩한 변수를 사용하여 혼란을 주지 말자.
  • 필요할 때 변수 말고 메소드만 오버라이딩을 하자.


Reference: