자바의 정석3-2 오버라이딩, super 참조변수, super( ) 생성자

자바의 정석3-2 오버라이딩, super 참조변수, super( ) 생성자

오버라이딩(overriding)

- 상속받은 조상의 메서드를 자신에 맞게 변경하는 것(메서드 오버라이딩)

- 선언부는 변경불가, 내용(구현부)만 변경 가능

예제1) Point 조상 클래스의 getLoction( )을 Point3D 클래스가 오버라이딩

getLocation은 원래 x와 y의 값만 나타내지만 Point3D가 오버라이딩이 되어서 x,y,z값이 나타나게 된다!

class Point { int x; int y; String getLocation() { return "x:" + x + ", y:" + y; } } class Point3D extends Point { int z; String getLoction() { // 조상의 getLocation()을 오버라이딩 return "x:" + x + ", y:" + y + ", z:" + z; } }

예제2) 모든 클래스의 조상인 Object클래스의 toString( )메서드를 사용해서 x와 y값을 넣고 출력!

생성자를 사용해서 굳이 x와 y를 따로 초기화해주지 않아도 한 줄의 코드로 x와 y의 값을 나타낼 수 있다.

class Point { int x; int y; Point(int x, int y) { this.x = x; this.y = y; } // Object클래스의 toString()을 오버라이딩 public String toString() { return "x:" + this.x + ", y:" + this.y; //this 참조변수 생략 가능 } } public class Inherit2 { public static void main(String[] args) { Point p = new Point(3,5); // Point 생성자 생성! // p.x = 3; // p.y = 5; // System.out.println("x:" + p.x + ", y:" + p.y); //x:3, y:5 System.out.println(p); //x:3, y:5 // System.out.println(p.toString()); //x:3, y:5 } }

오버라이딩의 조건

1. 선언부가 조상 클래스의 메서드와 일치해야 한다. (선언부: 반환타입, 메서드 이름, 매개변수 목록)

String getLocation() {

return "x:" + x + ", y:" + y;

}

String getLoction() { // 조상의 getLocation()을 오버라이딩

return "x:" + x + ", y:" + y + ", z:" + z;

}

2. 접근 제어자를 조상 클래스의 메서드보다 좁은 범위로 변경할 수 없다.

접근제어자: public protected default point

3. 자손클래스의 예외는 조상 클래스의 메서드보다 많이 선언할 수 없다.

핑크색이 예외 선언

-> 조상 클래스인 Parent는 예외선언 2개 자손 클래스인 Child는 예외선언 1개

오버로딩과 오버라이딩

- 오버로딩과 오버라이딩은 관계 없음(생성자 this( )와 참조변수 this 같이)

오버로딩 (overloading) 오버라이딩 (overriding) 기존에 없는 새로운 메서드를 정의하는 것 (new)

-> 이름이 같음 상속받은 메서드의 내용을 변경하는 것 (change, modify) 상속과 관계없음 상속과 관계 있음

class Parent { void parentMethod() {} } class Child extends Parent { void parentMethod() {} // 오버라이딩 void parentMehhod(int i) {} // 오버로딩, Child안에 이미 같은 이름인 메서드가 있고 매개변수만 다름) void childMethod() {} // 메서드 정의 void childMehthod(int i) {} // 오버로딩, child안에 이미 같은 이름인 메서드가 있고 매개변수만 다름) void childMethod() {} // 중복정의 에러! }

참조변수 super

- 객체 자신을 가리키는 참조변수로 인스턴스 메서드(생성자) 내에만 존재(static 메서드 내에서 사용 불가)

- 조상 멤버를 자신의 멤버와 구별할 때 사용(참조변수 this는 lv와 iv 구별에 사용)

- 조상 멤버는 super 참조변수 사용하고 자신의 멤버는 this 참조변수 사용

예제1) Parent 클래스와 Child 클래스 둘 다 같은 int x 변수가 있는 경우

<출력값>

x = 20

this.x = 20

super.x = 10

public class InheritSuper { public static void main(String args[]) { Child child = new Child(); child.method(); } } class Parent { int x = 10; } class Child extends Parent { //멤버 3개 int x = 20; void method() { System.out.println("x = " + x); // 가까운 쪽 클래스의 x System.out.println("this.x = " + this.x); // Child 클래스의 x System.out.println("super.x = " + super.x); // Parent 조상클래스의 x } }

예제2) Child클래스에는 x변수가 없고 Parent 클래스에만 int x 변수가 있는 경우

<출력값>

x = 10

this.x = 20

super.x = 10

public class InheritSuper { public static void main(String args[]) { Child child = new Child(); child.method(); } } class Parent { int x = 10; } // super.x와 this.x둘 다 가능! class Child extends Parent { //멤버 2개 void method() { System.out.println("x = " + x); // Parent 클래스의 x System.out.println("this.x = " + this.x); // Parent 클래스의 x System.out.println("super.x = " + super.x); // Parent 클래스의 x } }

-> this, super 둘 다 같은 주소를 가리키고 있음

super( ) – 조상의 생성자

- 조상의 생성자를 호출할 때 사용

- 조상의 멤버는 조상의 생성자를 호출해서 초기화

- 참조변수 super와 관계없음

- 조상인 Point 클래스가 iv를 초기화하고 있음

-> 자손의 생성자는 자기가 선언한 것만 초기화한다!(조상의 멤버를 굳이 초기화할 필요 없음)

-> 안 좋은 코드이다!!

-> 코드를 이렇게 바꿔야 함

-> 조상클래스의 생성자가 조상멤버를 초기화하게 해야 함

super( ) – 조상의 생성자 추가 조건

- 생성자의 첫 줄에 반드시 생성자를 호출해야 한다. 그렇지 않으면 컴파일러가 생성자의 첫 줄에 super( );를 삽입(첫 줄에 반드시 super( );를 적어줘야 한다!)

class Point extends Object { int x; int y; Point() { this(0,0); } Point(int x, int y) { super(); // 조상인 Object 클래스의 기본 생성자 호출 this.x = x; this.y = y; } }

예제 Point 조상 클래스와 Point3D 자식 클래스(모든 생성자는 다른 모든 생성자는 다른 생성자를 호출해야 한다는 조건)

class Point { int x; int y; Point(int x, int y) { super(); // 컴파일러가 자동 추가(, Point의 조상인 Object 클래스 생성자 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(x, y); // 조상의 생성자 Point(int x, int y)를 호출 아니면 super( ) 이렇게 적어도 됨 // this.x = x; // this.x = y; this.z = z; } String getLocation() { // 오버라이딩 return "x: " + x + "y: " + y + "z: " + z; } }

from http://everysmallstep.tistory.com/77 by ccl(A) rewrite - 2022-01-01 04:28:17