Dreaming Dean
Hello, I'm Studying
  • Secure
  • Java
  • Oracle
  • +others
Coding.
I AM STUDYING PROGRAMING LANGUAGE. IF YOU WANT TO SEE MY WORK THE PROGRAMMING PROJECT, CHECK IT OUT MY BLOG AND GITHUB.

Overriding and Overloading 오버라이딩과 오버로딩

Dean92
2017. 5. 26. 22:54

오버라이딩Overriding

 오버라이딩Overriding은 객체 지향 관점에서 서브클래스 또는 자식 클래스가 자신의 슈퍼클래스들 또는 부모 클래스들 중 하나에 의해 이미 제공된 메소드를 특정한 형태로 구현하는 것을 말한다. 즉 조상 클래스로부터 상속받은 메서드의 내용을 변경하는 것을 말한다. 상속받은 메서드를 원본 그대로 사용하기도 하지만 많은경우 자식 클래스만의 특징에 맞게 변경해야하는 경우가 훨씬 많고 이 때 부모 클래스를 오버라이딩 한다.

“조상클래스로부터 상속받은 메서드의 내용을 상속받는 클래스에 맞게 변경하는 것을 오버라이딩이라고 한다.”
class Point {
	int x;
	int y;
	
	String getLocation(){
		return "x : " + x + ", y : " + y;
	}
}

class Pint3D extends Point {
	int z;
	String getLocation() {	//오버라이딩
		return "x : " + x + ", y : " + y + ", z : " + z;
	}
}
오버라이딩 조건
  • 선언부(이름, 매개변수, 리턴타입)가 같아야 한다.
  • 접근제어자를 좁은 범위로 변경할 수 없다.
  • - 조상의 메서드가 protected라면, 범위가 같거나 넓은 protected나 public으로만 변경할 수 있다.
  • 조상클래스의 메서드보다 많은 수의 예외를 선언할 수 없다.
  • class Parent {
    	void parentMethod() throws IOException, SQLException {
    		// ...
    	}
    }
    
    class Child extends Parent {
    	void parentMethod() throws IOException {
    		// ...
    	}
    }
    
    class Child2 extends Parent {
    	void parentMethod() throws SQLException {
    		// ...
    	}
    }
    


    오버로딩Overloading

     메서드도 변수와 마찬가지로 같은 클래스 안에서 각각 다른 이름을 붙여 구분 되게 하여야 하지만 자바에서는 한 클래스내에 같은 이름의 메서드가 있다고 하더라도 매개변수의 개수 또는 타입이 다르면 같은 이름을 붙여 메소드를 정의할 수 있다.

    "하나의 클래스에 같은 이름의 메소드여러 개 정의하는것을 오버로딩이라고 한다."


    오버로딩 조건
  • 메서드의 이름이 같아야 한다
  • 매개변수의 개수 또는 타입이 달라야 한다.
  • 매개변수는 같고 리턴타입이 다른 경우는 오버로딩이 성립되지 않는다.
  • - 오버로딩된 메소드는 호출시 전달하는 인자를 통해서 구분
    class AAA {
    	//오버로딩된 메소드들
    	void isYourFunc(int n) { }
    	void isYourFunc(int n1, int n2) { }
    	void isYourFunc(int n1, double n2) { }
    }
    
    public static void main(String[] args) {
    	AAA inst = new AAA();
    	inst.isYourFunc(10, 'a');
    	//문자 'a'는 int형으로도 double형으로도 변환이 가능하다.
    	//결론적으로 형변환 규칙을 적용하되 가장 가까운 
    	//위치의 자료형으로 변환이 이루어진다.
    	//따라서 isYourFunc(int n1, int n2) 가 호출된다.
    }
    
    "형변환의 규칙까지 적용해야 메소드가 구분되는 상황은 만들지 않는 것이 좋다."


    오버라이딩 vs. 오버로딩

    오버라이딩Overriding   상속받은 메소드의 내용을 변경하는 것
    Vs.
    오버라이딩Overloading   기존에 존재하지 않는 새로운 메소드를 정의하는 것
    class Parent {
    	void parentMethod() { }
    }
    
    class Child extends Parent {
    	void parentMethod() { }		//오버라이딩
    	void parentMethod(int i) { }	//오버로딩
    	
    	void childMethod() { }
    	void childMethod(int i) { }		//오버로딩
    	void childeMethod() { }		//중복정의로 인한 컴파일 에러
    }
    


    super

     super는 자손 클래스에서 조상 클래스로부터 상속받은 멤버를 참조하는데 사용되는 참조변수이다. 앞선 포스팅에서 멤버변수와 지역변수의 이름이 같을 때 this를 사용해서 구별했듯이 상속받은 멤버와 자신의 클래스에 정의된 멤버의 이름이 같을 때 super을 사용한다.

     조상 클래스로부터 상속받은 멤버도 자손 클래스 자신의 멤버이므로 super대신 this를 사용할 수 있다. 그러므로 조상 클래스의 멤버와 자손클래스의 멤버가 중복 정의되어 서로 구별해야하는 경우에 super을 사용한다.

     조상의 멤버와 자신의 멤버를 구별하는데 사용되는 점을 제외하면 super와 this는 같다. 모든 인스턴스화 된 메서드에서는 자신이 속한 인스턴스의 주소가 지역변수로 저장되는데 이것이 참조변수인 this와 super의 값이 된다.

     static메서드(클래스메서드)는 인스턴스와 관련이 없기 때문에 this와 마찬가지로 super 역시 static메서드에서는 사용할 수 없고 인스턴스메서드에서만 사용할 수 있다.

    super ▶   this와 같다. 조상의 멤버와 자신의 멤버를 구별하는 데 사용된다.
    Vs.
    this ▶   인스턴스 자신을 가리키는 참조변수. 인스턴스의 주소가 저장되어있다. 모든 인스턴스 메서드에 지역변수로 숨겨진 채로 존재한다.
    class Parent {
    	int x = 10;
    }
    
    class Child extends Parent {
    	void method() {
    		System.out.println("x=" + x);
    		System.out.println("this.x=" + this.x);
    		System.out.println("super.x" + super.x);
    	}
    }
    
    class SuperTest {
    	public static void main(String args[]) {
    		Child c = new Child();
    		c.method();
    	}
    }
    
    x, this.x super.x 모두 같은 변수를 의미하므로 모두 같은 값 10이 출력된다.
    class Parent {
    	int x = 10;
    }
    
    class Child extends Parent {
    	int x = 10;
    	void method() {
    		System.out.println("x=" + x);
    		System.out.println("this.x=" + this.x);
    		System.out.println("super.x" + super.x);
    	}
    }
    
    class SuperTest2 {
    	public static void main(String args[]) {
    		Child c = new Child();
    		c.method();
    	}
    }
    
    같은 이름의 멤버변수가 조상 클래스인 Parent에도 있고 자손 클래스인 Child클래스에도 있을 때는 super.x와 this.x는 서로 다른 값을 참조하게 된다. super.x는 조상 클래스로부터 상속받은 멤버변수 x를 뜻하며 this.x는 자손 클래스에 선언된 멤버변수를 뜻한다. 즉 x=20, this.x=20, super.x=10 이다.
     조상 클래스에 선언된 멤버변수와 같은 이름의 멤버변수를 자손 클래스에서 중복해서 정의하는 것이 가능하며 참조변수 super를 이용해서 서로 구별 할 수 있다.


    super()

    this()와 마찬가지로 super() 역시 생성자이다. 다른점은 this()는 같은 클래스의 다른 생성자를 호출하는 데 사용되지만, super()는 조상 클래스의 생성자를 호출하는데 사용된다.

    자손 클래스의 멤버가 조상 클래스의 멤버를 사용할 수도 있으므로 조상의 멤버들이 먼저 초기화되어 있어야 하기 때문에 생성자의 첫 줄에서 조상클래스의 생성자를 호출해야 한다.

  • 자손클래스의 인스턴스를 생성하면, 자손의 멤버와 조상의 멤버가 합쳐진 하나의 인스턴스가 생성된다.
  • 조상의 멤버들도 초기화되어야 하기 때문에 자손의 생성자의 첫 문장에서 조상의 생성자를 호출해야 한다.
  • Object클래스를 제외한 모든 클래스의 생성자 첫 줄에는 생성자, this() 또는 super()를 호출해야 한다. 그렇지 않으면 컴파일러가 자동적으로 super();를 생성자의 첫 줄에 삽입한다
    class Point {
    	int x;
    	int y;
    	
    	Point(int x, int y) {
    		this.x = x;
    		this.y = y;
    	}
    	
    	String getLocation() {
    		return "x :" + x + ",y :" + y; 
    	}
    }
    
    class Point3D extends Point {
    	int z;
    	Point3D(int x, int y, int z) {
    		/*
    		 * 생성자 첫 줄에서 다른 생성자를 호출하지
    		 * 않기 때문에 컴파일러가 super();를 이곳에
    		 * 삽입한다.
    		 * super()는 Point3D의 조상인 Point클래스의
    		 * 기본생성자인 Point()를 의미한다.
    		 */
    		
    		//super(x, y)를 삽입하면 컴파일 에러가 사라진다.
    		this.x = x;
    		this.y = y;
    		this.z = z;
    	}
    	
    	String getLocation() {		//오버라이딩
    		return "x :" + x + ",y :" + y + ", z : " + z; 
    	}
    }
    
    조상 클래스의 멤버변수는 조상의 생성자에 의해 초기화되도록 해야한다.

    Comments