JAVA 요약 -상-

CSJ5801·2024년 2월 21일

자바스크립트 파트를 작성하고 한동안 글을 작성하지 못하였다. 자바와 데이터베이스를 학습할 때만 해도 이미 배운 경험이 있었기에 여유가 있었지만 서블릿과 스프링을 배우기 시작한 뒤로 매일 새로운 걸 배우고 익숙해지는 과정이 필요했기에 비전공자들과 비슷한 마음가짐을 가지고 임했던 거 같다. 그래도 글을 꾸준히 적겠다고 나 자신에게 맹세했기에 계속 적어나갈 생각이다. 다만, 글을 적는 시기는 불규칙해질거 같다.

사실 나는 언어선택에 있어서 고민이 많았었다. 웹 프로그래밍에 있어서 백엔드에 관련한 언어는 다양했기에 그 중 하나를 중점적으로 공부해야 할 것을 선택하기란 까다로운 일이었다. 관련언어로는 자바, 파이썬, 자바스크립트(Node.js), PHP, Ruby 등이 있었고 그 중 PHP와 Ruby는 아직 생소했기에 선택지에서 제외했다. 다음으로는 워크넷같은 구직 사이트에 들어가서 여러 기업들이 구직 공고를 일일히 찾아서 어느 언어를 쓰는게 내 기준에서 도움이 될지 선별하는 과정을 거쳤다. 그래서 선택한 것이 자바이다. 외국에서는 잘 모르겠지만 국내에서는 자바가 가장 범용성있게 사용되는 언어라고 생각이 들었다.(현업에서는 어떨지는 모르겠지만 내가 느끼기엔 그렇다)

1.자바
자바는 웹 프로그래밍에서 서버를 다루는 언어로서 서버 측에서 비즈니스 로직을 처리하고 데이터베이스와 통신하는 데 사용된다. 이를 통해 사용자의 요청에 따라 동적으로 콘텐츠를 생성하고 처리할 수 있다. 프레임워크인 Spring을 이용하여 보다 생산적이고 편리하게 프로젝트를 개발할 수 있다...
라고 설명할 수 있겠지만 직접 사용하기 이전까지는 어떠한 느낌인지는 크게 와닿지 않았다.
지금와서는 데이터베이스와 연동하여 프론트엔드에 연결한 뒤 브라우저에 띄워보았기 때문에 이해할 수 있지만 학교에서 자바를 처음 접할 때만 해도 이걸 어떻게 활용할지 무엇을 위해 배우는지도 막막했던 기억이 있다. 역시 배운걸 직접 활용하는 방법이 제일 베스트인 공부법인거 같다.

  1. 콘솔에 로그 찍기
    자바도 역시 다른 언어와 똑같이 콘솔이나 브라우저에 Hello World!를 찍는 거부터 시작했다.
    다만 차이점은 로그를 찍는데 쓰는 명령어의 길이가 상대적으로 길다. 물론 sysout을 치고 자동완성을 하면 딱히 길다고 느껴지진 않다. 또한 prinf를 사용하면 %타입 형식으로 변수의 값을 출력할 수 있다.
System.out.println("Hello World!");
System.out.printf("Hello World! %d", name);
  1. 입력받기
    입력을 받는 법은 java.util.Scanner를 import해주고 Scanner 객체를 사용해주면 된다.
    import란 패키지에 내장되어있는 기능을 가져오는 것으로 간단하게 말해 기본적으로 제공해주는 툴을 활용하는거라 보면 된다. Scanner 객체는 값을 입력받을 수 있게 해주는 기능이 있다.
Scanner s = new Scanner(System.in);

이제 s라는 인스턴스를 활용하여 숫자, 문자 등 다양한 값을 입력받을 수 있다.

String name = s.next();

이런 식으로 입력받은 값을 name에 저장한다.
다른 방법으로는 BufferedReader를 사용하는 것이 있다. 이번엔 java.util.BufferedReader를 import해준다

BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String name = br.readLine();

Scanner보다 BufferedReader가 더 길고 복잡해 보이는데 사용할 필요가 없다 느껴질 수 있지만 그 반대다.
BufferedReader가 효율성이 버퍼링된 입력을 사용하므로 대량의 데이터를 읽을 때 더 효율적이기 때문에 오히려 Scanner를 사용할 필요가 없게 된다.

  1. if문, for문, whlle문, switch_case문
    해당 문법들은 전부 자바스크립트에서 한번씩 다뤄보았기 때문에 한꺼번에 묶어서 활용법정도만 익혀도 될거 같다.
		while (bool) {
			System.out.print("이름 : ");
			String name = br.readLine();
			System.out.print("국어 : ");
			int kor = Integer.parseInt(br.readLine());
			System.out.print("영어 : ");
			int eng = Integer.parseInt(br.readLine());
			System.out.print("수학 : ");
			int math = Integer.parseInt(br.readLine());

			int total = kor + eng + math;
			double avg = total / 3.0;
			char grade;
			if (avg >= 90) {
				grade = 'A';
			} else if (avg >= 80) {
				grade = 'B';
			} else if (avg >= 70) {
				grade = 'C';
			} else if (avg >= 60) {
				grade = 'D';
			} else {
				grade = 'F';
			}
            			System.out.printf("%s, 국어(%d), 영어(%d), 수학(%d), 총점(%d), 평균(%.2f), 등급(%c)", name, kor, eng, math, total, avg,
					grade);
			System.out.println();
			System.out.println("종료하려면 X를 입력");
			String x = br.readLine();
			if (x.equals("x")) {
				break;
			}

BufferedReader와 whlie문과 if문을 총정리하는 좋은 예제같아서 가져와봤다. 이름, 국어, 영어, 수학을 입력받고 if문을 통해 등급을 분류하고 반복문을 끝낼 시 x를 입력하여 while문을 빠져나가는 것이다. 다음은 switch case와 for문을 이용하여 해당 예제를 변경해보았다.

		for (int i = 0; i < 10; i++) {
			System.out.print("이름 : ");
			String name = br.readLine();
			System.out.print("국어 : ");
			int kor = Integer.parseInt(br.readLine());
			System.out.print("영어 : ");
			int eng = Integer.parseInt(br.readLine());
			System.out.print("수학 : ");
			int math = Integer.parseInt(br.readLine());

			int total = kor + eng + math;
			double avg = total / 3.0;
			char grade;
            switch((int) avg / 10){
            case '9':
            grade = 'A';
            break;
            }
            case '8':
            grade = 'A';
            break;
            }
            case '7':
            grade = 'A';
            break;
            }
            defalut:
            grade = 'A';
            break;
            }
            			System.out.printf("%s, 국어(%d), 영어(%d), 수학(%d), 총점(%d), 평균(%.2f), 등급(%c)", name, kor, eng, math, total, avg,
					grade);
			System.out.println();
			System.out.println("종료하려면 X를 입력");
			String x = br.readLine();
			if (x.equals("x")) {
				break;
			}

다만 여기서는 for문을 활용하기 때문에 학생 수를 10명으로 지정해주었다.
여기서 for문의 i의 루프값을 입력받아서 반복문을 몇번 실행할지 사용자가 임의로 정하게 할 수도 있다.

  1. 배열
    배열(Array)은 동일한 데이터 타입의 요소들을 순차적으로 저장하는 자료 구조이다. 자바에서 배열은 고정된 크기를 가지며, 한 번 생성되면 크기를 변경할 수 없다. 배열은 고정된 크기를 가지며 동일한 데이터 타입으로 구성되어 한다. 인덱스는 배열의 순서를 나타내며 length 속성을 통해 배열의 길이를 나타낼 수 있다. 다음은 배열의 특징을 설명하는 예제다.
int[] arr = new int[]{11,22,33};	//배열 정의
System.out.println(arr[0]);		//인덱스를 통해 배열 조회
System.out.println(arr[1]);
System.out.println(arr[2]);
for (int i = 0; i < arr.length; i++) {
//length를 통해 배열의 크기만큼 반복
	System.out.println(arr[i]);
}

2차원 배열은 각 요소가 배열인 배열을 말한다. 행과 열로 나누어지며 각 행은 서로 다른 길이를 가질 수 있다. 2차원 배열은 행렬이나 표같은 데이터 구조를 표현할 수 있다.

int[][] matrix = {
    {1, 2, 3},
    {4, 5, 6},
    {7, 8, 9}
};
for (int i = 0; i < matrix.length; i++) {
    for (int j = 0; j < matrix[i].length; j++) {
        System.out.print(matrix[i][j] + " ");
    }
    System.out.println(); // 행이 끝나면 줄바꿈
}
  1. 객체

객체(Object)는 데이터와 해당 데이터를 처리하는 메서드의 집합을 포함하는 소프트웨어 모델이다. 객체는 현실 세계의 개념이나 개체를 모델링하는 데 사용된다.

자바와 같은 객체지향 프로그래밍 언어에서 객체는 클래스(Class)의 인스턴스이다. 클래스는 객체의 속성(attribute)을 정의하고 그것들을 다루기 위한 메서드(method)를 제공한다. 객체는 클래스로부터 생성될 때 클래스에 정의된 속성을 가지고 있고, 클래스에서 정의된 메서드를 사용하여 작업을 수행할 수 있다.

// Car 클래스 정의
class Car {
    String color;
    int speed;
    
    void accelerate() {
        speed += 10;
    }
}

// Car 클래스의 객체 생성
Car myCar = new Car();
myCar.color = "Red";
myCar.speed = 60;
myCar.accelerate(); // 메서드 호출

위의 코드에서 myCar는 Car 클래스의 객체이며, color와 speed는 객체의 속성이고, accelerate()는 객체의 메서드이다.
객체지향 프로그래밍에서는 객체를 사용하여 코드를 모듈화하고 재사용 가능한 구성 요소로 만들어 복잡성을 관리하고 유지보수성을 높인다. 객체는 속성과 행위를 캡슐화하여 개발자가 관련된 코드를 한 곳에 그룹화할 수 있도록 도와준다.

또한 인스턴스가 생성됨과 동시에 초기화 해줄 수 있다.
대신 이 때는 생성자라는 게 필요하다. 생성자를 정의할 때는 클래스의 이름과 동일하게 설정해줘야 하며, 매개변수의 개수에 따라 여러 종류의 생성자를 정의할 수 있다. 이것을 생성자 오버로딩이라고 한다.

class Car {
    String color;
    int speed;
    
    // 생성자 정의
    public Car(String c, int s) {
        color = c;
        speed = s;
    }
}

// 객체 생성과 동시에 생성자 호출
Car myCar = new Car("Red", 60);
  1. 메소드
    메소드(Method)는 객체 지향 프로그래밍에서 특정 작업을 수행하기 위한 코드 블록이다. 메소드는 클래스 내에 정의되며, 클래스의 행동을 정의하고 객체 간의 상호 작용을 구현하는 데 사용된다.

메소드는 일련의 명령문을 그룹화하고 이를 단일 단위로 실행할 수 있도록 한다. 메소드는 호출될 때마다 정의된 작업을 수행하고, 필요한 경우 값을 반환할 수 있다.

메소드는 다음과 같은 구성 요소로 이루어진다.

메소드 시그니처(Method Signature): 메소드의 이름과 매개변수 목록으로 구성된다. 매개변수 목록은 메소드에 전달되는 값의 타입과 이름을 지정한다.

메소드 본문(Method Body): 중괄호 {} 내에 있는 명령문으로, 메소드가 실행될 때 수행되는 작업을 정의한다.

예를 들어, 다음은 "add"라는 메소드의 예시이다.

public int add(int a, int b) { // 메소드 시그니처
    return a + b; // 메소드 본문
}

또한 전에 배웠던 클래스에서 속성과 같이 메소드를 넣어서 사용할 수 있다.

public class Calculator {
    public int add(int a, int b) {
        return a + b;
    }
}

public class Main {
    public static void main(String[] args) {
        Calculator calc = new Calculator(); // Calculator 클래스의 객체 생성
        int result = calc.add(3, 5); // add 메소드 호출
        System.out.println("Result: " + result);
    }
}
  1. Math 클래스
    Math 클래스는 자바에서 수학적인 연산을 수행하는 데 사용되는 유틸리티 클래스이다. 이 클래스는 모든 메소드와 필드가 정적(static)이므로 객체를 생성하지 않고 직접 접근할 수 있다.

Math 클래스의 주요 기능은 다음과 같다:

수학적인 상수: π(원주율), e(자연로그의 밑)와 같은 수학적인 상수를 제공한다.

기본 수학 연산: 산술 연산(덧셈, 뺄셈, 곱셈, 나눗셈), 지수 계산, 제곱근 계산, 로그 계산 등의 기본 수학 연산을 제공한다.

삼각 함수: 삼각 함수(sin, cos, tan)와 역삼각 함수(asin, acos, atan)를 제공하여 삼각형의 각도 계산을 지원한다.

랜덤 값 생성: 난수를 생성하기 위한 메소드를 제공한다.

예를 들어, Math 클래스를 사용하여 원주율 값을 가져오거나 삼각 함수를 계산할 수 있다.

double pi = Math.PI; // 원주율 상수 가져오기

double angle = 45; // 각도
double sineValue = Math.sin(Math.toRadians(angle)); // 사인 값 계산
double cosineValue = Math.cos(Math.toRadians(angle)); // 코사인 값 계산
double tangentValue = Math.tan(Math.toRadians(angle)); // 탄젠트 값 계산

Math 클래스는 자주 사용되는 수학 연산을 제공하여 자바 프로그래밍에서 수학적인 계산을 쉽게 할 수 있도록 도와준다.

  1. interface
    인터페이스는 자바 프로그래밍에서 일종의 "계약"이나 "규약"으로 볼 수 있다. 이를 통해 클래스가 특정한 메서드들을 반드시 구현하도록 강제할 수 있다. 인터페이스는 다음과 같은 특징을 가진다

추상 메서드 선언: 인터페이스는 메서드의 명세(선언)만을 포함하며, 메서드의 구현은 제공하지 않는다. 즉, 모든 메서드는 추상 메서드이다.

Copy code
interface MyInterface {
    void myMethod(); // 추상 메서드 선언
}

상수 선언: 인터페이스는 상수를 선언할 수 있다. 선언된 상수는 자동으로 public static final로 간주된다.

Copy code
interface MyInterface {
    int MY_CONSTANT = 10; // 상수 선언
}

다중 상속 지원: 자바에서는 클래스는 단일 상속만을 지원하지만, 인터페이스는 다중 상속을 지원한다. 즉, 하나의 클래스가 여러 개의 인터페이스를 구현할 수 있다.

Copy code
interface Interface1 {
    // 메서드 선언
}

interface Interface2 {
    // 메서드 선언
}

class MyClass implements Interface1, Interface2 {
    // Interface1과 Interface2를 모두 구현한 MyClass 클래스
}

인터페이스는 클래스의 계층 구조를 유연하게 만들어주고, 코드의 재사용성을 높여준다. 특히 다중 상속을 허용하는 인터페이스는 다양한 기능을 조합하여 클래스를 설계하는 데 유용하다.

  1. 마침
    백엔드 서버의 기초가 되는 언어다보니 이론적인 부분이 상당히 길다. 글이 너무 길어져서 일단은 한번 끊고 다음 글에서 이어서 쓰도록 해야겠다.

0개의 댓글