현실 세계에서 상속은 부모의 재산을 자신이 물려받는 것이다. 하지만, 객체 지향 언어에서 상속은 재산 상속이 아니라 부모의 생물학적 특성을 물려받는 유전에 가깝다.
정확히 말하면, 객체 지향에서 상속은 부모 클래스에 만들어진 필드와 메소드를 자식 클래스가 물려받는 것이다. 상속 선언만 하면, 자식 클래스는 부모 클래스에 만들어진 필드와 메소드를 만들지 않고도 만든 것과 같은 효과를 얻는다.
한가지 분명히 짚고 넘어가야할 것은, 상속은 클래스 사이의 상속이지 객체 사이의 상속이 아니라는 점이다. 다시 말해, 자식 객체는 자식 클래스와 부모 클래스에 만들어진 모든 멤버를 가지고 생성된다.
자바에서 상속이 필요한 예를 들어보자. 개발자가 4개의 클래스를 작성한다고 하자. 4개이 클래스에는 '말하기','먹기','걷기','잠자기'의 코드가 공통으로 들어있다. 만일 '말하기' 멤버에 오류가 있어 수정하게 되면, 4개의 클래스를 모두 수정해야 하고, '걷기' 코드를 개선하고자 하면 역시 4개의 클래스를 모두 수정하여야 한다. 이처럼 코드가 중복되면 클래스의 유지 보수가 여간 번거롭지 않다.

상속을 이용하면 이 문제는 간단히 해결된다. 공통된 코드를 모아 Person 클래스를 작성하고, 나머지 클래스를 상속 관계로 선언하면 코드를 중복 작성할 필요 없이 물려받기만 하면 된다. 그림에서 화살표가 위로 향하는 것은 아래 클래스가 위 클래스를 상속받아 확장함(extend)을 뜻한다. Student 클래스는 Person 클래스를 상속받고 '공부하기' 멤버만 만들면 되고, StudentWorker 클래스는 Student 클래스를 상속받아 '일하기'만 만들면 된다.

자바에서는 부모 클래스를 슈퍼 클래스(super class), 상속받는 자식 클래스를 서브 클래스(sub class)라고 부르며, 상속을 선언할 때 확장한다는 뜻을 가진 extends 키워드를 사용한다.
public class Person { // 슈퍼 클래스
...
}
// Person을 상속받는 클래스 Student 선언
public class Student extends Person { // 서브 클래스
...
}
// Student를 상속받는 클래스 StudentWorker 선언
public class StudentWorker extends Student {
...
}
Student 클래스는 Person 클래스의 멤버를 물려받으므로, Person 클래스에 선언된 필드나 메소드를 다시 반복하여 작성할 필요가 없고, 필드나 메소드를 추가 작성하면 된다. StudentWorker가 Student를 상속받으면 Person 클래스의 멤버도 자동 상속받는다.
(x,y)의 한 점을 표현하는 Point 클래스와 이를 상속받아 색을 가진 점을 표현하는 ColorPoint 클래스를 만들고 활용하는 예시를 들어보자.
class Point {
private int x, y; // 한 점을 구성하는 x, y 좌표
public void set(int x, int y) {
this.x = x; this.y = y;
}
public void showPint() { // 점의 좌표 출력
System.out.println("(" + x + "," + y + ")");
}
}
class ColorPoint extends Point { // Point를 상속받은 ColorPoint 선언
private String color; // 점의 색
public void setColor(String color) {
this.color = color
}
public void showClorPoint() { // 컬러 점의 좌표 출력
System.out.print(color);
showPoint(); // Point 클래스의 showPoint() 호출
}
}
public class ColorPointEx {
public static void main(String [] args) {
Point p = new Point(); // Point 객체 생성
p.set(1, 2); // Point 클래스의 set() 호출
p.showPoint();
ColorPoint cp = new ColorPoint(); // ColorPoint 객체 생성
cp.set(3, 4); // Point 클래스의 set() 호출
cp.setColor("red"); // ColorPoint 클래스의 setColor() 호출
cp.showColorPoint(); // 컬러와 좌표 출력
}
}
실행결과
(1,2)
red(3,4)
Point를 상속받는 ColorPoint 클래스의 상속 선언은 다음과 같다.
class ColorPoint extends Point {
...
}
상속에서 일차적으로 이해해야 하는 것은 바로 서브 클래스 객체의 모양이다. 다음은 Point 클래스의 객체와 ColorPoint 클래스의 객체를 생성하는 코드이다.
Point p = new Point();
ColorPoint cp = new ColorPoint(); // 서브 클래스 객체 생성
생성된 객체 p와 cp를 보여준다. 이 둘은 서로 별개의 객체이다. 객체 p는 Point 클래스의 멤버만 가지고, cp는 Point 클래스와 ColorPoint 클래스의 멤버를 모두 가진다. 상속은 바로 cp 객체처럼 슈퍼 클래스의 멤버와 서브 클래스의 멤버를 모두 갖고 탄생하게 하는 것이다.
다른 클래스에서 Point 객체와 ColorPoint 객체의 멤버를 접근하는 코드 사례를 보여준다. 특히 주목할 부분은 cp 객체에 대한 접근이다. ColorPointEx 클래스의 main() 메소드에서는 cp 객체를 구성하는 ColorPoint 클래스의 public 멤버와 슈퍼 클래스인 Point 클래스의 public 멤버를 모두 접근할 수 있다. 그러나 x, y, color 필드는 private 속성이어서 접근할 수 없다.
서브 클래스는 슈퍼 클래스의 private 멤버를 제외하고 모든 멤버를 접근할 수 있다. ColorPoint 클래스의 showColorPoint()가 슈퍼 클래스의 showPoint()를 호출하는 것을 보여준다. 이들은 모두 cp 객체 내에 있는 코드들이다. 하지만, x, y는 Point의 private 멤버로 오직 set()과 showPoint()에게만 접근이 허용되므로, ColorPoint 클래스의 메소드들은 접근할 수 없다.
자바는 클래스를 여러 개 상속받는 다중 상속을 지원하지 않는다. 그러므로 extends 다음에는 클래스 이름을 하나만 지정할 수 있다.
자바에서는 상속의 횟수에 제한을 두지 않는다.
자바에서 계층 구조의 최상위에 java.lang.Object 클래스가 있다.
사용자가 만들든 자바패키지에서 제공하든, 자바에서 모든 클래스는 Object 클래스를 자동으로 상속받도록 컴파일된다. Object를 상속받도록 선언하지 않더라도 마찬가지다.
예제에서 Point 클래스가 다른 클래스를 상속받는다고 선언하지 않았지만, 컴파일이 끝나면 Object를 상속받게 된다. 그러므로 자연스럽게 ColorPoint 클래스도 Object를 상속받게 된다. Object 클래스만이 유일하게 슈퍼 클래스를 가지지 않는다.