일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- aspect
- 트랜잭션
- proxy pattern
- Spring Security
- java
- SQL
- aop
- 객체지향프로그래밍
- MYSQL
- Interceptor
- 스프링 시큐리티
- Redis
- RestControllerAdvice
- request
- network
- spring boot
- 관점지향프로그래밍
- response
- 디자인패턴
- 스프링부트
- git
- 자바
- OOP
- 스프링
- mybatis
- exception
- 인터셉터
- Filter
- Spring
- http
- Today
- Total
장쫄깃 기술블로그
[Java] 상속(Inheritance)이란? 본문
상속(Inheritance)이란?
상속은 객체들 간의 관계를 구축하는 방법이다.
상속은 기존 클래스에 기능을 추가하거나 재정의하여 새로운 클래스를 정의하는 것이다. 하위 클래스들에서 사용할 공통된 메소드를 상위 클래스가 제공해주고, 하위 클래스들은 상위 클래스에서 없는 기능을 추가하거나 재정의한다.
기존 클래스에 기능을 추가하거나 재정의하여 새로운 클래스를 정의하는 것
상속의 장점
1. 코드를 재사용할 수 있다.
하위 클래스들이 공통으로 사용할 기능을 상위 클래스에 적용하고, 하위 클래스는 필요할 때 기능을 추가하거나 재정의 하면 되기 때문에, 공통 코드를 재사용할 수 있다.
public class Bird {
public void fly() {
System.out.println("푸드덕 푸드덕");
}
public void cry() {
System.out.println("꽥꽥");
}
}
public class Duck extents Bird {
public void swim() {
System.out.println("오리 수영한다");
}
@Override
public void fly() {
System.out.println("오리는 날 수 없다");
}
}
public class Chicken extents Bird {
@Override
public void cry() {
System.out.println("꼬끼오");
}
}
상위 클래스의 공통 기능을 사용하거나, 필요에 따라 재정의하거나, 추가해야할 기능을 추가하여 사용한다.
2. 다형성 구현
다형성을 구현하여 공통된 메소드 사용이 가능하게 한다.
다형성이 없다면 Bird로 추출한 메소드들을 하나하나 호출해줘야 한다.
public class Main {
public static void main(String[] args) {
final Duck duck = new Duck();
final Chicken chicken = new Chicken();
duck.fly();
chicken.fly();
}
}
하지만 다형성을 구현한다면 반복문을 통해 공통된 메소드를 딱 한번만 호출하면 된다.
public class Main {
public static void main(String[] args) {
final Duck duck = new Duck();
final Chicken chicken = new Chicken();
final List<Bird> birds = Arrays.asList(duck, chicken);
for(Bird bird : birds) {
bird.fly();
}
}
}
상속의 문제점
상속의 문제점 중 가장 핵심은 하위 클래스가 상위 클래스에 강하게 결합한다는 것이다. (때문에, 필자는 상속을 좋아하지 않는다.) 하위 클래스는 상위 클래스와 강하게 결합하므로 응집력이 낮아져서 수동적인 객체가 된다. 수동적인 객체가 되면 결합된 객체에 영향을 크게 받으므로 변화에 대처하기 어려워진다.
public class Document {
public int length() {
return this.content().length();
}
public String content() {
// ...
}
}
예를 들어, Document 라는 상위 클래스의 content() 메소드의 리턴 타입이 String이 아니고 char[]로 바뀐다면 어떻게 될까? 하위 클래스에서 해당 메소드를 사용하고 있다면 모조리 고쳐야 한다.
그리고 기능 확장을 위해 잘 정의된 상위 클래스의 메소드를 오버라이딩하면 캡슐화를 깨트린다. 캡슐화를 위해서는 외부에서 메소드를 가져다만 써야하는데, 오버라이딩은 구현을 수정하는 일이기 때문이다.
또한, 상위 클래스의 내부 구현을 알아야한다는 사실 자체가 캡슐화를 깨트린다. 하위 클래스가 상위 클래스의 정의된 메소드를 오버라이딩할 때 상위 클래스의 내부 구현을 반드시 확인해야하기 때문이다.
이렇듯 상속은 상위 클래스와 강하게 결합하여 변경이나 확장에 취약하며, 캡슐화를 깨트리는 프로그램을 만들 여지가 있다. 추가로, 상위 클래스에 결함이 있다면 하위 클래스는 그 결함을 그대로 넘겨받게 된다.
정리하며
상속은 잘 써야 좋다. 상속은 클래스의 행동을 확장할 때가 아니라 정제할 때 사용하는 편이 좋다. 새로운 기능을 붙이거나 기능을 보완하는것이 아니라, 불완전한 행동을 완전하게 만드는 순간 사용해야 한다.
참고
https://steady-coding.tistory.com/451
'Programming Language > Java' 카테고리의 다른 글
[Java] 코드 실행 시간 측정하기 (0) | 2022.04.19 |
---|---|
[Java] 다형성(Polymorphism)이란? (0) | 2022.04.19 |
[Java] 캡슐화(Encapsulation)란? (0) | 2022.04.19 |
[Java] 추상화(Abstraction)란? (0) | 2022.04.19 |
[Java] 객체 지향 프로그래밍 (0) | 2022.04.19 |