[자바] 인터페이스와 Inner Class

tech_bae·2025년 3월 14일

Java

목록 보기
1/10
post-thumbnail

인터페이스

클래스들이 구현해야하는 메서드들의 집합

클래스를 만들기위한 기본 뼈대.

추상 클래스 - 구현된 메소드와 필드를 가질수 있음, 단일 상속만 가능

인터페이스 - 메서드의 시그니쳐만 정의(이름, 변환형, 매개변수), 다중 상속 가능

인터페이스내의 메서드는 publicabstract로 간주(생략가능)

인터페이스는 상수만 가질 수 있음(public, static, final로 자동으로 선언)

public interface TestInterface {
    int a = 0;  //자동으로 public static final

    public abstract void testMethod();
    void testMethod2(); //기본적으로 public abstract 간주
}

인터페이스가 publicabstract 만 가능한 건 아님

default와 static은 가능

  • default : 인터페이스 내에서 구현이 가능(override도 가능)
  • static : 인터페이스 내에서 구현이 가능하나 재정의 불가능(override 불가)
public interface TestInterface {
    default void defaultTestMethod() {
        System.out.println("Default Method is available in Interface");
    }

    static void staticTestMethod() {
        System.out.println("Static Method is also available in Interface");
    }
}

package lec1.test.review;

public class TestClass implements TestInterface {

    @Override
    public void defaultTestMethod() {
        System.out.println("Default Method is available to override");

        TestInterface.super.defaultTestMethod(); //super키워드를 통해 인터페이스 내의 default메소드 호출 가능
    }

}

package lec1.test.review;

public class TestMain {
    public static void main(String[] args) {
        TestClass t = new TestClass();

        t.defaultTestMethod(); //Override된 메소드 호출
        TestInterface.staticTestMethod(); // Static이므로 인터페이스 이름을 통해 바로 접근 가능
    }
}

클래스가 여러 인터페이스를 구현가능(like 다중상속)

class A implements intesrfaceA, interfaceB
interface C extends interfaceA, interfaceB

인터페이스가 인터페이스를 다중상속가능

단, 이를 구현하는 class는 모든 메서드를 구현해야한다.

인터페이스 구현과 클래스 상속을 동시에 받는 겨우

class a extends b implements c

//c : void sleep();, method1();
//b : public void sleep();

클래스의 메서드가 인터페이스의 메서드보다 우선

c에 있는 sleep()을 b가 구현하고 a가 b를 상속받는다.

⇒ a는 method1()만 구현하면 된다. (부모클래스가 인터페이스를 이미 구현하고 상속한걸로 인식)

캐스팅

  • 다운캐스팅 - 부모 객체를 자식 객체로 변환( 문제가 자주 일어남)
  • 업캐스팅 - 자식 객체를 부모 타입으로 변환 (문제 거의 없음)

Inner Class

inner class는 outer 클래스의 멤버로 정의

inner class에서 outer변수는 사용이 가능하다

(변수명이 같다면 inner우선 ⇒ this.변수명이 자동으로 붙음)

outer변수를 사용하려면 outer클래스명.this.변수명 으로 사용

outer class에서 inner class의 변수에는 접근이 불가능(static 제외)

⇒ inner class의 객체를 생성후에 접근해야함

inner class의 인스턴스를 생성하려면 outer class의 인스턴스를 먼저 생성해야함

OuterClass out = new OuterClass();
OuterClass.InnerClass in = out.new InnerClass();

OuterClass.InnerClass in2 = new OuterClass().new InnerClass();

Static Inner Class

Outer class의 인스턴스와 독립적으로 존재

Outer class의 정적멤버에만 접근이 가능

Outer class의 인스턴스 없이 독립적으로 생성가능

Inner Class의 메모리 누수

static이 아닌 inner class는 메모리 누수를 일으킬 우려가 있음

일반 Inner Class는 Outer Class에 대한 참조를 유지하기 때문

Inner Class의 인스턴스가 생성되는 순간 Outer 클래스의 참조를 가진다.

⇒ Outer Class의 this 참조를 자동으로 포함하기 때문에 Outer class가 더이상 필요 없더라고 GC가 이를 해제하지 못함

⇒ Inner class의 객체가 Outer class의 객체보다 오래 유지되면 메모리 누수 발생 가능

public class OuterClass {
    private int ramdomNumber = 45678;

    public int getRamdomNumber() {
        return ramdomNumber;
    }

    public class InnerClass {
        public void trash() {
            System.out.println(ramdomNumber + "is still available");
        }
    }

}

public class TestMain {
    public static void main(String[] args) {
        OuterClass outerInstance = new OuterClass();
        OuterClass.InnerClass innerInstance = outerInstance.new InnerClass();

        System.out.println(outerInstance.getRamdomNumber());
        innerInstance.trash();
        outerInstance = null;
        //System.out.println(outerInstance.getRamdomNumber());
        innerInstance.trash();
    }
    
}

출력: 
45678
45678is still available
45678is still available

Outer 인스턴스가 null 로 변하고 나서도 Inner 인스턴스는 값을 계속 참조하여 호출이 가능함 → 메모리누수!

💡

메모리 누수를 방지하기 위해 특별한 경우가 아니라면(외부클래스의 멤버 사용 등) static으로 생성 요망

profile
전 아무고토 몰루고 아무고토 못해여

0개의 댓글