```
int i = 1; // 조건 변수 초기화 while (i <= 5) { // 조건식- for : 조건변수에 따른 조건식이 참일 동안 반복된다. 가장 많이 쓰인다.
```
for (조건 변수 초기화; 조건식; 조건 변수 제어) {
// 반복해서 실행될 코드
}
``` ``` // 복잡할때 -> 일반적인 방법 ```// 편한 방법 -> 줄바꿈이 안된다.
System.out.printf("%d살 %s입니다.\n", age, name); // 줄바꿈이 안되니까 이스케이프 시퀀스 \n 쓰면 된다.변수[] = new Int[배열의 길이];변수[] = {값1,값2,값3,값4,값5}[클래스명] [변수명] = new [클래스명](); // 객체 생성 -> 클래스(설계도)를 실체하는 인스턴스(객체)로 만드는 선언 : 배열과 비슷하다.int[] person = new int[5]; -> int[]자리만 클래스로 바뀜.equals
```
String str1 = new String("Hello world!!");
String str2 = new String("Hello world!!");
System.out.println(str1);
System.out.println(str2);
System.out.println(str1 == str2);
// str1, str2는 참조값(주소값)
// heap 안에 만들어진 애들은 인스턴스나 객체라고 부른다.
// 주소를 비교 -> 만약에 두 변수가 동일한 주소를 가지고 있다면 같다고 나옴.
System.out.println("------------");
if( str1 == str2 ){
System.out.println("str1과 str2는 같은 값을 가지고 있습니다.");
}
else{
System.out.println("str1과 str2는 다른 값을 가지고 있습니다.");
}
// 두 참조 변수가 가리키는 객체의 내용을 비교
System.out.println("------------");
if( str1.equals(str2) ){
System.out.println("str1과 str2는 같은 값을 가지고 있습니다.");
}
else{
System.out.println("str1과 str2는 다른 값을 가지고 있습니다.");
}
```
static
static 변수는 클래스 수준의 변수로서(변수나 함수에 쓸 수 있음), 해당 클래스의 모든 인스턴스들이 공유하는 변수입니다. 즉, 클래스의 모든 객체들이 동일한 static 변수를 참조하며 값을 공유합니다.
이때 모든 객체들 안에는 static 변수는 포함되지 않고 클래스 내의 동일한 static 변수를 참조한다.
static 변수는 클래스가 로드될 때 생성되며, 프로그램이 실행되는 동안 메모리에 유지됩니다.
static 변수는 클래스 이름을 통해 접근할 수 있으며, 클래스의 인스턴스를 생성하지 않고도 사용할 수 있습니다.
클래스 내의 static 으로 만들어진 함수는 클래스 내의 static 으로 만들어진 변수를 써야된다.(물론 스태틱 함수 내부의 함수는 static을 쓸 필요는 없다.) -> 클래스 생성시 만들어지는 스태틱 함수 내의 변수는 객체 만들기 전의 변수를 사용할 수 없다는 말
static 변수는 일반적으로 클래스 수준의 상수 또는 모든 인스턴스가 공유해야 하는 값을 저장하는 데 사용됩니다. 예를 들어, 다수의 객체가 공유하는 카운터 값이나 설정값 등을 static 변수로 정의할 수 있습니다.
아래는 static 변수의 예시입니다
```
public class Counter {
private static int count = 0;
public Counter() {
count++;
}
public static int getCount() {
return count;
}
public static void main(String[] args) {
Counter c1 = new Counter();
System.out.println(Counter.getCount()); // 출력: 1
Counter c2 = new Counter();
System.out.println(Counter.getCount()); // 출력: 2
}
- 위의 예시에서 count 변수는 static 키워드로 선언되었습니다. 이 변수는 Counter 클래스의 모든 인스턴스들이 공유하는 변수이므로,
Counter 객체가 생성될 때마다 count 값이 증가합니다.
getCount() 메서드를 통해 count 값을 얻을 수 있습니다. 출력 결과로는 1과 2가 차례로 출력됩니다.
클래스명(){ ★★ 초기화 ★★ }오버로딩(overloading : 과적)
- 오버로딩(overloading)은 하나의 클래스 내에서 같은 이름의 메서드를 다양한 매개변수로 정의하는 것-> 코드의 가독성과 재사용성을 높일 수 있습니다.
```
int add(int a, int b) {
return a + b;
}
double add(double a, double b) {
return a + b;
}
int add(int a, int b, int c) {
return a + b + c;
}
```
오버라이딩(overriding : 치환) : 상속 관계에서 상위 클래스의 메서드를 하위 클래스에서 재정의하는 것
객체 지향 3요소
- 캡슐화 (Encapsulation): 관련된 데이터와 메서드를 하나의 단위인 객체로 묶는 것을 의미합니다.
객체는 내부의 상태(데이터)를 숨기고 외부에 공개된 인터페이스(메서드)를 통해 상호작용합니다. 이를 통해 데이터의 무결성을 보호하고 코드의 유지보수성을 향상시킵니다.
- 상속 (Inheritance): 클래스 간의 계층적인 관계를 형성하여 코드를 재사용하는 방법입니다.
상속을 통해 하위 클래스는 상위 클래스의 속성과 동작을 상속받아 사용할 수 있으며, 필요한 경우 상속된 멤버들을 재정의하거나 추가 기능을 구현할 수 있습니다.
- 다형성 (Polymorphism): 하나의 객체가 여러 가지 타입을 가질 수 있는 능력을 의미합니다.
다형성은 상속과 밀접한 관련이 있으며, 부모 클래스의 타입으로 파생된 여러 클래스의 객체를 동일한 타입으로 다룰 수 있습니다. 이를 통해 유연하고 확장 가능한 코드를 작성할 수 있으며, 메서드 오버라이딩과 인터페이스를 통한 다형성을 구현할 수 있습니다.
업캐스팅과 다운캐스팅(형변환 중 오브젝트 형변환)
형변환 기본 개념 : 더 큰(상위개념)이 작은 타입 안으로 들어갈 수 없기 때문에 작은 타입에 큰 타입을 집어 넣으려고 하면
명시적으로 '()' 괄호 안에 해당 형태를 표시 해줘야된다. 반대로 큰 타입을 작은 타입으로 형변환 하려고 하면 자동으로 변환해준다.
```Cat cat = new Cat();
Animal animal = cat; // Cat 객체를 Animal 타입으로 업캐스팅
Animal animal = new Cat();
```
Animal animal = new Cat(); // Cat 객체를 Animal 타입으로 업캐스팅
Cat cat = (Cat) animal; // Animal 타입을 다시 Cat 타입으로 다운캐스팅
```
class 클래스명{
클래스명(){} -> 보이지 않더라도 자바에서 기본적으로 생성되는 것
클래스명(int i){생성자 내용추가} -> 이렇게 매개변수가 들어간 생성자를 만들었을때는 자바에서 기본으로 만들어준 생성자는 따로 만든 것이 없다면 없어지게된다.
}
```
``` class 자식클래스 extends 부모클래스 {-> 보이지 않더라도 자바에서 기본적으로 생성되는 자식 생성자
// 만약에 부모 클래스의 생성자가 매개변수를 포함한 생성자가 있다면 이 코드는 작동되지 않는다.
기본 생성자가 없기 때문. 따라서
```
클래스명(){
super(매개변수);
} -> 이런식으로 부모클래스에 있는 형태에 맞는 기본 생성자를 호출해줘야된다. 여기서 super()는 부모 클래스의 생성자를 호출하는 메서드다.
}Object obj;
obj = 10; // int 타입
obj = "Hello"; // String 타입
obj = new ArrayList<>(); // ArrayList 타입
obj = true; // boolean 타입
제네릭(generic : 포괄적인)
- 타입 안정성(Type Safety): 제너릭은 컴파일 시간에 타입 체크를 수행하여 잘못된 타입 사용을 방지합니다.
컴파일러는 타입 매개변수를 이용하여 타입 검사를 수행하므로, 컴파일 시점에서 오류를 잡아내고 실행 시점에서의 ClassCastException과 같은 예외를 방지할 수 있습니다.
- 코드 재사용성: 제너릭을 사용하면 여러 종류의 타입에 대해 동일한 코드를 재사용할 수 있습니다. 하나의 제너릭 클래스나 메서드를 선언하면 다양한 타입에 대해 동작하는 코드를 작성할 수 있습니다.
- 컴파일 타임 타입 체크: 제너릭을 사용하면 타입 매개변수에 대한 타입 체크를 컴파일 시간에 수행하므로, 타입 안정성을 보장할 수 있습니다. 이로 인해 런타임에 발생할 수 있는 타입 관련 오류를 사전에 방지할 수 있습니다.
- 자동 형변환: 제너릭을 사용하면 컴파일러가 자동으로 형변환을 처리해줍니다. 타입 매개변수에 해당하는 실제 타입으로의 형변환을 개발자가 수동으로 처리할 필요가 없습니다.
// 제너릭 클래스
class MyGenericClass<T> {
private T data;
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
}
// 제너릭 메서드
public <T> void printArray(T[] array) {
for (T element : array) {
System.out.println(element);
}
}
// 제너릭 타입 사용
MyGenericClass<Integer> myObj = new MyGenericClass<>();
myObj.setData(10);
int value = myObj.getData();
String[] stringArray = {"Hello", "World"};
printArray(stringArray);
```
String numberStr = "123";
int number = Integer.valueOf(numberStr);
System.out.println(number); // 123 ```
int number = 123;
Integer numberObj = Integer.valueOf(number);
System.out.println(numberObj); // 123
``` Scanner sc = new Scanner(System.in);
System.out.print("이름을 입력하세요: ");
String name = sc.nextLine();
System.out.print("나이를 입력하세요: ");
int age = sc.nextInt();
sc.nextLine(); // 개행 문자 소비
System.out.print("직업을 입력하세요: ");
String occupation = sc.nextLine();
``` ``` // LocalDate 사용해서 현재 날짜 객체 생성