Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
Tags
- 웹개발 기초
- 필기
- DB
- 도커
- Flutter
- 마크다운
- SQL
- DB 개요
- github
- dql
- oracle
- 쿠버네티스
- 기초 선택자
- mybatis
- 기본 API
- VS Code
- docker
- java 기초
- 정보처리기사
- java
- 깃허브
- 데이터베이스
- 프로그래밍 기초
- DB 모델링
- DDL
- view
- ORACLE 기초
- MVC 패턴
- 쿠버네티스 기본 개념
- docker 소개
Archives
- Today
- Total
핑구
07. 상속 본문
📅 2021.08.24 ~ 2021.08.25
상속
- 상속: 클래스 간에 부모, 자식 관계를 맺은 후, 부모 클래스가 자식 클래스에게 멤버(필드 + 메소드)를 주는 것을 상속이라고 한다.
부모 클래스는 조상 클래스, 상위 클래스라고도 하며, 자식 클래스는 후손 클래스, 하위 클래스라고도 불린다.
다른 클래스가 가지고 있는 멤버들을 새로 작성할 클래스에서 직접 만들지 않고 상속을 받음으로써 새 클래스가 멤버를 자신의 멤버처럼 사용 가능하다. - 상속은 extends 키워드를 이용하여 진행한다. extends는 확장하다라는 의미이며, 자식 클래스가 부모 클래스에게서 멤버를 받아온 후 내 클래스에서 더 작성할 수 있고, 해당 멤버들을 내 클래스에 맞게 용도를 바꾸어 사용할 수 있기 때문에 확장의 의미를 가진다.
[접근제한자] class 자식 클래스명 extends 부모 클래스명 {} - 상속 받은 클래스의 객체에서 부모 클래스의 멤버에 접근해 값을 변경하여도 부모 클래스의 객체에서는 해당 값이 변경되지 않는다. 두 객체가 서로 다른 주소 값을 가지고 있기 때문이다.
- 상속을 받는 경우에도 부모 클래스와 자식 클래스가 서로 다른 패키지에 존재한다면 자식 클래스에 부모 클래스 import 후 상속 받아야 한다.
상속의 목적
- 클래스의 재사용 및 연관된 일련의 클래스들에 대한 공통적인 규약 정의를 목적으로 한다.
만약 A, B, C 클래스에 반복되는 코드가 존재할 경우 중복된 코드를 부모 클래스에 작성한 후 A, B, C 클래스를 자식 클래스로 만들어 상속으로 연결한 후 사용한다.
상속의 장점
- 보다 적은 양의 코드로 새로운 클래스를 작성 가능하다.
- 코드를 부모 클래스에서 공통적으로 관리하기 때문에 코드의 추가 및 변경이 용이하다.
- 코드의 중복을 제거하여 프로그램의 생산성 및 유지보수에 기여한다.
상속의 특징
- 모든 클래스는 Object 클래스의 후손이다.
내가 만든 클래스를 포함한 모든 클래스의 최상위 부모 클래스는 Object 클래스이다. 따라서 모든 클래스들은 Object가 가진 메소드와 필드를 가지고 있다. - 부모 클래스의 생성자, 초기화 블록은 클래스의 멤버가 아니기 때문에 상속되지 않는다.
- 부모 클래스의 private 멤버는 상속은 가능하나, 자식 클래스에서 직접 접근할 수 없다. 범위에서 벗어나기 때문에 setter/getter를 이용해 접근하여야 한다.
단일 상속과 다중 상속
- 단일 상속 : 클래스 간의 관계가 다중 상속보다 명확하고 신뢰성 있다. 자바에서는 단일 상속만 지원한다.
단일 상속이지만 여러 번 거슬러 올라가게 만들어서 다중 상속처럼 사용할 수 있다. - 다중 상속 : C++에서 사용 가능한 기능으로 여러 클래스로부터 상속을 받아 복합적인 기능을 가진 클래스를 쉽게 작성 가능하다. 하지만 서로 다른 클래스로부터 상속 받은 멤버의 이름이 같은 경우 문제가 발생한다.
super.
- super : this.는 자기 자신의 필드를 가리키는 참조 변수였다면, super.은 상속을 통한 자식 클래스 정의 시 자식 클래스에서 부모 객체(멤버)를 가리키는 참조 변수이다.
자식 클래스 내에서 부모 클래스 객체에 접근하여 필드나 메소드 호출 시 사용한다. - super.을 사용하여도 부모 클래스의 private 멤버에는 접근할 수 없다.
super()(= super 생성자)
- 부모 생성자를 호출하는 메소드이다. super() 형태로 사용하는 경우 부모 생성자의 기본 생성자를 호출하며, 매개 변수 생성자를 호출하는 경우에는 소괄호 안에 호출할 생성자의 매개 변수를 작성해준다.
ex. super(name, age, weight); - 자식 생성자에는 부모 생성자가 기본적으로 포함되어 있으며, 자식 객체 생성 시 부모 객체부터 생성되기 때문에 자식 클래스 생성자 내부에는 부모 생성자를 호출하는 super()가 첫 줄에 존재한다.
따라서 명시적으로 작성할 때도 반드시 첫 줄에 작성하여야 한다.
오버라이딩(Overriding)
- 오버라이딩: 자식 클래스가 상속받은 부모 메소드를 재작성하는 것을 말한다. 자식 객체를 통해 해당 메소드 실행 시 자식 객체의 메소드가 우선 시 된다.
- 오버라이딩의 특징
- 메소드 헤드 라인 위에 @Override Annotation을 작성하여야 한다.
반드시 표시해야 하는 것은 아니지만, 오버라이딩이 성립하는지를 쉽게 알 수 있게 하기 위하여 표시해 주는 것이 좋다. - 접근 제어자를 부모 것과 같거나 넓은 범위로 변경 가능하다.
오버라이딩을 할 경우 조건이 맞는지 부모 메소드와의 비교가 필요한데, 부모의 접근 제어자보다 좁은 범위로 변경하는 경우 비교가 불가능하기 때문에 자식 클래스의 접근 제어자는 부모 클래스와 같거나 더 넓은 범위여야 한다. - 부모 메소드의 예외 처리 클래스 처리 범위보다 좁은 범위로 예외 처리 클래스를 수정 가능하다.
- 메소드 헤드 라인 위에 @Override Annotation을 작성하여야 한다.
- 오버라이딩 성립 조건
- 메소드의 선언부가 접근제한자와 예외처리를 제외하고 모두 같아야 한다.
- 메소드의 이름이 동일하여야 한다.
- 매개변수의 개수와 타입이 동일해야 한다.
- 리턴 타입이 동일해야 한다.
- 부모 클래스의 private 메소드는 오버라이딩이 불가능하다.
범위가 부모 클래스 내에서만 변경 가능하기 때문에 상속을 받아도 마음대로 변경하거나 그 자체로 접근할 수 없다. - final 메소드는 오버라이딩이 불가능하다.
toString()
- toString() : toString 메소드는 Object 객체의 멤버로 객체의 문자열 대표 값을 반환하는 메소드이다.
이때 리턴되는 값은 getClass().getName() + '@' + Integer.toHexString(hashCode())인데, 이것이 toString에서 지정한 대표 값이며, 해당 객체의 주소 값을 의미한다. - 대표 값을 반환하는 메소드이기 때문에 굳이 호출하지 않는 경우에도 객체를 프린트하는 경우 toString의 리턴 값(주소 값)이 출력된다.따라서 toString을 오버라이딩하여 원하는 데이터를 출력하는 코드로 변경하는 경우 객체 출력 메소드를 따로 만들어주지 않아도 출력이 가능하다.
@Override public String toString() { return name + " " + age + " " + weight; }
final 예약어
- final : 종단(= 끝, 마무리, 마지막)의 의미를 가지기 때문에 이후에 더 이상 수정할 수 없다. 따라서 변수에 붙는 경우 값을 변경할 수 없는 상수가 되며, 메소드에 붙는 경우 메소드 재작성의 의미인 오버라이딩이 불가능하다. 클래스에 붙는 경우에는 상속이 불가능하다. 상속을 하게 되면 해당 클래스를 수정이 가능한데, 수정할 수 없다는 의미의 예약어이기 때문이다.
- 유의 사항
- 클래스에 abstract와 final을 동시에 사용할 수 없다.
abstract의 경우 추상화를 뜻하며 아직 구체적으로 정의되어 있지 않은 상황을 의미한다. 따라서 추후에 구체화를 하여야 하는데, 이 구체화는 상속을 통해 이루어진다. 하지만 final은 수정을 할 수 없다는 뜻이기 때문에 서로 의미가 상충된다. - 메소드에 static과 abstract를 동시에 사용할 수 없다.
static은 해당 메소드를 공유하겠다는 의미인데, 아직 구체화되지 않은 메소드를 공유할 수는 없다. - abstract 메소드에 접근제어자 private을 사용할 수 없다.
abstract 메소드는 미완성이기 때문에 자식 클래스에서 완성시켜 주어야 하는데, 만약 private일 경우 해당 메소드에 자식 객체가 접근할 수 없다.
- 클래스에 abstract와 final을 동시에 사용할 수 없다.