728x90
👩👦 상속(inheritance)
기존 클래스를 재사용하여 새로운 클래스를 정의하는 것
자식(하위, 파생) 클래스가 부모(상위) 클래스의 멤버를 물려받는 것
Class Vehicle {
public int speed;
public int getSpeed() {
return speed;
}
public void setSpeed(int speed) {
this.speed = speed;
}
}
class Car extends Vehicle {
}
public class Test {
public static void main(String[] args) {
Car A = new Car();
A.getSpeed();
}
}
- 상속 대상 : 부모의 필드와 메소드
- 상속 효과 :
- 부모 클래스를 재사용하여 자식 클래스를 빠르게 개발 할 수 있다.
- 코드의 중복을 줄일 수 있다.
- 프로그램의 생산성과 유지보수성에 크게 기여한다.
- 객체 다형성 구현이 가능하다.
- 생성자와 초기화 블록은 상속되지 않으며 멤버만 상속된다
- 자손 클래스 멤버 개수는 조상 클래스보다 항상 같거나 많다
- 자손 클래스의 인스턴스를 생성하면 조상 클래스의 멤버와 자손 클래스의 멤버가 합쳐진 하나의 인스턴스로 생성된다.
조상 클래스 | 부모(parent) 클래스, 상위(super) 클래스, 기반(base) 클래스 |
자손 클래스 | 자식(child) 클래스, 하위(sub) 클래스, 파생된(derived) 클래스 |
[ 포함 관계 ]
상속이 아닌 클래스 내부에 새로운 클래스를 선언하는 것
class A {
int a;
}
class B {
A test = new A();
int b;
}
상속과의 차이
- 상속 : (is - a) B는 A이다.
- 포함 : (has - a) B는 A를 가지고 있다.
[ 단일 상속 ]
서브클래스가 하나의 슈퍼클래스만 가질 수 있다.
- C++에선 다중 상속을 허용하지만, 자바에서는 오직 단일 상속만을 허용한다.
- 이럴 때에 포함관계를 사용할 수 있다. (상속을 받으면서 포함관계를 하면 두 개의 클래스로부터 사용가능)
- 부모 클래스는 여러 서브 클래스를 가질 수 있음
- ex) Object 클래스
Object 클래스
모든 클래스의 슈퍼 클래스
모든 클래스들은 자동적으로 Object 클래스로부터 상속받게 한다.
📝 오버라이딩(overriding)
슈퍼 클래스로부터 상속받은 메소드의 내용을 재정의하는 것
상속받은 메서드를 그대로 사용하기도 하지만, 자손 클래스에 맞추어 변경이 필요할 때도 있다. 이러할 때에 조상의 메서드를 오버라이딩이라고 한다.
class Food {
private int kcal;
private int price;
private int kg;
public Food(int kcal, int price, int kg) {
this.kcal = kcal;
this.price = price;
this.kg = kg;
}
@Override
public String toString() {
return "Food [kcal=" + kcal + ", price=" + price + ", kg=" + kg + "]";
}
}
class Melon extends Food { //상속
private String where;
public Melon(int kcal, int price, int kg, String where) {
super(kcal, price, kg);
// TODO Auto-generated constructor stub
this.where = where;
}
@Override
public String toString() {
return super.toString() + " Melon [where=" + where + "]";
}
}
public class whatFood {
public static void main(String[] args) {
// TODO Auto-generated method stub
Melon mel = new Melon(100, 4000, 3, "Afganistan");
System.out.println(mel.toString());
}
}
[ 오버라이딩 조건 ]
- 슈퍼 클래스와 이름(메소드 명), 매개변수, 반환타입이 같아야한다.
- 접근제어자는 조상클래스의 메서드보다 좁은 범위로 변경할 수 있다.
- ex ) 조상 클래스의 정의된 메서드의 접근 제어자가 protected
- 이를 오버라이딩하는 자손 클래스의 메서드는 접근 제어자가 protected 또는 public이어야 한다.
- (대부분은 같은 번위의 접근 제어자 사용)
- 슈퍼 클래스의 메서드보다 많은 수의 예외를 선언할 수 없다.
- 예외의 수 뿐 아니라 범위 또한 고려해야 한다.
- 인스턴스 메소드를 static 메소드 또는 그 반대로 변경할 수 없다.
- @Override 어노테이션을 사용하면 좋다.
- 오버라이딩이 불가능한 경우
- private 메소드 : 부모 클래스 전용이므로 자식 클래스에 상속되지 않음
- 정적 메소드 : 클래스 소속이므로 자식 클래스에 상속되지 않음
- final 메소드 : 더이상 수정할 수 없으므로 오버라이딩 불가
class A {
void f() throws IOException, SQLException{}
}
//올바른 사용
class B extends A{
void f() throws IOException {}
}
//error
class C extends A{
void f() throws Exception{}
}
/* Exception은 모든 예외의 조상임, 단순히 예외의 수가 아닌 범위(상속관계) 또한 고려해야함
[ 오버로딩 vs 오버라이딩 ]
오버로딩(overloading)은 기존에 없는 새로운 메서드를 추가하는 것(new)
오버라이딩(overriding)은 조상으로부터 상속받은 메서드의 내용을 변경하는 것(change, modify)
[ super ]
서브 클래스에서 슈퍼 클래스로부터 상속받은 멤버를 참조하는 데 사용되는 참조변수
class A {
int a;
int b;
}
class B extends A {
int b;
//모두 슈퍼클래스의 a를 참조
a;
this.a;
super.a;
//서브 클래스의 b를 참조
b;
this.b;
//super 클래스의 b를 참조
super.b;
}
- 멤버변수와 지역변수의 이름이 같을 때 this를 붙여서 구별하듯이 상속받은 멤버와 자신의 멤버가 이름이 같을 때 super를 붙여 구분할 수 있다.
- super.a, super.method()
- 조상클래스로부터 상속받은 멤버도 클래스 자신의 멤버이므로 super대신 this를 사용할 수 있다.
- 조상클래스의 멤버와 자손 클래스의 멤버가 중복 정의되어서 서로 구별해야 하는 경우에만 super를 사용하는 것이 좋다.
- super역시 인스턴스가 있어야하므로 static 변수나 메소드에는 접근 불가
[ super() 메소드 ]
슈퍼 클래스의 생성자 호출
this()는 같은 클래스의 다른 생성자를 호출하지만 super()는 조상클래스의 생성자를 호출하는 데 사용된다.
- Object Class를 제외한 모든 생성자의 첫 줄에는 this() 또는 super()를 삽입해야한다.
- 그렇지 않으면 컴파일러가 자동으로 super() 삽입
- 명시적 상속관계가 없다면 super()를 통해 Object() 삽입
- 서브클래스의 생성자에 super(args) 를 삽입하지 않으면 자동으로 super()를 삽입한다. 이때 슈퍼클래스에 기본 생성자가 없다면 컴파일 에러 발생
- 생성자의 첫 줄에서 조상클래스의 생성자를 호출해야 하는 이유
- 자손클래스의 멤버가 조상클래스의 멤버를 사용할 수도 있으므로 조상의 멤버들이 먼저 초기화되어 있어야 한다.
- 조상클래스에서 초기화 한 값을 쓰기 위해서는 조상에서 먼저 초기화 작업을 해야한다.
- 부모의 생성자가 먼저 초기화 되어 있어야 자식도 생성자를 생성할 수 있다.
- 처음에 아무것도 안 쓰면 자식은 부모의 기본 생성자로 초기화할 수 있다.
- 자손 클래스의 인스턴스를 생성하면, 자손의 멤버와 조상의 멤버가 합쳐진 하나의 인스턴스가 생성된다.
- 이때 조상클래스의 멤버의 초기화 작업이 수행되어야 하기 때문에 자손클래스의 생성자에게 조상클래스의 생성자가 호출되어야 한다.
- super()로 기본 생성자 아닌 부모에서 작성한 다른 생성자로 초기화 할 수 있다.
📖 참고 자료
[Java] 상속 - 메소드 오버로딩과 오버라이딩의 차이, 패키지, super(), 클래스 상속 extends
728x90
'Programming Language 👅' 카테고리의 다른 글
[Java] 자바는 Call by Value! (0) | 2023.05.19 |
---|---|
[Java] 제네릭(Generic) (0) | 2023.04.25 |
[Java] Stream API (0) | 2023.04.10 |
[Java] 자바의 컴파일 과정 (0) | 2023.03.27 |
댓글