<상속>
부모 클래스에 만들어진 필드와 메소드를 자식 클래스가 물려받는 것이다.
동일한 특성을 재정의할 필요가 없어 자식 클래스가 간결해진다.
자바에서는 부모 클래스를 슈퍼 클래스, 상속받는 자식 클래스를 서브 클래스라고 부른다.
<상속과 생성자>
• 서브 클래스/슈퍼 클래스의 생성자 호출 및 실행
new에 의해 서브 클래스의 객체가 생성될 때 슈퍼클래스 생성자와 서브 클래스 생성자가 모두 실행된다.
호출 순서 : 서브 클래스의 생성자가 먼저 호출, 서브 클래스의 생성자는 실행 전 슈퍼 클래스 생성자 호출
실행 순서 : 슈퍼 클래스의 생성자가 먼저 실행된 후 서브 클래스의 생성자가 실행된다.
원칙적으로 서브 클래스의 개발자가 서브 클래스의 각 생성자에 대해 함께 실행될 슈퍼 클래스의 생성자를 지정해야 한다.
하지만 개발자의 명시적 지시가 없으면 컴파일러가 자동으로 슈퍼 클래스의 기본 생성자를 선택한다.
그렇다면 기본 생성자 없이 A(int x)만 작성한 경우에는 어떻게 될까?
클래스에 아무 생성자도 선언되지 않은 경우에만 컴파일러에 의해 기본 생성자가 강제로 삽입된다.
다음은 서버 클래스에 매개변수를 가진 생성자의 경우이다.
그럼 명시적으로 슈퍼 클래스의 생성자를 선택할 수 있는 방법은 무엇일까?
서브 클래스의 생성자에서 super()을 이용하면 된다!
<업캐스팅과 instanceof 연산자>
캐스팅이란 타입 변환을 말한다.
자바에서 클래스에 대한 캐스팅은 업케스팅과 다운캐스팅으로 나뉜다.
• 업캐스팅
서브 클래스 객체를 슈퍼 클래스 타입으로 변환하는 것을 업케스팅이라고 한다.
class Person {...}
class Student extends Person {...}
Student s = new Student();
Person p = s; // 업캐스팅, 자동타입변환
• 다운캐스팅
업캐스팅과 반대로 슈퍼 클래스 객체를 서브 클래스 타입으로 변환해주는 것을 말한다.
개발자의 명시적 타입 변환이 필요하다.
class Person {...}
class Student extends Person {...}
...
Person p = new Student("이재문"); // 업캐스팅
...
Student s = (Student)p; // 다운캐스팅, (student)의 타입 변환 표시 필요
- instanceof 연산자
슈퍼 클래스는 여러 서브 클래스에 상속되기 때문에 업케스팅된 레퍼런스로 객체의 타입 판단이 어렵다.
따라서 레퍼런스가 가리키는 객체의 타입 식별을 위해 instanceof 연산자를 사용한다.
레퍼런스 instance of 클래스명
<메소드 오버라이딩>
슈퍼 클래스의 메소드를 서브 클래스에서 재정의하는 것을 매소드 오버라이딩이라고 한다.
메소드 무시하기, 덮어쓰기로 변역되기도 한다.
메소드 오버라이딩은 슈퍼 클래스의 메소드를 무시하고 서브 클래스에서 오버라이딩된 메소드가 무조건 실행되도록 하는 동적 바인딩을 유발시킨다.
다음은 Shape 클래스의 draw() 메소드를 Line, Rect, Circle 클래스에서 각각 오버라이딩한 사례이다.
• 오버라이딩 vs 오버로딩
비교 요소 | 메소드 오버로딩 | 메소드 오버라이딩 |
선언 | 같은 클래스나 상속 관계에서 동일한 이름의 메소드 중복 작성 |
서브 클래스에서 슈퍼 클래스에 있는 메소드와 동일한 이름의 메소드 재작성 |
관계 | 동일한 클래스 내 혹은 상속 관계 | 상속 관계 |
목적 | 이름이 같은 여러 개의 메소드 중복 작성하여 사용의 편리성 향상. 다형성 실현 |
슈퍼 클래스에 구현된 메소드를 무시하고 서브 클래스에서 새로운 기능의 메소드를 재정의하고자 함. 다형성 실현 |
조건 | 메소드 이름은 반드시 동일하고, 매개변수 타입나 개수가 달라야 성립 |
메소드의 이름, 매개변수 타입과 개수, 리턴 타입이 모두 동일하여야 성립 |
바인딩 | 정적 바인딩. 호출될 메소드는 컴파일 시에 결정 |
동적 바인딩. 실행 시간에 오버라이딩된 메소드 찾아 호출 |
<추상 메소드와 추상 클래스>
• 추상 메소드
선언되어 있으나 구현되어 있지 않은 메소드로, abstract로 선언한다.
public abstract String getName();
public abstract void setName(String s);
추상 클래스 2종류
1. 추상 메소드를 하나라도 가진 클래스
클래스 앞에 반드시 abstract라고 선언해야 한다.
2. 추상 메소드가 하나도 없지만 abstract로 선언된 클래스
주의할 점은 추상 클래스는 객체를 생성할 수 없다는 것이다.
• 추상 클래스의 상속
1. 추상 클래스의 단순 상속
추상 클래스를 상속받아 추상 메소드를 구현하지 않으면 추상 클래스가 된다.
서브 클래스도 abstract로 선언해야 한다.
2. 추상 클래스 구현 상속
서브 클래스에서 슈퍼 클래스의 추상 메소드를 구현한다.(오버라이딩)
서브 클래스는 추상 클래스가 아니다.
abstract class Shape { // 추상 클래스
public Shape() {}
public void paint() { draw(); }
abstract public void draw(); // 추상 메소드
}
abstract class Line extends Shape { // 추상 클래스. draw()를 상속 받기 때문
public String toString() { return "Line";}
}
'CS > 객체지향프로그래밍' 카테고리의 다른 글
[객체지향프로그래밍] #7 제네릭과 컬렉션 (0) | 2024.06.13 |
---|---|
[객체지향프로그래밍] #6 모듈과 패키지 (0) | 2024.06.09 |
[객체지향프로그래밍] #4 클래스와 객체 (0) | 2024.04.21 |
[객체지향프로그래밍] #3 배열 (0) | 2024.04.18 |
[객체지향프로그래밍] #2 자바 기본 프로그래밍(2) (0) | 2024.04.14 |