오버라이딩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;
}
}
오버라이딩 조건
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. 오버로딩
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메서드에서는 사용할 수 없고 인스턴스메서드에서만 사용할 수 있다.
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();
}
}
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();
}
}
super()
this()와 마찬가지로 super() 역시 생성자이다. 다른점은 this()는 같은 클래스의 다른 생성자를 호출하는 데 사용되지만, 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;
}
}