기존의 클래스로 새로운 클래스를 작성하는 것(코드의 재사용)
두 클래스를 부모와 자식으로 관계를 맺어주는 것
class 자식클래스 extends 부모클래스 {}
class Parent {}
class Child extends Parent { } // 상속 관계
자손은 조상의 모든 멤버를 상속받는다.(생성자, 초기화블럭 제외)
자손의 멤버 개수는 조상보다 적을 수 없다.(같거나 많음)
class Parent {
int age; // 멤버 1개
}
class Child extends Parent { } // 자신의 멤버 0개, 상속받는 멤버 1개 = 총 멤버 1개
자손의 변경은 조상에 영향을 미치지 않는다.
단, 조상의 변경은 자손에 영향을 미친다.
class Parent {
int age; // 멤버 1개
}
class Child extends Parent { // 자신의 멤버 1개, 상속받은 멤버 1개 = 총 멤버 2개
void play() { // 새로운 멤버 추가
System.out.println("놀자~");
}
}
클래스의 멤버로 참조변수를 선언하는 것
작은 단위의 클래스를 만들고, 이 들을 조합해서 클래스를 만든다.
class Point {
int x;
int y;
}
class Circle {
Point c = new Point(); // 원점
int r; // 반지름(radius)
}
상속관계 ~은 ~이다. (is-a)
포함관계 ~은 ~을 가지고 있다. (has-a)
class Circle extends Point { int r; }
❌ 원(Circle)은 점(Point)이다 - Circle is a Point.
상속은 꼭 필요할 때만.
class Circle { Point c = new Point(); int r; }
⭕️ 원(Circle)은 점(Point)을 가지고 있다. - Circle has a Point.
90%가 포함관계.
Java는 단일상속만을 허용한다.(c++은 다중상속 허용)
class TvDVD extends Tv, DVD { } // 에러! 조상은 하나만 허용된다.
비중이 높은 클래스 하나만 상속관계로, 나머지는 포함관계로 한다.
부모가 없는 클래스는 자동적으로 Object클래스를 상속받게 된다.
모든 클래스는 Object 클래스에 정의된 11개의 메서드를 상속받는다.
toString(), equals(Object obj), hashCode(), ...
class Tv {} // 부모가 없는 클래스
class Tv extends Object {} // 컴파일러가 자동 추가
상속받은 조상의 메서드를 자신에 맞게 변경하는 것
class Point {
int x;
int y;
String getLocation() {
return "x:"+x+", y:"+y;
}
}
선언부 변경 불가.
내용만 변경 가능(구현부 {})
조상의 getLocation()을 오버라이딩
class Point3D extends Point {
int z;
String getLocation() { // 오버라이딩
return "x:"+x+", y:"+y+", z:"+z;
}
- 선언부가 조상 클래스의 메서드와 일치해야 한다.
String getLocation() - 선언부(반환타입, 메서드이름, 매개변수 목록)- 접근 제어자를 조상 클래스의 메서드보다 좁은 범위로 변경할 수 없다.
public, protexted, default, private- 예외는 조상 클래스의 메서드보다 많이 선언할 수 없다.
조상이 예외 2개일 때 자손도 작거나 같아야 함
이름만 비슷하지 전혀 관계가 없는데... 차이를 물을 때가 있기 때문에 알아가자
오버로딩: 기존에 없는 새로운 메서드를 정의하는 것(new, 이름이 같음) -> 상속과 관계 X
오버라이딩: 상속받은 메서드의 내용을 변경하는 것(change, modify) -> 상속과 관계 O
class Parent {
void parentMethod() {}
}
class Child extends Parent {
void parentMethod() {} // 오버라이딩
void parentMethod(int i) {} // 오버로딩
void childMethod() {} // 메서드 정의
void childMethod(int i) {} // 오버로딩
void childMethod() {} // 에러! 중복 정의
}
객체 자신을 가리키는 참조변수. 인스턴스 메서드(생성자)내에만 존재
조상의 멤버를 자신의 멤버을 구별할 때 사용
(this와 비슷, this는 lv와 iv를 구별할 때 사용)
class Ex {
public static void main(String args[]) {
Child c = new child();
c.method();
}
}
class Parent { int x = 10; } // super.x
class Child extends Parent {
int x = 20; // this.x
void method() {
System.out.println("x="+x); // x=20
System.out.println("this.x="+this.x); // this.x=20
System.out.println("super.x="+super.x); // super.x=10
}
}
조상의 생성자를 호출할 때 사용
조상의 멤버는 조상의 생성자를 호출해서 초기화
class Point {
int x, y;
Point(int x, int y) {
this.x = x;
this.y = y;
}
}
class Point3D extends Point {
int z;
Point3D(int x, int y, int z) {
super(x, y); // 조상클래스의 생성자 Point(int x, int y)를 호출
this.z = z; // 자신의 멤버를 초기화
}
}
🌟생성자의 첫 줄에 반드시 생성자를 호출해야 한다.
그렇지 않으면 컴파일러가 생성자의 첫 줄에 super();를 삽입