Java
익명 클래스
메서드의 매개변수로 인터페이스를 받는다고 가정하면 다음과 같다.
public void method(TestInterface test){
...
}
만약 기존 방법으로 사용하려면 다음과 같이, TestInterface 구현체를 만들어서 매개변수로 전달하여야 한다.
public class TestInterfaceImpl implements TestInterface {
...
}
만약 저 메서드가 일회용이라 가정하면, 딱 한번 사용하기 위해 클래스를 만들고, 메모리에 올려야 한다.
익명 클래스를 이용하면 구현체를 만들지 않고도 매개변수로 바로 전달할 수 있다.
익명 클래스를 사용하면 재사용 하지 못하고, 딱 1번만 사용이 가능하다. 그 후 어떠한 참조도 하지 못하게 된다.
method(new TestInterface() {
@Override
....
});
즉, 위의 예제와 같이 구현체를 만들지 않고 매개변수로 전달한다.
익명 클래스의 장점
만약 클래스를 만들면, 결국 그 클래스는 메모리에 올라가게 된다.
즉, 클래스를 많이 만들수록 메모리에는 그 클래스를 사용할 때 결국 올라가게 된다.
한개 두개 이렇게 클래스가 늘어난다고, 극단적으로 자바 애플리케이션이 느려지는 것은 아니다. 하지만 늘리는 것보다 줄이는게 좋다. 결국 많이 쌓이면 영향을 주기 때문이다.
어노테이션이란?
어노테이션은 클래스나, 메서드, 변수의 선언시에 @를 사용하는 것이다.
즉, 어노테이션을 통해 컴파일러에게 정보를 알려줄때 주로 사용한다.
자바에서 정해져 있는 어노테이션은 다음 3개이다.
- @Override : 해당 메서드가 상위 클래스에 있는 메서드를 오버라이드 했다는 것을 컴파일러에게 명시적으로 알려준다.
- @Deprecated : 해당 메서드가 더 이상 사용되지 않는 다는 것을 컴파일러에게 명시적으로 알려준다. 사용한다 하더라도, 컴파일러는 오류를 발생시키지 않고, 경고만 발생시킨다.
- @SupressWarnings : 컴파일러가 알려주는 경고 알고도 작성했다고 컴파일러에 알려준다. 즉, 의도한 경고 이므로, 컴파일러는 더이상 경고를 발생시키지 않는다.
만약 @Override 가 없다면?
class Test1 {
public void method1(Test test){}
}
class Test2 extends Test1 {
@Override
public void method1(Test test){}
}
기존 위와 같이 코드를 작성해야 컴파일러에게 명시적으로 오버라이딩 된 메서드라고 알려준다.
class Test1 {
public void method1(Test test){}
}
class Test2 extends Test1 {
public void method1(Test test){}
}
위와 같이 작성해도 메서드의 시그니처가 똑같기 때문에 정상적으로 오버라이딩 된 메서드로 실행된다.
class Test1 {
public void method1(Test test){}
}
class Test2 extends Test1 {
public void method1(Test test, String s){}
}
만약 실수로 매개변수가 하나 더 추가되었다고 하자.
그럼 기존 method1 메서드와는 아예 다른 메서드가 된다.
즉, 상위 클래스의 method1은 오버라이딩 하지 않은 것이 된다.
현재는 클래스를 예시로 들어서 오버라이딩이 강제되지 않는다. 그래서 따로 오류를 발생시키진 않는다. 오버라이딩을 잘못한 메서드가 아닌, 새로운 메서드가 생성되는 것 이기 때문이다.
즉, @Override의 역할은 컴파일러가 오버라이딩된 메서드의 시그니처를 검사할 수 있게 한다.
Primitive Type vs Reference Type
기본 자료형은 기본적인 데이터 유형으로 숫자, 문자 등의 값을 직접 저장합니다.
기본 자료형은 스택(stack) 메모리에 저장합니다.
참조 자료형은 객체를 참조하는데 사용되며, 객체의 위치를 가리키는 메모리 주소를 저장합니다.
즉, 참조 자료형은 객체가 실제로 어디 저장되어 있는지 주소를 알려줍니다.
실제 데이터는 Heap 공간에 저장되며, Stack 에는 해당 객체의 참조가 저장됩니다.
형 변환이란 무엇이고, 왜 사용?
형 변환은 데이터 타입을 변환하는 작업을 말합니다.
기본 타입에서의 형 변환은 2가지 방식이 있습니다.
묵시적 형 변환은 자동으로 발생하는 형 변환으로, 작은 크기의 데이터를 큰 크기에 데이터 타입에 대입하거나 연산할 때 발생합니다. 즉, 데이터 손실이 없거나 무시가능할 때 발생합니다.
명시적 형 변환은 프로그래머가 명시적으로 타입 변환을 지정하는 것 입니다. 큰 크기의 데이터를 작은 크기의 데이터 타입에 대입하거나 연산할 때 발생하며, 데이터 손실이 발생할 수 도 있습니다.
참조 타입에서 형변환에서는 다음 방식이 있습니다.
업 캐스팅은 하위 클래스의 인스턴스를 상위 클래스의 참조 타입으로 변환하는 것입니다. 하위 클래스가 상위 클래스의 모든 기능을 가지고 있는 상황에서 발생하며, 업 캐스팅을 통해 객체를 일반화된 상위 타입으로 다룰 수 있고, 이를 통해 코드의 유연성과 재사용성을 높일 수 있습니다. 업 캐스팅은 묵시적으로 이루어집니다.
다운 캐스팅은 상위 클래스의 인스턴스를 하위 클래스의 참조 타입으로 변환하는 것 입니다. 다운 캐스팅은 묵시적으로 수행되지 않기 때문에 명시적으로 형 변환을 지정해야 합니다. 만약 타입이 맞지 않거나, 상위 클래스에서 하위 클래스의 기능을 제대로 하지 못한다면 ClassCastException 오류가 발생합니다.
static import
import 문은 다른 패키지에 있는 클래스를 현재 위치에서 사용할 수 있도록 해줍니다.
즉, 다른 패키지에 있는 클래스를 사용할 때 패키지명을 생략하고 사용할 수 있게 해줍니다.
static import는 정적 멤버들을 패키지명 없이 사용할 수 있게 해줍니다. 대표적으로 Math 클래스의 기능들은 static 으로 선언되어 있어, Math.메서드() 이런 방식으로 접근이 가능한데, static import를 사용하면 클래스 명도 생략 가능합니다.
Constant Interface의 대안으로 주로 사용됩니다.
Constant Interface란 상수만 정의되어 있는 인터페이스 입니다.
Interface vs Abstract class
인터페이스는 모든 메서드의 시그니처만 작성하고, 나머지 구현은 구현체에서 전담합니다.
인터페이스에는 상수를 제외한 멤버 변수를 사용할 수 없고, 오로지 메서드만 작성이 가능합니다.
만약 인터페이스에 변수를 작성한다면 public static final이 붙어, 어디에서든 접근이 가능합니다. 또한 해당 인터페이스를 구현한 경우 네임스페이스를 붙이지 않고도 상수 사용이 가능합니다.
추상 클래스는 메서드 중 하나라도 abstract 키워드가 붙으면 해당 클래스는 추상 클래스가 됩니다.
즉, 인터페이스 처럼 모든 메서드를 구현체에서 전담하는 것이 아닌, 일부 메서드만 구현체에서 구현을 하도록 할 수 있습니다.
추상 클래스는 인터페이스와 달리 변수, 생성자, 구현되어 있는 메서드도 선언이 가능합니다. 즉 하위 구현체에서 일부 메서드만 구현 할 수 있습니다.
또한 인터페이스는 다중 구현이 가능하지만, 클래스는 단일 상속만 가능합니다.
하지만 인터페이스에서 default 키워드를 붙여 메서드를 선언하면, 미리 메서드의 구현부를 작성 할 수 있습니다. 이 메서드를 재정의하거나, 기존 구현부를 재사용할지는 구현하는 클래스가 정할 수 있습니다.
'Back-end' 카테고리의 다른 글
동일성 vs 동등성 (0) | 2023.08.16 |
---|---|
static vs static final vs final In Java (0) | 2023.08.15 |
왜 enum(열거형)을 상속하지 못할까? (0) | 2023.08.13 |
자바 static (0) | 2023.08.13 |
접근 지정자 (0) | 2023.08.13 |