★Enum (열거형)
Enum의 주요 메서드
- values(): 열거형에 정의된 모든 값을 배열로 반환.
- valueOf(String name): 이름으로 열거형 상수를 찾음.
// 모든 값을 배열로 반환
enum Day {
MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY
}
public class EnumValuesExample {
public static void main(String[] args) {
Day[] days = Day.values();
for (Day day : days) {
System.out.println(day); // MONDAY, TUESDAY, ... 출력
}
}
}
사용 시 유의점
- Enum은 상수 값을 정의하는 데 유용하지만, 값의 추가나 변경이 자주 일어날 경우 유연성에서 부족할 수 있습니다.
- Enum을 사용할 때는 상수의 집합이 의미가 있는지, 그 값들이 변경되지 않도록 보장해야 하는 경우 적합합니다.
< 예제 >
enum Day {
MONDAY("월요일"), TUESDAY("화요일"), WEDNESDAY("수요일"),
THURSDAY("목요일"), FRIDAY("금요일"), SATURDAY("토요일"), SUNDAY("일요일");
private String koreanName;
Day(String koreanName) {
this.koreanName = koreanName;
}
public String getKoreanName() {
return koreanName;
}
}
public class EnumExample {
public static void main(String[] args) {
Day today = Day.MONDAY;
System.out.println(today.getKoreanName()); // 월요일 출력
}
}
//////////////////////////////응용
enum Season {
SPRING, SUMMER, FALL, WINTER
}
public class EnumComparisonExample {
public static void main(String[] args) {
Season currentSeason = Season.SUMMER;
if (currentSeason == Season.SUMMER) {
System.out.println("It's summer!");
}
}
}
★람다 (Lambda Expression)
★스트림 (Stream)
★제네릭 (Generics)
📌 클래스, 인터페이스, 메서드 등에서 사용하는 타입을 매개변수화하여 코드의 재사용성과 유연성을 높여주는 Java의 중요한 기능
제네릭의 사용 상황
- 컬렉션 프레임워크:
- List, Set, Map 등에서 제네릭을 사용하여 타입을 명확히 지정함으로써 타입 안전성을 보장하고, 불필요한 캐스팅을 피할 수 있습니다.
- 유틸리티 클래스 작성:
- 제네릭을 사용하면 다양한 타입에 대해 범용적으로 사용할 수 있는 클래스나 메서드를 작성할 수 있습니다. 예를 들어, Box 클래스를 사용하면 Integer, String 등 다양한 타입을 처리할 수 있습니다.
- 타입 제한이 필요한 경우:
- 특정 타입이나 그 하위 타입에 대해서만 작동하도록 제네릭을 사용할 때 타입 제한을 두어, 보다 강력한 타입 안전성을 유지할 수 있습니다.
- API 설계:
- 제네릭을 사용하면 클래스나 메서드의 재사용성을 높이기 위해, 라이브러리나 프레임워크를 설계할 때 유용합니다. 예를 들어, Java의 ArrayList는 다양한 타입을 받을 수 있도록 제네릭을 사용합니다.
public <T extends Number> void printNumber(T num) {
System.out.println(num);
}
제네릭의 단점
- 타입 불일치: 컴파일 타임에 타입을 지정하므로 런타임에 타입을 변경할 수 없습니다.
- 다형성 제한: 제네릭 타입은 **원시 타입(primitive type)**을 사용할 수 없습니다. 예를 들어, int 대신 Integer와 같은 래퍼 클래스를 사용해야 합니다.
- 복잡성: 제네릭을 사용할 때 코드가 다소 복잡해질 수 있습니다.
1. 제네릭 클래스
// 제네릭 클래스를 정의할 때 타입 파라미터 <T>를 사용
class Box<T> {
private T item;
public void setItem(T item) {
this.item = item;
}
public T getItem() {
return item;
}
}
public class Main {
public static void main(String[] args) {
Box<Integer> intBox = new Box<>();
intBox.setItem(10);
System.out.println(intBox.getItem()); // 10
Box<String> strBox = new Box<>();
strBox.setItem("Hello");
System.out.println(strBox.getItem()); // Hello
}
}
2. 제네릭 메서드
// 제네릭 메서드는 메서드 레벨에서 타입 파라미터를 지정
public class Main {
public static <T> void printArray(T[] array) {
for (T element : array) {
System.out.print(element + " ");
}
System.out.println();
}
public static void main(String[] args) {
Integer[] intArray = {1, 2, 3};
String[] strArray = {"Hello", "World"};
printArray(intArray); // 1 2 3
printArray(strArray); // Hello World
}
}
3. 제네릭 인터페이스
interface Pair<K, V> {
K getKey();
V getValue();
}
class KeyValuePair<K, V> implements Pair<K, V> {
private K key;
private V value;
public KeyValuePair(K key, V value) {
this.key = key;
this.value = value;
}
public K getKey() {
return key;
}
public V getValue() {
return value;
}
}
public class Main {
public static void main(String[] args) {
Pair<Integer, String> pair = new KeyValuePair<>(1, "One");
System.out.println(pair.getKey() + ": " + pair.getValue()); // 1: One
}
}
★static
📌 Java에서 클래스나 객체의 특정 구성 요소에 대한 정적(Static) 특성을 정의하는 키워드입니다. 이를 사용하면 해당 구성 요소가 클래스에 속하게 되며(객체가 아닌 클래스의 변수, 메소드 선언 가능), 객체의 인스턴스화 없이 접근할 수 있습니다.
★추상 클래스 (Abstract Class)
📌 구현되지 않은 메서드(즉, 추상 메서드)를 포함할 수 있는 클래스입니다. 추상 클래스는 직접 인스턴스를 생성할 수 없으며, 다른 클래스에서 상속받아 사용하도록 설계됩니다.
정의:
- 추상 클래스는 abstract 키워드로 선언되며, 구현되지 않은 메서드를 포함할 수 있습니다.
- 인스턴스를 생성할 수 없다는 특징이 있으며, 이를 상속받은 자식 클래스에서 추상 메서드를 구현해야 합니다.
사용처:
- 공통된 속성과 동작을 여러 클래스에서 공유해야 할 때 사용합니다.
- 공통된 기본 기능을 부분적으로 구현하고, 그 외의 구체적인 구현은 자식 클래스에서 하도록 유도할 때 유용합니다.
- 저 인터페이스 공통된 기능을 다른 클래스들에게 강제 한다는 말은 인터페이스에서 사용된 변수, 메소드는 반드시 인터페이스를 구현할 클래스에서 반드시 구현되어야만 한다. (추상 클래스는 안해도 상관없다.)
- 이런 일이 발생하는 이유는 객체의 청사진이 클래스라면, 클래스의 청사진이 인터페이스이기 때문
★인터페이스
📌 클래스의 청사진으로, 인터페이스를 구현할 클래스는 반드시 인터페이스에서 사용된 변수, 메소드를 반드시 구현해야한다.
- implements 키워드를 사용하여 인터페이스를 구현할 수 있습니다.
public class 클래스명 implements 인터페이스명 {
// 추상 메서드 오버라이딩
@Override
public 리턴타입 메서드이름(매개변수, ...) {
// 실행문
}
}
- 인터페이스 간의 상속은 implements 가 아니라 extends 키워드를 사용합니다.
public class Main extends D implements C {
@Override
public void a() {
System.out.println("A");
}
@Override
public void b() {
System.out.println("B");
}
@Override
void d() {
super.d();
}
public static void main(String[] args) {
Main main = new Main();
main.a();
main.b();
main.d();
}
}
interface A {
void a();
}
interface B {
void b();
}
interface C extends A, B {
}
class D {
void d() {
System.out.println("D");
}
}
This
📌 현재 객체 자신을 참조하는 키워드로, 객체 내부에서 객체의 멤버(필드, 메서드, 생성자)를 명확히 참조하기 위해 사용됩니다.
정의 | 객체의 현재 인스턴스를 참조하는 키워드로, 객체 내부에서 멤버 변수와 메서드를 호출하거나 생성자 호출에 사용. |
특징 | ✔ 객체 자신의 주소를 나타냄 ✔ 인스턴스 멤버에 접근할 때 사용 ✔ 메서드나 생성자에서 주로 활용됨 ✔ 정적(static) 맥락에서는 사용 불가 |
- 위 경우 입력값 model이 객체의 model이 아닌 매개변수 model에 입력됨
- 위 경우 입력값 model이 객체의 model에 입력됨
- 매개변수, 지역 변수, 클래스 변수의 이름이 동일할 경우 구분을 위해 사용
- this. = 현재 객체의 변수
- this() = 현재 객체 생성자
final
📌 현재 클래스, 변수를 더이상 변경 불가하게 만들어 버린다. 상속도 막힌다.
Object
📌 Java 내 모든 클래스들의 최상위 부모 클래스, 다양한 기능 제공
★객체지향 프로그래밍
class Car {
String model;
String color;
// 기본 생성자
public Car(String model, String color) {
this.model = model;
this.color = color;
}
// gasPedal 메서드: 속도를 설정하는 메서드로 kmh 값을 speed 필드에 저장하고 반환
public double gasPedal(double kmh) {
speed = kmh; // 자동차의 현재 속도를 kmh 값으로 설정
return speed; // 설정된 속도 반환
}
}
public class Main {
public static void main(String[] args) {
// 인스턴스화 과정
Car car1 = new Car("Sedan", "Red"); // Car 클래스로부터 car1 객체 생성
Car car2 = new Car("SUV", "Blue"); // Car 클래스로부터 car2 객체 생성
System.out.println(car1.model); // Sedan 출력
System.out.println(car2.model); // SUV 출력
}
}
Car car1 = new Car("Sedan", "Red");는 Car 클래스를 사용하여 "Sedan"과 "Red"라는 속성값을 가지는 새로운 Car 객체를 생성하고, 그 객체를 car1이라는 참조형 변수에 참조하도록 하는 코드
인스턴스(객체) | car1, car2 |
인스턴스화 | new |
메서드 | public double gasPedal(double kmh) |
클래스 | class Car |
생성자 | public Car(String model, String color) / 생성자는 메서드와 다르게 클래스와 이름이 같다 |
★오버라이딩
🐳 부모 클래스로부터 상속받은 메서드의 내용을 재정의 하는 것을 오버라이딩이라고 합니다.
- 선언부가 부모 클래스의 메서드와 일치해야 합니다.
- 접근 제어자를 부모 클래스의 메서드 보다 좁은 범위로 변경할 수 없습니다.
- 예외는 부모 클래스의 메서드 보다 많이 선언할 수 없습니다
오버라이딩 사용 상황:
- 부모 클래스의 메서드를 자식 클래스에서만 새롭게 정의하고자 할 때.
- 상속 구조에서 특정 메서드를 변경하고자 할 때.
- 다형성을 활용하여, 자식 클래스의 특성에 맞는 기능을 구현하고자 할 때.
★오버로드
🐳 오버로딩은 하나의 클래스 내에서 동일한 이름을 가진 메서드를 여러 개 정의하는 것입니다. 하지만 오버로딩된 메서드는 매개변수의 개수나 타입이 달라야 합니다.
- 즉, 메서드 이름은 같지만 매개변수의 타입, 개수, 순서가 다르면 컴파일러가 어떤 메서드를 호출할지 구분할 수 있습니다. 반환 타입만 달라서는 오버로딩이 발생하지 않습니다. 컴파일 시점에 메서드가 결정됩니다
오버로딩 사용 상황:
- 하나의 메서드 이름으로 다양한 입력을 처리하고자 할 때.
- 매개변수의 개수나 타입이 다른 경우에도 같은 작업을 처리하고 싶을 때.
- 메서드를 다수 정의해야 하는 경우, 메서드 이름을 통일하고 코드의 가독성을 높이기 위해.
다형성 & 추상화
동일한 메서드 이름이지만 다른 방식으로 동작할 수 있게 함
- sound를 한 부모에서 상속받았지만 내용은 다름 = 다형성은 오버라이딩으로 구현됨
// 부모 클래스
class Animal {
public void sound() {
System.out.println("Animal makes a sound");
}
}
// 자식 클래스 1
class Dog extends Animal {
@Override
public void sound() {
System.out.println("Dog barks");
}
}
// 자식 클래스 2
class Cat extends Animal {
@Override
public void sound() {
System.out.println("Cat meows");
}
}
참조형 자료구조
클래스 & 객체 & 인터페이스
인스턴스 맴버와 클래스 맴버
생성자
항목 | 내용 |
정의 | 객체 생성 시 초기화 작업을 수행하는 특수한 메서드. 클래스 이름과 동일한 이름을 가지며 반환 타입이 없음. (초기화의 이유 : 안정적이고 예측 가능한 상태에서 객체를 사용할 수 있도록 보장하기 위해서 ) |
특징 | ✔ 클래스 이름과 동일 ✔ 반환 타입이 없음 (void도 사용하지 않음) ✔ 객체 생성 시 자동 호출 ✔ 오버로딩 가능 |
사용처 | ▶ 객체 초기화 시 필수 데이터를 설정하거나 특정 작업 수행 ▶ 객체를 생성하면서 동시에 원하는 상태로 설정해야 할 때 사용 |
종류 | - 기본 생성자: 매개변수가 없는 생성자 (컴파일러가 자동 생성, 명시적 정의 가능). - 매개변수 생성자: 원하는 값으로 객체 초기화 |
기본값 | - 생성자를 정의하지 않으면 컴파일러가 기본 생성자를 자동으로 제공. - 생성자를 정의하면 기본 생성자는 제공되지 않음. |
< 접근 제어자 정리표 >
접근 제어자 | 같은 클래스 | 같은 패키지 (클래스 폴더) | 자식 클래스 | 외부 클래스 |
public | O | O | O | O |
protected | O | O | O | X |
default | O | O | X | X |
private | O | X | X | X |
접근 제어
< 접근 제어자 정리표 >
접근 제어자 | 같은 클래스 | 같은 패키지 (클래스 폴더) | 자식 클래스 | 외부 클래스 |
public | O | O | O | O |
protected | O | O | O | X |
default | O | O | X | X |
private | O | X | X | X |
< 사용 가능한 접근 제어자 >
클래스 | public, default |
메서드 & 멤버 변수 | public, protected, default, private |
지역변수 | 없음 |
'Back-End (Web) > JAVA' 카테고리의 다른 글
[JAVA] HASH란 무엇인가 (1) | 2024.11.21 |
---|---|
[JAVA] 자바의 정렬 (0) | 2024.11.21 |
[JAVA] NULL (0) | 2024.11.13 |
[JAVA] 쓰레드 & 람다 함수 & 스트림 (3) | 2024.11.13 |
[JAVA] Generic (3) | 2024.11.12 |