추상 클래스와 인터페이스

heeezni·2025년 5월 16일
0

Java 문법

목록 보기
11/14
post-thumbnail

추상 클래스 (abstract class)

  • 지침 가이드 역할을 하는 기준 클래스

  • 불완전한 클래스

  • 완전하지 않기 때문에 new 할 수 없다! (객체 생성x)
    (이 클래스를 상속받는 자식을 정의하여 자식을 new 해야함)

  • 추상 메서드를 하나라도 포함하고 있으면 반드시 추상 클래스로 선언
    물론 일반 메서드 넣을 수 있음

  • 형식: abstract | class | 클래스명{abstract | 반환형 | 메서드명( ) ; }
    불완전한 메서드(=추상 메서드) 만드는 방법 : abstract수식자 + { } 없애기

  • abstract 수식자는 "추상적인"이란 뜻이며
    메서드나 클래스에 적용가능
    변수에는 붙일 수 없음 (구현하지 않을 몸체가 없기 때문...)
    '수식자'와의 첫 만남

  • 추상 클래스를 상속받는 자식 클래스도 추상 클래스도 정의될 수 있음
    (“추상 클래스의 자식이 다시 추상 클래스가 되는 것”
    == “구현 책임을 미루는 것”)

❗ 추상 메서드 구현 강제

자식 메서드는 추상 메서드를 완전하게 구현할 의무를 가짐
➡ 일종의 안전장치!⛑
안하면 컴파일 에러남

abstract class Animal {
    abstract void sound(); // 구현 강제!
}

class Dog extends Animal {
    // 부모의 메서드를 자식이 재정의하는 메서드 정의기법
	// '오버라이딩' 의무가 생김
    void sound() {
        System.out.println("멍멍");
    }
}

인터페이스 (Interface)

Java는 다중상속을 금지을 금지하지만, 현실은 '다중 상속'처럼 작동
이에 대한 Java의 해결 방법: ✅ 인터페이스

인터페이스: 메서드의 시그니처만 정의하고, 구현은 자식 클래스에게 위임
(객체아니므로 다중상속 금지 조건에 해당 X
객체에서 “기능만 쏙 뺀 것”)

  • 인터페이스는 상수와 추상메서드만을 보유할 수 있는 단위
    (Java 7이하기준)
interface Animal {
    int LEGS = 4; // public static final 자동 적용
    void sound(); // public abstract 자동 적용
}
  • A is a B → class A implements B
    "인터페이스 구현"을 표현하는 자바 문법 "implements"
  • is a 관계 (can do 관계로도 봄)
// 인터페이스 선언
public interface Flyable {
    public void fly();  // 나는 기능
}
  • 인터페이스도 추상 메서드 구현 강제 (오버라이딩)
// class에서 인터페이스 구현
class Bird implements Flyable {
    public void fly() {
        System.out.println("새가 하늘을 납니다");
    }
}
// 사용하기
public class Test {
    public static void main(String[] args) {
        Flyable f = new Bird();  // 인터페이스 타입으로 다형성 활용
        f.fly();  // 출력: 새가 하늘을 납니다
    }
}
  • 인터페이스간 상속 가능 (보기 드묾)

추상 클래스와 인터페이스 비교

항목추상 클래스인터페이스
키워드abstract classinterface
다중 상속❌ 안 됨✅ 다중 구현 가능
메서드일반 메서드 O, 추상 메서드 OJava 7까지: 추상 메서드만
Java 8 이후: default, static O
Java 9 이후: private도 가능
변수일반 필드 Opublic static final 상수만 가능
생성자O (호출 가능)❌ 없음
사용 목적상속 관계에서 공통 기능 제공기능 규약 정의, 역할 위임
상속 방법extends (단일 상속)implements (다중 구현)
예시abstract class Animalinterface Flyable

상수

상수 (항상 상'常'數, constant): 변하지 않는 수

상수의 조건

(1) 상수는 모든 인스턴스가 제한 없이 접근할 수 있어야 한다.
(2) 상수는 모든 인스턴스 간 공유될 수 있어야 한다.
(모든 인스턴스가 공통으로 이 값을 공유)
(3) 상수는 프로그램이 실행되는 동안 그 값이 변해서는 안된다

이 조건들을 충족하게 각 자리를 채워 넣으면
➡ (public )(static)(final) int x = 3;

ex) BorderLayout 클래스 내부에 있는 상수 변수

public static final String NORTH = "North";

"North" 라는 문자열 값에 모두 제한 없이 접근할 수 있게(public) 하고 클래스명으로 직접 접근 가능하게(static) 만들고
절대 바뀌지 않게(final) 만들었음.


super( ) 와 this( )

안그래도 어제 super( )공부하면서 찾아봤지
Java 생성자에서는 this() 또는 super() 중 하나만 호출할 수 있고, 둘 다 생략하면 super()가 자동으로 붙음

(자동 생성되는 super();는 매개변수가 없는 기본 생성자)

  class X { 
      X() { System.out.print(1); } 
      X(int x) { 
          this(); System.out.print(2); 
      } 
  } 
  public class Y extends X { 
      Y() { super(6); System.out.print(3); } 
      Y(int y) {
          this(); System.out.println(4); 
      } 
      public static void main(String[] a) { new Y(5); } // 1234 출력
  } 

생성자 호출 흐름

new Y(5)Y(int y)this();            // → Y() 호출Y() {
    super(6);      // → X(int) 호출this();    // → X() 호출print(1)print(2)print(3)
}print(4)

정적 바인딩과 동적 바인딩 비교문제

자료형은 서랍장 개념
메서드는 this 바인딩으로 찾기!

class Foo {     
	public int a = 3;     
	public void addFive() { 
		a += 5; 
		System.out.print("f "); 
	} 
} 

class Bar extends Foo { 
	public int a = 8; // 필드 "숨김" (hiding) 
	
	public void addFive() { 
		this.a += 5; 
		System.out.print("b "); 
	} 
}
Foo f = new Bar(); 
f.addFive(); // 동적 바인딩
System.out.println(f.a); // 정적 바인딩
//출력: b 3

addFive()는 오버라이딩 되었기 때문에 → Bar의 addFive() 실행됨 → b 출력

그런데 f.a는 Foo 타입 기준으로 보므로 → Foo.a 즉, 3 출력됨

this.a += 5;는 Bar의 a, 즉 8 + 5 = 13 되었지만,

f.a는 Foo의 a라서 여전히 3

바인딩

종류바인딩 시점기준
정적 바인딩 (static binding)컴파일 시점자료형 기준 (서랍장)
동적 바인딩 (dynamic binding)실행 시점실제 인스턴스(this) 기준

필드 숨김(field hiding)은 정적 바인딩에서 일어남.
즉, 변수(필드)는 참조 변수의 자료형(타입)을 기준으로 컴파일 시점에 결정되기 때문에 발생하는 현상 (메서드 오버라이딩처럼 런타임에 바뀌는 구조가 아님)

profile
아이들의 가능성을 믿었던 마음 그대로, 이제는 나의 가능성을 믿고 나아가는 중입니다.🌱

0개의 댓글