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
- Docker
- lightsail
- jpa
- java
- jsp
- nginx
- Flutter
- 알고리즘
- 에러
- SpringBoot
- REACT
- 인텔리제이
- 자바스크립트
- JavaScript
- vue
- gradle
- Keycloak 17.0.1
- ES6
- 메서드
- arraylist
- json
- aws
- keycloak
- 스프링
- 맥길대학교
- 글로벌
- jQuery
- 현장학습
- vue.js
- spring
Archives
- Today
- Total
korean IT student
[Java-Live-Study] 6주차 - 상속 본문
목표
자바의 상속에 대해 학습하세요.
학습할 것 (필수)
- 자바 상속의 특징
- super 키워드
- 메소드 오버라이딩
- 다이나믹 메소드 디스패치 (Dynamic Method Dispatch)
- 추상 클래스
- final 키워드
- Object 클래스
1. 자바 상속의 특징
class 자식클래스명 extends 부모클래스명{}
- 상속이란 상위클래스에서 정의한 필드와 메서드를 하위클래스도 동일하게 사용할 수 있게 물려받는 것이다.
- extends 키워드를 사용하여 상속
class 자식클래스명 extends 부모클래스명1, 부모클래스명2{} // 불가능하다.
- 위와 같이 두 개의 클래스를 상속받는 것은 불가능
- 다중상속을 허용하면 여러 클래스로부터 상속받을 수 있기 때문에 복합적인 기능을 가진 클래스를 쉽게 작성할 수 있다는 장점이 있지만, 클래스간의 관계가 복잡해지소 서로 다른 클래스로부터 상속받은 멤버의 이름이 같은 경우 구별할 수 있는 방법이 없어서 자바에서는 다중상속을 포기하고 단일상속만 허용함.
- 부모 메소드를 자식 클래스에서 재정의(오버라이딩) 가능
- 부모의 private 접근 제한을 갖는 멤버는 상속 불가능
- private 제한자는 오로지 선언된 클래스 내부에서만 접근 가능하므로 외부에서 사용할 수 있게 하는 상속은 불가능 만약 상속이 필요할 경우, 다른 접근 제한자(public, protected) 사용
- 자바의 모든 클래스는 Object 클래스의 자식/자손 클래스
- 자바의 최상의 클래스는 Object 클래스 클래스 선언 시 다른 클래스를 상속받지 않으면 암시적으로 java.lang.Object 클래스를 상속
- java.lang 패키지는 자바에서 가장 기본적인 동작을 수행하는 클래스들의 집합, 따라서 자바에서는 java.lang 패키지의 클래스들은 import 문을 사용하지 않아도 클래스 이름만으로 바로 사용가능합니다.
2. super 키워드
class Parent {
String name;
int age;
public Parent() {
}
public Parent(String name, int age) {
this.name = name;
this.age = age;
}
}
class Child extends Parent {
public Child() {
}
public setName(String name) {
super.name = name; // 부모 클래스의 필드
}
public setAge(int age) {
super.age = age; // 부모 클래스의 필드
}
}
- 자식이 부모 메소드를 호출해야하는 경우 super 키워드 사용
- 부모 객체를 참고하고 있기 때문에 부모에 직접 접근 가능
class Parent {
public Parent() {
}
}
class Child extends Parent {
// 자식클래스의 생성자 함수에 super()가 없어도 컴파일러가 넣어준다.
public Child() {
// super();
}
}
========================
class Parent {
String userName;
public Parant(String userName){
this.userName = userName;
}
}
class Child extends Parent {
// 부모 클래스에 기본 생성자가 없기 때문에 컴파일 에러가 남
public Child() {
// super();
}
// 부모 클래스의 생성자가 정확히 호출 되므로 에러가 없다.
public Child() {
super("changHyun");
}
}
- super() 를 통해 부모 클래스의 생성자가 호출
- 자식 클래스에서 super()를 명시적으로 작성하지 않아도 컴파일러가 자동으로 추가
- 부모 클래스에서 기본 생성자가 없고 매개변수를 갖는 생성자만 있다면 자식 클래스에서 반드시 super(매개값) 명시
3. 메소드 오버라이딩
class Parent {
void method1() {}
void method2() {}
}
class Child extends Parent {
@Override
void method2() {}
void method3() {}
}
class Example {
public static void main(String[] args) {
Child child = new Child();
child.method1(); // 상속 받은 부모 메소드 호출
child.method2(); // 재정의한 자식 메소드 호출
child.method3(); // 자식 메소드 호출
}
}
- 메소드를 오버라이딩하면 자식 객체의 메소드 호출 시 부모 기능은 숨겨지고 자식이 재성의한 기능 실행
4. 다이나믹 메소드 디스패치 (Dynamic Method Dispatch)
- 메소드 디스패치란, 메소드를 어떻게 호출할 지를 정해서 호출하는 것, 대표적으로 static, dynamic이 있다.
정적 메소드 디스패치(Static Method Dispatch)
class Parent {
void method1() {}
}
class Child extends Parent {
@Override
void method1() {}
}
class Example {
public static void main(String[] args) {
Child child = new Child();
child.method1(); // 재정의한 자식 메소드 호출
}
}
- 메인 함수에서 child.method1()를 호출했을 때 우리는 재정의한 자식 메소드를 호출하는것을 알고 있다. 컴파일러 역시 이 메소드를 호출하고 실행시켜야되는 것을 명확하게 알고 있는데 이를 정적 메소드 디스패치라 부른다.
- -> 컴파일러 시점
동적 메소드 디스패치(Dynamic Method Dispatch)
interface Family{
void method1() {}
}
class Parent implements Family {
@Override
void method1() {}
}
class Child implements Family{
@Override
void method1() {}
}
class Example {
private Family family
Example(Family family){
this.family = family;
}
void print(){
System.out.println(family.method1());
}
}
- 상위 개념인 Interface 혹은 Abstract Class에서 정의된 abstract method를 호출하는 경우에 해당
- 정적 디스패치와 반대로 컴파일러가 어떤 메서드를 호출하는지 모르는 경우
- 동적 디스패치는 호출할 메서드를 런타임 시점에서 결정한다.
- Example 클래스의 생성자 인자로 넘오오는 매개값의 타입이 parant, child인지는 실행 시 확인가능
- 실행 시 동적으로 확인해서 다이나믹 디스패치
5. 추상클래스
abstract class 클래스이름 {
abstract 반환타입 메소드이름();
}
- 자바에서는 하나 이상의 추상메소드를 포함하는 클래스를 가리켜 추상클래스라 정의한다.
abstract class Family{
void with() {}
}
class Parent extends Family {
@Override
void with() {}
}
class Example {
public static void main(String[] args) {
// Family f = new Family(); 에러!
Parent parant = new Parent();
Family family = new Parent(); // 추상 클래스도 다형성 적용이 가능하다.
}
}
- 추상 클래스를 상속받은 자식 클래스에서 해당 추상 메소드의 정의를 강제한다.
- 추상 클래스를 인스턴스로 생성할 수 없다. -> 정의되지 않은 메소드가 있는 인스턴스를 만둘 수는 없기 때문
6. final 키워드
- 클래스, 필드, 메소드 선언 시 사용 가능한 키워드 해당 선언이 최종 상태이고, 더 이상 수정될 수 없음을 의미
final 클래스
- 클래스 선언 시 final 키워드를 사용하면, 이 클래스는 상속할 수 없는 클래스임을 의미 부모 클래스가 될 수 없으며 자식 클래스를 만들 수 없는 클래스
final 메소드
- 메소드 정의 시 final 키워드를 사용하면, 이 메소드는 오버라이딩할 수 없는 메소드임을 의미 상속받은 부모 클래스의 final 메소드는 자식 클래스에서 재정의 불가능
7. Object 클래스
- 자바의 최상위 클래스는 Object 클래스
- 클래스 선언 시 다른 클래스를 상속받지 않으면 암시적으로 java.lang.Object 클래스를 상속
- .Object 클래스는 필드가 없고 메소드들로 구성
Object 클래스의 메소드는 다음과 같습니다.
protected Object clone() | 해당 객체의 복제본을 생성하여 반환함. |
boolean equals(Object obj) | 해당 객체와 전달받은 객체가 같은지 여부를 반환함. |
protected void finalize() | 해당 객체를 더는 아무도 참조하지 않아 가비지 컬렉터가 객체의 리소스를 정리하기 위해 호출함. |
Class<T> getClass() | 해당 객체의 클래스 타입을 반환함. |
int hashCode() | 해당 객체의 해시 코드값을 반환함. |
void notify() | 해당 객체의 대기(wait)하고 있는 하나의 스레드를 다시 실행할 때 호출함. |
void notifyAll() | 해당 객체의 대기(wait)하고 있는 모든 스레드를 다시 실행할 때 호출함. |
String toString() | 해당 객체의 정보를 문자열로 반환함. |
void wait() | 해당 객체의 다른 스레드가 notify()나 notifyAll() 메소드를 실행할 때까지 현재 스레드를 일시적으로 대기(wait)시킬 때 호출함. |
void wait(long timeout) | 해당 객체의 다른 스레드가 notify()나 notifyAll() 메소드를 실행하거나 전달받은 시간이 지날 때까지 현재 스레드를 일시적으로 대기(wait)시킬 때 호출함. |
void wait(long timeout, int nanos) | 해당 객체의 다른 스레드가 notify()나 notifyAll() 메소드를 실행하거나 전달받은 시간이 지나거나 다른 스레드가 현재 스레드를 인터럽트(interrupt) 할 때까지 현재 스레드를 일시적으로 대기(wait)시킬 때 호출함. |
'back-end > JAVA' 카테고리의 다른 글
[Java-Live-Study] 8주차 - 인터페이스 (0) | 2021.11.02 |
---|---|
[Java-Live-Study] 7주차 - 패키지 (0) | 2021.10.26 |
[Java-Live-Study] 5주차 - 클래스 (0) | 2021.09.17 |
[Java-Live-Study] 4주차 - 제어문 (0) | 2021.08.19 |
[Java-Live-Study] 3주차 - 연산자 (0) | 2021.08.16 |
Comments