일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- CentOS8
- Python
- Codewars
- Oralce
- CentOS
- 이클립스
- 자바기초스터디
- 남산타워뷰
- 서울복층에어비앤비
- 시즌1
- 중첩쿼리
- Linux
- class파일바로보기
- 멀티쓰레드프로그래밍
- 서울에어비앤비
- https
- 이것이리눅스다
- 사용자변경
- 오류
- 파이썬
- VMware
- JavaScript
- java
- monthPicker
- 8kyu
- Eclipse
- SQL
- 6kyu
- 7kyu
- 주민번호마스킹
- Today
- Total
보통사람
[Study-6주차] 상속 본문
-
목표
-
자바의 상속에 대해 학습하세요.
-
-
학습할 것 (필수)
-
자바 상속의 특징
-
super 키워드
-
메소드 오버 라이딩
-
다이나믹 메소드 디스패치 (Dynamic Method Dispatch)
-
추상 클래스
-
final 키워드
-
Object 클래스
-
1. 상속(Inheritance)
-
다른 클래스(상위클래스)의 멤버 변수와 메소드를 물려받는 것을 의미함
-
상속을 이용하면 적은 양의 코드로 새로운 클래스를 만들 수 있으며 코드의 재사용을 높일 수 있음
-
extends 키워드를 이용해서 상속할 클래스명을 명시함
- 자바 상속의 특징
- Object 클래스를 제외하고는 모든 클래스는 하나의 상위클래스만 상속받을 수 있으며 이를 단일 상속(Single Inheritance) 이라고 함
-
상속을 선언하지 않아도 자동적으로 최상위 클래스인 Object 클래스를 상속 받음
-
상속 횟수 제한이 없음
class 클래스명 extends 상속받고자하는 클래스명 {}
public class Me extends Parent {}
2. Object 클래스
-
위에서도 잠깐 언급했듯이 모든 클래스의 조상이며 상속계층도의 최상위 클래스
-
Object 클래스의 멤버들은 모든 클래스에서 바로 사용 가능하며 멤버 변수는 없고 11개의 메소드만 가지고 있음
package com.study.java.inheritance;
public class Parent {
// 상속을 선언한 게 없음
public Parent() {
System.out.println("Parent 생성자입니다.");
}
public void print() {
System.out.println("Parent 클래스 입니다.");
}
}
3. 오버 라이딩(Overriding)
-
상위 클래스로부터 상속받은 메소드의 내용을 변경하는 것을 의미함
-
Java 1.5 이상부터 공변 반환타입(Convariant Return Type)이 추가되어 하위클래스 타입으로도 변환 가능함
- @Override 어노테이션으로 오버 라이딩이 맞는지 확인할 수 있으며 어노테이션이 없어도 에러는 안 나지만 명확하게 하기 위해서 사용하는 게 좋음
-
오버 라이딩의 조건
-
선언부가(이름, 매개변수, 반환 타입) 동일해야 함
-
접근 제어자를 상위 클래스의 메소드보다 좁은 범위로 변경할 수 없음
-
예외(Exception)는 상위 클래스보다 많이 선언할 수 없음
-
인스턴스메소드를 statice 메소드로 또는 그 반대로 변경할 수 없음
-
package com.study.java.inheritance;
public class Parent {
protected void print2() {
System.out.println("protected print2() - Parent");
}
protected void print3() {
System.out.println("protected print3() - Parent");
}
public Parent getObj() {
return new Parent();
}
}
package com.study.java.inheritance;
public class Me extends Parent {
// 접근 제어자 : public > protected > (default) > private
// 에러 없음
public void print2() {
// Why? 상위클래스의 print2()의 접근 제어자보다 넒은 범위로 지정했기 때문에
}
// 에러 발생
private void print3() {
// Why? 상위클래스의 print3()의 접근 제어자보다 좁은 범위로 지정했기 때문에
}
// 에러 없음
public Me getObj() {
// Why? 공변 반환 타입이 때문에 반환타입을 하위클래스로 변경해도 상관없음
return new Me();
}
}
※ 오버 로딩(Overloading)
-
기존에 없는 새로운 메소드를 추가하는 것을 의미
-
오버 로딩의 조건
-
메소드의 이름이 동일해야 함
-
매개변수의 타입 또는 개수가 달라야 하며 반환 타입은 상관없음
-
package com.study.java.inheritance;
public class Me extends Parent {
// 오버라이딩(Overriding)
public void print2() {
System.out.println("public print2() - Me");
}
// 오버로딩(Overloading)
public void print2(String str) {
System.out.println("public print2("+ str+") - Me ");
}
public static void main(String[] args) {
Me me = new Me();
me.print2();
me.print2("안녕");
}
}
[실행결과]
public print2() - Me
public print2(안녕) - Me
4. super, super()
-
super
-
상위클래스의 참조변수
-
하위클래스에서 상위클래스의 멤버를 사용하는 경우에 사용됨
-
-
super()
-
상위 클래스의 생성자를 호출할 때 사용함
-
Object 클래스를 제외하고 모든 클래스의 생성자 첫 줄에는 'this()' 또는 'super()'를 호출해야 함 없으면 컴파일러가 자동으로 'super()' 추가함(하위 클래스가 상위 클래스의 멤버 변수를 사용할 수 있기 때문에 상위 클래스를 먼저 초기화하기 위해서 첫 줄에 추가)
-
package com.study.java.inheritance;
public class Me extends Parent {
public Me() {
// super() 를 선언하지 않았음
System.out.println("Me 생성자입니다.");
}
public static void main(String[] args) {
Me me = new Me();
}
}
5. final
-
클래스, 메소드, 멤버 변수, 지역변수 등 모든 대상에 final 키워드를 사용할 수 있음
-
대표적인 final 클래스로 String과 Math가 있음
package com.study.java.inheritance;
public final class ParentFinal { // 상속 받을 수 없음
final int MAX_NUM = 100; // 상수
final void printFinal() { // 오버라이딩 할 수 없음
System.out.println("printFinal");
}
}
6. 추상 클래스(Abstract Class)
-
미완성 클래스를 의미함
-
abstract 키워드를 이용해서 추상 클래스를 만들 수 있음
-
클래스 내에 추상 메소드(선언부만 있는 메소드)를 포함한 클래스를 의미하지만 추상 메소드가 없어도 abstract를 이용해서 추상 클래스로 지정할 수 있음
-
일반 클래스와 동일하게 생성자, 멤버 변수, 메소드를 가질 수 있으나 인스턴스는 생성할 수 없음
-
추상메소드를 선언하는 이유는 하위 클래스에서 반드시 구현하도록 강요하기 위해서 사용함
abstract class 클래스명 {}
public abstract class AbstractParent {}
public abstract class AbstractParent {
abstract void test(); // 추상메소드
}
public class Me2 extends AbstractParent {
@Override
void test() { // 상속받으면 추상메소드를 반드시 구현해야함
}
}
7. 다형성(Polymorphism)
-
여러 가지 타입을 가질 수 있는 것을 의미하며 Java는 한 타입의 참조 변수로 다양한 타입의 객체를 참조할 수 있도록 함으로 다형성을 구현하고 있음
-
참조 변수의 형 변환은 참조하고 있는 객체에서 사용할 수 있는 멤버의 범위를 조절하는 것뿐
-
상속 시 상위 타입의 참조 변수로 하위 타입의 객체를 참조할 수 있으나 그 반대는 안됨
하위 타입 → 상위 타입(Up-casting) : 형변환 생략가능
하위 타입 ← 상위 타입(Down-casting) : 형변환 생략불가
Parent p = new Me(); // O
→ 상위 타입의 참조변수로 하위 타입의 객체를 참조
Me me = new Parent(); // X (에러발생)
→ 하위 타입의 참조변수는 상위 타입의 객체 참조 못함
→ Why? 하위 타입의 참조변수가 상위 타입에 없는 객체를 참조 할 수 있기때문에 허용되지 않음
8. 다이나믹 메소드 디스패치(Dynamic Method Dispatch)
-
컴파일시가 아닌 런타임(Runtime)시에 어떤 메소드를 호출할지 결정하는 방법
-
Java가 런타임 다형성(Polymorphism)을 지원하는 방법 중 하나
public class Parent {
public String myName = "Parent";
public void print() {
System.out.println("This is Parent");
}
}
public class Me extends Parent {
public String myName = "Me";
public int x = 200;
public void print() {
System.out.println("This is Me");
}
public static void main(String[] args) {
Me me = new Me();
System.out.println(me.myName);
me.print();
System.out.println("####################");
// 다이나믹 메소드 디스패치
Parent p = new Me();
System.out.println(p.myName);
p.print();
}
}
[실행결과]
Me
This is Me
####################
Parent
This is Me
-
메소드 디스패치는 이것 말고도 2가지 방법이 더 있음
-
static 메소드 디스패치 : 정적인 메소드 디스패치
-
더블 디스패치 : 다이나믹 메소드 디스패치가 2번 발생된 것
-
-
자바는 싱글 디스패치를 지원하는 언어이기 때문에 최대 2번만 발생 할 수 있는 듯
-
정리 잘된 링크 참조 (더블 디스패치 예제와 방문자 패턴에 대한 설명도 있음)
※ 참조
자바의 정석
www.geeksforgeeks.org/dynamic-method-dispatch-runtime-polymorphism-java/
defacto-standard.tistory.com/413
www.tcpschool.com/java/java_polymorphism_concept
'Study' 카테고리의 다른 글
[Study-8주차] 인터페이스 (0) | 2021.01.04 |
---|---|
[Study-7주차] 패키지 (0) | 2020.12.29 |
[Study-5주차] 클래스 (0) | 2020.12.13 |
[Study-4주차] 제어문 (0) | 2020.12.07 |
[Study-3주차] 연산자 (0) | 2020.11.28 |