JAVA

JAVA 상속, 캡슐화, 인터페이스

woohap 2025. 2. 8. 00:00

자바에서 생략가능한 부분

- 패키지를 생략할 경우 default package에 자동으로 등록된다.
- import java.lang.*;가 자동으로 import 되므로 생략가능
  - String, System 같은 자주 사용하는 클래스를 담고 있는 패키지
- class 정의시 extends를 사용해 상속받지 않으면 자동으로 Object 클래스가 부모가 된다.
  Object 클래스는 모든 클래스의 최상위 클래스 
- 모든 클래스는 하나 이상의 생성자를 가져야 한다. 
  생략할 경우 기본 생성자가 자동으로 생성된다.
- 부모 클래스가 기본 생성자를 사용한다면, 자식 클래스의 생성자에서 super()를 생략할 수 있다.
  만약 부모 클래스가 기본 생성자를 사용하지 않느다면
  명시적으로 super()를 호출해야 한다.
  그렇지 않으면 컴파일 오류가 발생한다. 
class Parent {
    Parent(String name) {  // 매개변수를 받는 생성자만 존재
        System.out.println("Parent 생성자 호출: " + name);
    }
}

class Child extends Parent {
    Child() {
        // super()를 명시적으로 호출하지 않으면 컴파일 오류 발생
        super("Parent Name");  // 부모 생성자를 호출해야 함
        System.out.println("Child 생성자 호출");
    }
}

public class Main {
    public static void main(String[] args) {
        Child child = new Child();
        // 출력:
        // Parent 생성자 호출: Parent Name
        // Child 생성자 호출
    }
}

 

- 자바는 하나의 소스 파일에 둘 이상의 클래스 정의 가능
  단, 그 중 소스파일의 이름과 클래스 이름이 일치해야 한다.
- 소스파일과 달리 클래스 파일은 클래스마다 하나씩 만들어진다.
- 클래스 변수의 경우 클래스가 메모리 탑재될 때, 각 타입의 초기값으로 초기화된다.
- 인스턴스 변수의 경우 인스턴스 생성시 각 타입의 초기값으로 초기화된다.
- 참조타입 변수는 생성자로 의존관계를 주입해주는 것이 아니라면 
  참조 타입은 null로 초기화된다.
[인스턴스는 참조 변수를 통해서만 다룰 수 있으며, 참조변수의 타입은 인스턴스 타입과 일치해야 함]

호출 스택

- 메서드가 호출되면 수행에 필요한 만큼의 메모리를 스택에 할당
- 메서드가 수행을 마치고나면 사용했던 메모리를 반환하고 스택에서 제거
- 호출 스택의 맨 위에 있는 메서드가 현재 실행 중인 메서드
- 아래에 있는 메서드가 위의 메서드를 호출한 메서드

기본타입, 참조타입 매개변수

- 기본 타입 변수를 매개변수로 사용하면 
  매개변수에 단순값이 복사되어 지역변수 처럼 사용
- 참조 타입 변수를 매개변수로 사용하면 
  매개변수에 주소값이 저장되므로 주소에 저장된 인스턴스에 접근 가능

** 반환타입이 참조타입도 가능한데, 이 경우 단순히 참조변수의 주소가 반환되므로 정수값이 반환됨 **

클래스 메서드와 인스턴스 메서드

- 인스턴스 메서드는 인스턴스 변수를 사용하는 경우에 사용
- 클래스 메서드는 인스턴스 변수나 인스턴스 메서드를 
  클래스 메서드 내부에서 실행하지 않을 때 사용
- 클래스 메서드는 인스턴스 메서드를 사용할 수 없다.
  → 클래스 메서드 생성 시점에 인스턴스가 없을 수 있기 때문

static 키워드

- 같은 타입의 모든 인스턴스가 동일한 값을 유지해야하는 경우 static 키워드를 사용(클래스 변수)
  → 인스턴스 생성 없이 사용 가능
- 작성한 메서드 중에 인스턴스 변수, 매서드를 사용하지 않으면 static 키워드를 붙인다.

메서드 간의 호출과 참조

- 같은 클래스에 속한 멤버들 간에는 별도의 인스턴스를 생성하지 않고도 서로 참조 또는 호출 가능 
  단, 클래스 멤버가 인스턴스 멤버를 호출하는 경우 인스턴스가 생성되어 있어야 함 

오버로딩(중복정의)

자바는 동일한 이름을 갖는 메서드를 정의할 수 있다.

[오버로딩 조건]
1. 메서드 이름이 같아야 한다.
2. 매개변수의 개수 또는 타입이 달라야 한다.
   매개변수 타입 순서가 달라도 가능
   Ex) add(long a, int b), add(int a, long b)
3. 반환 타입은 상관 없음

생성자

- 생성자는 인스턴스가 생성될 때, 호출되는 
인스턴스 초기화 메서드 ( 인스턴스 변수의 초기화 )
1. 생성자는 클래스 이름과 동일
2. 리턴값이 없다.

**** 생성자를 생략하는 경우 컴파일러가 기본 생성자를 자동으로 추가 ****
**** new 연산자가 인스턴스를 생성하는 것이지 생성자가 인스턴스를 생성하는 것이 아니다. ****

[생성자에서 다른 생성자 호출]
- 생성자의 이름으로 클래스 이름 대신 this()를 사용한다.
- 한 생성자에서 다른 생성자를 호출할 때는 반드시 첫 줄에서만 호출 가능 
  → 생성자 호출 이전의 작업이 무의미해지기 때문

[this - 객체 자기 자신을 가리키는 참조변수]
- this는 참조변수로 인스턴스 자신을 가리킨다.
- this를 사용할 수 있는 건 인스턴스 멤버뿐
  this는 자기 자신을 참조하는데 클래스가 초기화될 때, this가 가리키는 값이 없을 수 있음

[초기화 블럭]
- 복잡한 로직 처리와 생성자 간 중복 제거에 유용
  단순한 경우 필드에 바로 초기화하는 것이 더 좋음

상속

- 기존의 클래스를 재사용하여 새로운 클래스를 작성하는 것
- 코드의 재사용성을 높이고, 코드의 중복을 제거
  → 프로그램 생산성과 유지보수에 크게 기여

[정리]
- 자손 클래스는 조상 클래스의 모든 멤버를 상속 받는다.
  → 단, 초기화 블록과 생성자는 상속되지 않는다.
- 자손 클래스의 멤버 개수는 조상 클래스 보다 항상 같거나 많다.

클래스 간의 관계

[포함관계]
- 한 클래스의 멤버변수로 다른 클래스 타입의 참조 변수를 선언하는 것

**
상속 관계 - [~은 ~이다.]
포함 관계 - [~은 ~을 가지고 있다.]

단일 상속

- 자바는 단일 상속만 지원
- 다중상속을 허용하면 클래스 간의 관계가 매우 복잡해짐
- 서로 다른 클래스로부터 상속 받은 멤버간의 이름이 같은 경우 구별 불가

오버라이딩(재정의)

- 부모 클래스의 메서드를 상속 받아 자신에 맞게 변경하는 것을 의미

[오버라이딩 조건]
1. 선언부가 조상 클래스의 메서드와 일치해야 한다.
2. 접근 제어자는 조상 클래스의 메서브보다 좁은 범위로 변경할 수 없다.
   private - 오버라이딩 불가
   default - default, protected, public 가능
   protected - protected, public 가능
   public - public 가능 

3. 조상 클래스의 메서드보다 많은 수의 예외를 선언할 수 없다.

super 참조 변수

- 자손 클래스에서 조상 클래스로부터 상속받은 멤버를 참조하는데 사용되는 참조변수
- 부모의 멤버와 자신의 멤버의 이름이 같을 때 구분하기 위해 사용

super() 생성자

- 조상의 생성자를 호출할 때 사용한다.
- 클래스 자신에 선언된 변수는 자신의 생성자가 초기화를 채임지도록 작성하는 것이 좋다.

패키지

- 관련된 클래스와 인터페이스 묶음을 의미
- 패키지 - 하나의 디렉터리
- 클래스 - 하나의 클래스 파일

// 반드시 소스코드 첫 문장으로 와야 함 
package 패키지명;

제어자

- 클래스, 변수, 메서드 선언부에 선언

[접근 제어자] - public protected, default, private
- 접근 제어자는 4개 중 하나만 사용 가능

[그 외] - static, fanal, abstract, native, transient, synchronized, volatile, strictfp
- 그 외 제어자는 여러 제어자 조합 가능

static 제어자

- 멤버변수, 메서드, 초기화 블럭에 사용 가능
- 클래스 메서드, 클래스 변수로 만들 때 사용

final 제어자

- 클래스, 메서드, 멤버변수, 지역변수에 사용
- 클래스 - 변경 및 확장 될 수 없는 클래스, 다른 클래스의 조상 불가
- 메서드 - 변경될 수 없는 메서드 (오버라이딩 불가)
- 멤버변수, 지역변수 - 상수화

abstract 제어자

- 클래스, 메서드에 사용
- 클래스 - 추상 클래스
- 메서드 - 선언부만 작성하고 구현부는 작성하지 않은 추상 메서드임을 알림

접근 제어자

- private, default, protected, public
- private - 같은 클래스 내에서만 접근 가능
- default - 같은 패키지 내에서만 접근 가능
- protected - 같은 패키지 내에서, 그리고 다른 패키지의 자손 클래스에서 접근이 가능 
  다른 패키지에서는 오직 protected 멤버를 가진 
  부모 클래스를 상속받은 자식 클래스만 해당 멤버에 접근
- public - 접근 제한 없음

[접근 제어자 사용 이유]
- 외부로부터 데이터를 보호하기 위해서
- 외부에는 불필요한, 내부적으로만 사용되는 부분을 감추기 위해서

캡슐화

- 외부에는 불필요한, 내부적으로만 사용되는 부분을 감추기 위해서
- 외부에서 접근할 필요가 없는 멤버를 외부에 노출시키지 않음으로써 복잡성을 줄임
- 데이터 감추기, 캡슐화라고 한다.
- 클래스 내부에 선언된 데이터를 보호하기 위해서 사용

다형성

- 여러 가지 형태를 가질 수 있는 능력
- 자바에서는 하나의 참조변수로 여러 타입의 객체를 참조할 수 있게 함
- 조상 클래스 타입 참조변수는 자식 타입 인스턴스 참조 가능 (반대 불가능)
    - 단, 이 경우 부모 클래스의 멤버에만 접근 가능
    - 오버라이딩 된 메서드는 재정의한 메서드가 호출됨

참조변수의 형변환

- 참조타입도 형변환 가능 
  → 단, 상속 관계에 있는 클래스 사이에서만 가능
- 자식 타입 참조변수는 부모 타입 참조변수로 형변환 가능 (생략 가능)
- 부모 타입 참조변수는 자식 타입 참조변수로 형변환 가능 (생략 불가)
  → 이 때, 인스턴스는 자식 타입 인스턴스

instanceof 연산자

- 참조변수가 참조하고 있는 인스턴스의 타입을 알아보기 위해 사용
- 값이 null인 참조변수에 대해 Instanceof 연산을 수행하면 false 반환

// Student 타입 참조 변수가 가리키는 인스턴스가 Human의 자식인 경우 true 반환 
student instanceof Human

- instanceof 연산의 결과가 true인 경우 검사한 타입으로 형변환 가능하다는 말 

추상 클래스

- 인스턴스 생성 불가
- 생성자, 멤버 변수와 메서드를 가질 수 있다.
- 추상 메서드(미완성 메서드)를 포함
- abstract 키워드를 붙이면 된다.
  → 추상 메서드가 있다는 것을 의미
- 추상 클래스를 상속 받아 모든 추상 메서드를 구현하여 사용하면 된다. (오버라이딩)

abstract class A { ... }

추상 메서드

- 메서드의 선언부만 작성하고 구현부는 작성하지 않은 채 남겨 둔 것
- 상속 받은 클래스마다 다르게 구현하도록 유도하기 위해 사용
- 주석으로 어떤 기능을 수행할지 작성해주면 된다.

//abstract 리턴타입 메서드이름();
abstract int discountPrice();

추상 클래스 작성

- 처음 설계 시 공통적으로 사용될 수 있는 부분을 찾아서 추상 클래스로 작성
- 기존의 클래스에서 공통적인 부분을 뽑아서 추상 클래스로 작성

[상속]
- 자손 클래스를 만드는데 부모 클래스를 사용

[추상화]
- 기존 클래스들의 공통 부분을 뽑아서 조상 클래스를 만드는 것
  상위 클래스로 올라갈수록 공통적인 부분이 존재
  하위 클래스로 내려갈수록 개별적인 부분이 존재

인터페이스

- 추상 클래스보다 추상화 정도가 더 높음
- 추상 메서드, 클래스 메서드, 디폴트 메서드, 상수(final static), private 메서드
- 추상 메서드 - public abstarct
- 클래스 메서드 - static
- 디폴트 메서드 - public default
- 상수 - public final static
- 프라이빗 메서드 - private method // 인터페이스 내부에서 사용
- 클래스처럼 접근 제어자를 public, default 만 가능

정리

- 모든 멤버 변수는 public static final 이어야 함
- 모든 메서드는 public abstract 이어야 하며, 이를 생략할 수 있다.
- JDK 1.8부터 static, default 메서드 사용 가능

인터페이스의 상속

- 인터페이스는 인터페이스로부터만 상속 받을 수 있다.
- 인터페이스는 다중 상속 가능

인터페이스의 구현

- 인터페이스 자체로 인스턴스를 생성할 수 없다.
- 인터페이스를 구현한 클래스의 인스턴스를 사용해야 한다.
- 인터페이스 상속과 구현을 동시에 진행 가능

디폴트 메서드와 static 메서드

- static 메서드는 인스턴스와 관계가 없는 독립적인 메서드이므로 인터페이스에서 사용 가능하게 함
- 이후 인터페이스에 메서드를 쉽게 추가하기 위해서 default 메서드를 사용 
  → 추상 메서드를 중간에 구현하면, 해당 인터페이스를 구현하는 모든 클래스가 
    추상 메서드를 구현해야힘
- default 메서드 앞에 default 키워드를 붙인다.

default void onClick() { } 

주의

- 새로 추가된 디폴트 메서드가 기존의 메서드와 이름이 중복되어 충돌하는 경우가 발생
    1. 여러 인터페이스의 디폴트 메서드 간의 충돌
    → 디폴트 메서드를 오버라이딩해서 사용

    2. 디폴트 메서드와 조상 클래스 메서드 간의 충돌
    → 디폴트 메서드 무시

내부 클래스(inner class)

- 내부에 선언된 클래스
- 외부에서는 잘 사용되지 않고 외부 클래스와 긴밀한 관계를 갖는 경우 내부 클래스로 선언

[장점]
- 내부에서 외부 클래스의 멤버들을 쉽게 접근 가능
- 외부에는 불필요한 클래스를 감춰 코드의 복잡성을 줄인다.

내부 클래스의 종류와 특징

- 인스턴스 클래스 - 외부 클래스의 인스턴스 멤버 처럼 다뤄진다.
- 스태틱 클래스 - 외부 클래스의 static 멤버 처럼 사용된다.
- 지역 클래스 - 외부 클래스의 메서드나 초기화 블록 안에 선언, 선언된 영역 내부에서만 사용
- 익명 클래스 - 클래스의 선언과 객체의 생성을 동시에 하는 이름 없는 클래스

내부 클래스의 제어자와 접근성

- 인스턴스 클래스와 스태틱 클래스는 외부 클래스의 멤버변수와 같은 위치에 선언되며
  멤버변수와 같은 성질을 갖는다.
- 내부 클래스는 클래스이므로 abstract와 final 같은 제어자를 사용할 수 있을 뿐만 아니라
- 멤버 변수처럼 private protected 접근 제어자도 사용 가능
- 지역 클래스는, 외부 클래스의 인스턴스 멤버와 static 멤버 모두 사용 가능
  지역 클래스가 포함된 메서드에 정의된 지역변수 사용 가능
  단, final이 붙은 변수만 사용 가능

내부 클래스

- 내부 클래스 중 스태틱 클래스만이 스태틱 멤버를 가질 수 있다. 
  final static은 상수이므로 가능
- 인스턴스 클래스는 외부 클래스의 인스턴스 멤버와 스태틱 멤버를 사용 가능
  반면 스태틱 클래스는 스태틱 멤버에만 접근 가능
- 내부 클래스와 외부 클래스의 변수 명이 같으면 
  this와 외부클래스.this를 붙여서 구별 가능

'JAVA' 카테고리의 다른 글

JAVA 쓰레드 1  (0) 2025.02.11
지네릭스  (0) 2025.02.06
Object 클래스의 메서드  (0) 2024.12.04
객체지향 프로그래밍 1  (0) 2024.11.27
JAVA Collection Framework 3  (0) 2024.11.26