C#과 Java에서 각각의 키워드인 final, sealed, readonly, const의 차이점을 비교해 보겠습니다.
1. final (Java) vs sealed (C#)
Java의 final과 C#의 sealed는 클래스 상속 및 메서드 재정의 방지와 관련이 있습니다.
기능 | Java (final) | C# (sealed) |
클래스 제한 | final class는 상속 불가능 | sealed class는 상속 불가능 |
메서드 제한 | final 메서드는 오버라이드 불가능 | sealed는 override된 메서드만 사용 가능 (sealed override) |
변수 제한 | final 필드는 한 번 할당 후 변경 불가 | sealed는 변수에 사용 불가 |
예제
Java (final)
final class FinalClass {} // 이 클래스는 상속 불가능
class Parent {
final void finalMethod() {
System.out.println("Cannot be overridden");
}
}
class Child extends Parent {
// 컴파일 에러 발생 (final 메서드는 오버라이드 불가)
// void finalMethod() {}
}
C# (sealed)
sealed class SealedClass {} // 이 클래스는 상속 불가능
class Parent {
public virtual void Method() { }
}
class Child : Parent {
public sealed override void Method() { } // 더 이상 override 불가능
}
2. final (Java) vs readonly & const (C#)
Java의 final 필드와 C#의 readonly, const는 변수의 변경 가능성과 관련이 있습니다.
기능 | Java (final) | C# (readonly) | C# (const) |
변경 가능 여부 | 한 번 초기화 후 변경 불가 | 생성자에서만 변경 가능 | 컴파일 타임 상수, 변경 불가 |
할당 시점 | 선언과 동시에 or 생성자에서 가능 | 선언과 동시에 or 생성자에서 가능 | 선언과 동시에만 가능 |
인스턴스/정적 필드 | 인스턴스 필드, 정적 필드 모두 가능 | 인스턴스 필드, 정적 필드 모두 가능 | 반드시 정적(static)이며, 리터럴 값만 가능 |
사용 가능한 값 | 모든 값 가능 (객체, 기본형) | 모든 값 가능 (객체, 기본형) | 리터럴 값만 가능 (숫자, 문자열 등) |
예제
Java (final)
class Example {
final int instanceValue; // 생성자에서 초기화 가능
final static int STATIC_VALUE = 100; // 선언과 동시에 초기화 가능
Example(int value) {
this.instanceValue = value; // 생성자에서만 초기화 가능
}
}
C# (readonly vs const)
class Example {
public readonly int instanceValue; // 생성자에서 초기화 가능
public const int CONSTANT_VALUE = 100; // 상수 값, 변경 불가
public Example(int value) {
this.instanceValue = value; // 생성자에서 초기화 가능
// this.CONSTANT_VALUE = 200; // 오류 발생 (const는 변경 불가)
}
}
3. final 변수 vs readonly 필드 vs const 차이 정리
- final(Java) ≈ readonly(C#) → 생성자에서 값을 변경할 수 있음.
- const(C#) → 반드시 컴파일 타임 상수여야 하며, 선언과 동시에 초기화해야 함.
사용 예시
예제 | Java (final) | C# (readonly) | C# (const) |
인스턴스 필드 | ✅ (생성자에서 초기화 가능) | ✅ (생성자에서 초기화 가능) | ❌ (불가능) |
정적 필드 | ✅ (final static 사용) | ✅ (static readonly 사용) | ✅ (const 사용) |
런타임 값 할당 가능 여부 | ✅ (가능) | ✅ (가능) | ❌ (컴파일 타임에 결정된 값만 가능) |
결론
- 클래스 상속 제한
- Java는 final을 사용.
- C#은 sealed을 사용.
- 메서드 재정의 제한
- Java는 final을 사용.
- C#은 sealed override를 사용.
- 변수 변경 제한
- Java는 final을 사용.
- C#은 readonly 또는 const를 사용 (readonly는 생성자에서 초기화 가능, const는 변경 불가).
Java와 C#에서 abstract와 final(Java) 또는 sealed(C#)을 함께 사용하는 경우를 살펴보겠습니다.
1. abstract와 final (Java)
Java에서 abstract와 final은 동시에 사용할 수 없습니다.
이유는 abstract는 상속을 통해 구현해야 하는 미완성 클래스를 의미하지만,
final은 상속을 금지하기 때문입니다.
Java에서 불가능한 코드
abstract final class Example { // 오류 발생
}
컴파일 오류: The class Example can not be declared both abstract and final
해결 방법:
- abstract를 유지하고 final을 제거 (abstract class Example {})
- final을 유지하고 abstract를 제거 (final class Example {})
단, abstract 클래스 내의 메서드에서 final을 사용하는 것은 가능합니다.
abstract class Parent {
final void nonOverridableMethod() {
System.out.println("This method cannot be overridden");
}
abstract void mustBeImplemented();
}
class Child extends Parent {
// final 메서드는 오버라이드 불가
// void nonOverridableMethod() {} // 오류 발생
@Override
void mustBeImplemented() {
System.out.println("Implemented in Child");
}
}
2. abstract와 sealed (C#)
C#에서도 abstract와 sealed는 동시에 사용할 수 없습니다.
이유는 Java와 동일하게 abstract는 상속을 요구하는 반면,
sealed는 상속을 금지하기 때문입니다.
C#에서 불가능한 코드
public abstract sealed class Example {} // 오류 발생
컴파일 오류: 'Example' cannot be both abstract and sealed
해결 방법:
- abstract를 유지하고 sealed를 제거 (abstract class Example {})
- sealed를 유지하고 abstract를 제거 (sealed class Example {})
하지만, C#에서는 sealed override를 사용하여 메서드의 재정의를 막을 수 있습니다.
abstract class Parent {
public abstract void MustBeImplemented();
public virtual void NormalMethod() {
Console.WriteLine("Can be overridden");
}
}
class Child : Parent {
public override void MustBeImplemented() {
Console.WriteLine("Implemented in Child");
}
public sealed override void NormalMethod() {
Console.WriteLine("Cannot be overridden anymore");
}
}
class GrandChild : Child {
// public override void NormalMethod() {} // 오류 발생 (sealed로 인해 재정의 불가)
}
결론
특징 | Java (final) | C# (sealed) |
abstract class와 함께 사용 가능? | ❌ 불가능 | ❌ 불가능 |
메서드에서 사용 가능? | ✅ 가능 (final 메서드는 오버라이드 금지) | ✅ 가능 (sealed override로 재정의 금지) |
- 클래스에서는 abstract와 final/sealed를 함께 사용할 수 없다.
- 메서드에서는 final(Java) 또는 sealed override(C#)를 사용하여 오버라이드를 막을 수 있다.
'프로그래밍' 카테고리의 다른 글
자바와 닷넷 비교 - 생성자 (0) | 2025.03.02 |
---|---|
자바와 닷넷 비교 - static (0) | 2025.03.02 |
자바와 닷넷 문자열 비교 (2) | 2025.03.02 |
자바와 닷넷 리플렉션 비교 (0) | 2025.03.02 |
자바와 닷넷 비교 - ENUM (0) | 2025.03.02 |