[새싹 x 코딩온] 웹 풀스택 영등포 5기 19주차 회고 - 2

용가리🐉·2023년 12월 11일
0
post-thumbnail

📌 표준 배열

📣 배열

  • 같은 타입의 여러 변수를 하나의 묶음으로 다루는 것
  • 처음 선언한 배열의 크기는 변경 불가 → 정적 할당
// 배열 선언
int[] intArray;
char[] charArray;

// 배열 생성
int[] intArray = new int[10];
char[] charArray = new char[20];

// 배열 초기화
int[] intArray = { 1, 2, 3, 4, 5 }

📣 배열 출력

  • for문 활용
for(int i=0; i < intArray.length; i++) {
	System.out.print(intArray[i] + " ");
}
  • Arrays 클래스의 toString 메소드 활용
    • Arrays 클래스는 배열을 다루기 위한 다양한 메소드가 포함됨
 import java.util.Arrays;
 ...
 System.out.println(Arrays.toString(intArray));
  • for-each 문
    • 배열의 각 원소에 순차적으로 접근하는데 유용한 for문
for(int value: intArray) {
	System.out.println(value + " ");
}

📣 2차원 배열

int[][] intArray;
char[][] charArray;
double[][] doubleArray;

int[][] intArray = new int[2][5];
char[][] charArray = new char[5][5];
double[][] doubleArray = new double[5][2];

int intArray[][] = {{0,1,2}, {3,4,5}, {6,7,8}};
char charArray[][] = {{'a','b','c'},{'d','e','f'}};
double doubleArray[][] = {{0.01, 0.02}, {0.03, 0.04}}

📣 Arrays 메소드

  • copyOf(arr, copyArrayLength) : 배열 전체를 복사해 복사할 길이만큼 지정하여 복사한 새로운 배열로 변환
  • copyOfRange(arr, sIdx, eIdx) : 배열 시작 인덱스와 끝 인덱스를 지정하여 복사한 새로운 배열 반환
  • fill(arr, n) : 배열의 모든 요소를 동일한 값으로 채워주는 함수
  • toString(arr) : 배열을 문자열로 변환하여 반환
  • sort(arr) : 배열 내의 요소들을 오름차순으로 정렬(원본 배열 순서 변경)
  • equals(arr1, arr2) : 두 배열의 각각의 요소 값이 동일한지 비교하여 True/False 반환
  • deepEquals(arr1, arr2) : 단일 차원 또는 다차원 배열인 두 배열이 같은지 비교하여 True/False 반환
  • binarySearch(arr, idx) : 배열의 특정 인덱스 요소값을 이진 검색 알고리즘을 사용하여 검색한 후, 해당 위치 반환
    • 이진 검색 알고리즘 사용 → 매개변수로 전달되는 배열이 sort() 등을 사용하여 미리 정렬되어 있어야만 제대로 동작

📌 ArrayList

📣 ArrayList 클래스

  • 표준 배열보다 조금 느릴 수 있지만, 배열에서 많은 조작이 필요할 때 유용하게 사용되는 클래스
  • 크기를 미리 정하지 않아도 되는 배열 → 동적 할당
import java.util.ArrayList;
...
ArrayList<Integer> arrayList1 = new ArrayList<>();
ArrayList<String> arrayList2 = new ArrayList<>();
ArrayList<Double> arrayList3 = new ArrayList<>();

📣 ArrayList 메소드

  • add(element) : ArrayList 맨 뒤에 element 추가
  • add(idx, element) : 인덱스 위치에 element 삽입
  • addAll(ArrayList) : ArrayList 뒤에 ArrayList 추가
  • size() : ArrayList의 길이 리턴
  • get(idx) : 인덱스에 해당하는 요소 리턴
  • indexOf(params) : params와 같은 첫 번째 요소의 인덱스 리턴, 없으면 -1 리턴
  • remove(idx) : 인덱스의 요소 삭제
  • clear() : 모든 요소 삭제

📌 예외 처리

  • 컴파일 오류와 다름
    • 컴파일 오류는 문법에 맞지 않게 작성된 코드가 있을 때 발생
    • 컴파일 시 발견되기 때문에 코드가 실행조차 되지 않음
  • 예외 : 프로그램 실행 중에 의도치 않는 결과가 나오는 것 → 예외 처리는 예외를 처리하고 방지하는 것

📣 예외가 발생하는 경우

  • 숫자를 0으로 나누는 경우 → ArithmeticException
  • 배열의 인덱스 범위를 벗어나는 경우 → ArrayIndexOutOfBoundsException
  • 정수를 입력받도록 작성한 코드에 문자열을 입력한 경우 → InputMismatchException
    • import 필요
    • import java.util.InputMismatchException
  • 참조 변수가 null인 상태에서 필드나 메소드에 접근한 경우 → NullPointerException

📣 try-catch-finally

try {
	// 예외가 발생할 가능성이 있는 실행문(try 블록)
}
catch (처리할 예외 타입 선언) {
	// 예외 처리문 (catch 블록)
}
finally {
	// 예외 발생 여부와 상관없이 무조건 실행되는 문장 (finally 블록)
    // (finally 블록은 생략 가능)
}

try {
	int num1 = 4;
    int num2 = 0;
    System.out.println(num1 + " / " + num2 + " = " + (num1/num2));
}
catch (ArithmeticException e) {
	System.out.println("0으로 나누어 예외가 발생했습니다.");
}

System.out.println("여기까지 읽힐까?");

📌 객체지향 프로그래밍 (OOP)

필요한 데이터와 코드를 묶어 하나의 객체로 만들고 이 객체들 간에 상호작용을 하도록 프로그램을 만드는 방식 → OOP (Object Oriented Programming)

  • ex. 부품(객체)를 만들고, 부품(객체)를 조립해서 하나의 완성품(프로그램)을 만듦

📣 객체란? (Object)

물리적으로 존재하거나 개념적인 것 중에서 다른 것과 식별 가능한 것

  • ex. 학생, 자동자, 학과 등
  • 속성 (필드, field)동작(메소드, method)으로 구성
    • ex. 학생 객체 - 속성 : 이름, 나이 / 동작 : 공부하다, 시험보다

📣 상호작용

  • 객체는 다른 객체와 상호작용
  • 객체의 동작인 메소드(method)를 이용해 서로 상호작용 함
    → 상호작용 : 데이터를 주고 받는 것
  • 상호작용 방법
    • '메소드명 (매개변수1, 매개변수2, ...)'와 같이 메소드를 호출함으로써 다른 객체에게 정보를 넘겨줌

📣 특징

  • 캡슐화(Encapsulation) : 객체의 필드와 메소드를 묶고, 내용을 외부에 감추는 것
  • 상속(Inheritance) : 부모 객체의 필드/메소드를 자식 객체에게 물려주는 것
  • 다형성(Polymorphism) : 사용 방법은 동일하지만, 결과가 다양하게 나오는 것

🟠 장점

  • 코드 재사용에 용이
  • 유지보수 용이
  • 대형 프로젝트에 적합

🟠 단점

  • 처리 속도가 느림
  • 설계 복잡
  • 많은 시간 투자 필요

절차지향 프로그래밍

  • ex. C언어
  • 장점
    • 실행 속도가 빠름 → 코드가 기술 순서대로 실행되어 컴퓨터 처리 구조와 비슷하기 때문
  • 단점
    • 프로그램이 커진다면 유지보수 어려움
    • 순서가 바뀌면 결과 도출의 어려움
    • 대형 프로젝트에 적합하지 않음

📌 클래스

사용자가 정의하는 자료형이라 생각하면 쉬움!

  • 실수형 변수를 선언 → float 자료형 사용
  • 정수형 변수 선언 → int 자료형 사용
  • ex. 자동차 정보를 저장하는 변수 선언 시, 사용자가 클래스를 만들어서 새로운 자료형을 정의해야 함

📣 객체와 클래스

  • 소프트웨어 개발(현실 세계)에서 자동차 객체를 만든다고 가정
    • 클래스(설계도)를 바탕으로 자동차 객체(실제)를 하나하나 생성!
  • 인스턴스화 : 클래스로부터 객체를 만듦
  • 인스턴스(Instance) : 클래스로부터 만들어진 객체
    → 클래스로부터 여러 개의 인스턴스를 만들 수 있음

📣 클래스 선언과 객체 생성

  • new 키워드 이용
// 클래스 선언
public class 클래스명 { ... }

// 객체 생성
// new 연산자 : 객체의 주소 리턴
클래스명 변수 = new 클래스명();

public class Main {
	public static void main(String[] args) {
    	ClassName test = new ClassName();
    }
}
  • Main 클래스에서 test라는 객체를 생성함
  • test는 ClassName 클래스의 인스턴스!

📣 클래스의 구조

// 공개 클래스 선언
// 클래스명은 첫 글자가 대문자인 CamelCase 
public class ClassName {
	// 필드(변수)
	public int number;
    public String name;
    
    // 메소드 - 생성자
    public ClassName(){
    }
    
    // 메소드
    public String getName() {
    	return name;
    }
}

공개 클래스란?

  • 어느 위치에 있든지 패키지와 상관없이 사용 가능한 클래스
  • 필드(변수) : 클래스 내에서 값을 저장하는 변수
  • 메소드
    • 객체 동작으로 호출 시 실행하는 블록
    • 객체 내부의 함수
  • 생성자
    • 클래스 이름과 동일한 이름을 갖는 특별한 종류의 메소드
    • 객체가 생성될 때 자동으로 호출되는 메소드
    • 객체의 초기화 담당

📣 필드

🟠 선언

  • 클래스 블록에서 선언되어야 필드 선언이 됨
  • 필드의 초기값을 할당하지 않으면 자동으로 기본 값으로 초기화
// 필드 선언
자료형 필드명 [= 초기값];

🟠 사용

  • 필드는 객체 내부 데이터이므로 객체가 존재해야 필드 사용 가능
  • 클래스로부터 객체를 생성한 후 필드에 접근 가능
  • 필드가 속한 클래스 내부에서는 필드명 그래도 사용
  • 외부 객체에서는 참조 변수와 dot(.) 연산자를 이용해 필드 사용
int name; // 필드 선언
name = '아이오닉 6'; // 필드 사용

// 외부 객체
Car c1 = new Car(); // 객체 생성 후
c1.name = "아이오닉6"; // dot 연산자를 이용해 필드 접근

📣 메소드 기본 구조

  • 메소드 형태
public void test() {
	System.out.print("test 메소드");
}
  • 생성자
    • 생성자의 이름은 클래스 이름과 같아야 함
    • 생성자는 리턴 타입을 적지 않음
    • 접근제한자가 public 인 경우만 호출됨
public class ClassName {
	public ClassName(){} // 생성자
}

📌 접근 제어자

📣 패키지 (package)

  • 관련있는 클래스 파일을 저장하는 공간
  • 디렉터리의 역할 뿐만 아니라 클래스의 일부분으로 클래스를 식별하는 공간

🟠 선언

  • 항상 소스파일의 최산단에 위치해야 함
  • 소문자로만 작성하는 것이 관례
package 상위패키지.하위패키지;

public class 클래스명 { ... }
  • 같은 패키지에 있는 클래스
    • 아무 조건 없이 사용 가능
  • 다른 패키지에 있는 클래스
    • import 문으로 어떤 패키지의 클래스인지 명시
    • 특정 패키지에서 다수의 클래스를 사용한다면? → import.패키지.*;

📣 접근 제어자 (Access Modifier)

  • 접근 제어자의 목적

    • 클래스나 일부 멤버(필드, 메소드)를 외부에서의 접근을 제한하는 것
    • 중요한 필드와 메서드가 외부로 노출되지 않도록 하기 위함
  • 종류

    • public

      • 패키지에 관계 없이 모든 클래스에서 접근 가능
    • protected

      • 같은 패키지 내의 모든 클래스에서 접근 가능 (다른 패키지에서 접근 불가)
      • 단, 다른 패키지에 있더라도 상속 받은 서브클래스에서는 접근 가능
    • default → 접근 제한자가 붙지 않은 상태

      • 같은 패키지 내의 모든 클래스에서 접근 가능 (다른 패키지에서 접근 불가)
    • private
      - 같은 클래스에서만 접근 가능

🟠 클래스의 접근 제한

  • public 생략하면, default 접근 제한
    • 같은 패키지에서는 제한 없음
    • 다른 패키지에서는 사용 불가
  • public 접근 제한
    • 같은 패키지에서는 제한 없음
    • 다른 패키지에서도 제한 없음

🟠 필드와 메소드의 접근 제한

  • 필드와 메소드는 어떤 접근 제한자를 갖느냐에 따라 호출 가능 여부가 결정됨

📣 getter와 setter

  • 클래스에서 필드(변수)는 private로 지정하는 것이 일반적 → 외부에서 마음대로 데이터를 변경한다면 무결성이 깨짐
    • ex. 학생의 시험 점수는 음수가 될 수 없는데, 외부에서 음수로 변경한다면?
  • private로 선언하면 다른 클래스에서 접근하지 못하는 것이 아닌가?
    간접적으로 필드에 접근할 수 있도록 public 메소드 제공
    → 이것을 getter / setter 라고 함
    → 객체지향 프로그래밍에서는 데이터의 직접적인 변경을 막고, 메소드를 통해 필드에 접근하는 것을 선호

getter : 필드 값을 가져올 때
setter : 필드 값을 설정할 때

🟠 형태

public class Person {
	private int age;
    private String name;
    
    public Person(String name) {
    	this.name = name;
    }
    
    // getter
    public int getAge() {
    	return age;
    }
    
    // setter
    public void setAge(int age) {
    	this.age = age;
    }
    
    // getter
    public int getName() {
    	return name;
    }
    
    // setter
    public void setName(String name) {
    	this.name = name;
    }
}

🟠 사용

Person codee = new Person("코디");
codee.setAge(1);
System.out.println(codee.getName());

📌 static

📣 static 멤버(변수, 메소드)

  • 객체마다 생성되는 것이 아니고, 클래스 당 하나만 생성
  • 클래스가 생성되는 순간에 메모리를 할당 받음
    객체를 생성하지 않아도 static 멤버에 접근 가능
  • 동일한 클래스의 모든 인스턴스에 공유됨 (같은 메모리 공간 공유)
  • non-static의 경우, 객체가 생성될 때마다 멤버 공간을 새로 만듦 → 메모리 공간이 공유되지 않음
public class SomeClass {
	// 정적 필드
    static 타입 필드명 [= 초기값];
    
    // 정적 메소드
    static 리턴타입 메소드명 (매개변수1, 매개변수2, ...) { ... }
}

📣 static의 활용

  • 보통 static 변수공유의 목적으로 많이 사용됨
  • static 메소드유틸리티성 메소드를 작성할 때 많이 사용됨
    • ex. 오늘의 날짜 구하기, 숫자에 콤마 추가하기 등등...
    • ex. java.lang 패키지의 Math 클래스

📣 static의 제약

  • static 메소드에서 non-static 멤버에 접근할 수 없음
    • 객체가 생성되지 않은 상태에서 non-static 멤버는 만들어져 있지 않기 때문에
  • 반대로, non-static 메소드에서 static 멤버에 접근할 수 있음
  • static 메소드에서는 this 키워드 사용 불가

📌 final

📣 final 필드 선언

  • 인스턴스 필드, 정적 필드는 언제든지 값 변경이 가능했음
  • 값 변경을 막고 읽기만 허용하고 싶을 때에는 final 키워드 사용
final 타입 필드 [=초기값];
  • final 필드
    • 한 번만 초기화 할 수 있으며 초기화된 값이 최종 값 (변경 불가능)
  • final 필드 초기값 대입 방법
    • 필드 선언 시 초기화 : 간단
    • 생성자에서 초기화 : 객체 생성 시 외부에서 전달하는 값으로 초기화 해야 할 때 사용

📣 상수 선언

  • 상수(constant) : 변하지 않는 값
  • 상수는 객체마다 저장할 필요가 없고, 단 한 번만 값이 선언되면 되기 때문에 static이면서 final인 특성을 가지므로 다음과 같이 선언함
static final 타입 상수 [=초기값];
  • 대문자로 작성하는 것이 관례
  • 여러 단어를 사용해야 한다면, 언더스코어(_)를 이용해 연결
static final double PI = 3.141592;
static final String HELLO_WORLD = "Hello, World!";

📌 클래스의 상속 (Inheritance)

부모 클래스에서 정의된 필드와 메소드를 자식 클래스가 물려받는 것

  • 프로그래밍에서는 자식 클래스가 어떤 부모로부터 상속받을 것인지 선택
  • Java는 다중 상속 허용 X → 단 하나만 상속 가능
  • 장점
    - 멤버의 중복 작성 제거
    - 클래스 수정 최소화
    - 클래스의 계층적 분류 가능
    - 클래스의 재사용, 확장성 용이

📣 예시

  • 아래와 같이 직업 별로 클래스를 정의했을 때, '말하기, 먹기, 걷기, 잠자기'의 행동은 모든 직업에 동일하게 정의됨
  • 계층화하면, 아래와 사진과 같이 표현 가능함
    • Person 이라는 부모 클래스를 만들고, Student, Researcher, ... 클래스에서 상속받도록 하는 것
  • 슈퍼(부모) 클래스 : Person
  • 서브(자식) 클래스 : Student, Researcher, ...

📣 문법

  • extends 키워드 사용
  • 다중 상속을 허용하지 않으므로 extends 뒤에는 부모 클래스 하나만!
public class Person {
	...
}

public class Researcher extends Person { // Person을 상속받는 Researcher 선언
	...
}

public class Professor extends Researcher { // Researcher를 상속받는 Professor 선언
	...
}

public class Student extends Person { // Person을 상속받는 Student 선언
	...
}

📣 예제

public class Person {
	private int age;
    private String name;
    
    public int getAge() {
    	return age;
    }
    
    public void setAge(int age) {
    	this.age = age;
    }
    
    public int getName() {
    	return name;
    }
    
    public void setName(String name) {
    	this.name = name;
    }
}

public class Student extends Person {
	private String school;
    
    public Student(int age, String name) {
    	// 상속으로 부모 클래스의 멤버에 접근 가능!
    	setAge(age);
        setName(name);
    }
    
    public String getSchool() {
    	return school;
    }
    
    public void setSchool(String schoool) {
    	this.school= school;
    }
}

Student stu = new Student(20, "새싹");
stu.setSchool("새싹 대학교");

📣 부모 생성자 호출

  • 자식 객체를 생성하면 부모 객체가 먼저 생성됨!
    • 부모 객체가 먼저 생성된 후, 자식 객체인 Student가 생성된 것 → 부모인 Person 객체를 생성하지 않았는데, 가능한 이유..?

🟠 super()

  • 모든 객체는 생성자를 호출해야만 생성됨 → 비밀스럽게 부모 생성자가 실행된 것!
    • 자식 생성자의 맨 첫 줄에 super()가 숨겨져 있음
    • super()가 컴파일 과정에서 자동으로 추가되면서 부모의 기본 생성자를 호출함!
    • 만약, 부모 클래스에 기본 생성자가 아닌 매개변수를 갖는 생성자만 있다면, super()에 매개변수를 넣어줘야 함
// 자식 클래스의 생성자
public Student(...) {
	super();
    // 또는
    super(매개변수1, ... );
    // ...
}

🟠 예제

  • 부모클래스(슈퍼클래스)의 생성자가 매개변수를 필요로 할 경우
  • 즉, 부모 클래스의 생성자를 호출해야 한다면?
public class Person {
	private int age;
    private String name;
    
    public Person(String name) {
    	setName(name);
    }
    
    ...
    
    public void setName(String name) {
    	this.name = name;
    }
}

public class Student extends Person {
	private String school;
    
    public Student(int age, String name) {
    	super(name) // 서브 클래스 첫 줄에서 super() 사용
        setAge(age);
    }
    
    ...
}

📣 메소드 오버라이딩 (Overriding)

슈퍼 클래스의 메소드서브 클래스에서 재정의하는 것!

  • 상황에 따라 부모 클래스의 메소드를 자식 클래스가 사용하기에 적합하지 않을 수도 있기 때문에
  • 메소드의 이름, 매개변수 타입 및 개수, 리턴 타입 등 모든 것을 동일하게 작성
  • @Override
    • 컴파일 시 정확히 오버라이딩 되었는지 확인하는 어노테이션으로 생략 가능

      // Person 클래스
      public void printName(){
      	System.out.println("익명");
      }
      
      // Student 클래스
      @Override
      public void printName(){
      	System.out.println(getName());
      }

오버로딩 VS 오버라이딩

  • 오버로딩은 동일한 함수명에 매개변수의 차이를 두어 알아서 알맞는 함수를 찾아가도록 하는 것
  • 오버라이딩은 이미 정의된 함수의 내부 코드를 수정하여 재정의하는 것

📌 추상 클래스와 추상 메소드

📣 추상 클래스

추상 : 실체 간의 공통되는 특성

하나 이상의 추상 메소드(선언만 있고, 구현되지 않은 메소드)를 포함하는 클래스

  • 상속 관계에서 부모 클래스 역할을 하며, 추상 메소드와 일반 메소드를 가질 수 있음
  • 서브 클래스에서 반드시 구현되어야 함
  • 객체의 공통적인 특징을 추상화해서 정의하고, 이를 상속하는 서브 클래스에서 구현
    • 실체 클래스는 추상 클래스를 상속해서 공통적인 필드나 메소드를 물려받음
  • 추상 클래스는 new 연산자를 통해 인스턴스 객체를 만들 수 없음
  • 추상 클래스를 상속받는 서브 클래스에서 추상 메소드를 오버라이딩 해줘야 함!

🟠 용도

  • 설계와 구현 분리
  • 슈퍼 클래스에서는 개념 정의
    • 서브클래스마다 다른 구현이 필요한 메소드는 추상 메소드로 선언
  • 서브 클래스에서는 구체적 행위 구현
    • 서브클래스마다 목적에 맞게 추상 메소드를 다르게 구현
  • 추상 클래스는 new 연산자 사용해 객체 직접 생성 불가능!
  • 새로운 클래스를 만들기 위한 부모 클래스로만 사용되므로 extends 뒤에만 올 수 있음
Shape shape = new Shape(); // 불가능!

🟠 구현

  • abstract 키워드 사용
public abstract class Person {
	private int age;
    private String name;
    ...
    
    abstract public void printName();
}

// Student Class
public void printName() {
	System.out.println("학생" + getName());
}

📌 인터페이스

인터페이스(interface) 사전적 의미

  • 두 장치를 연결하는 접속기
    → 인터페이스는 두 객체를 연결하는 역할을 함!

추상 메소드의 모음 → 여러 구현체에서 공통적인 부분을 추상화하는 역할

  • 서브 클래스가 같은 동작을 한다는 것을 보장하기 위해 사용
  • 상속과 달리 하나의 클래스가 두 개 이상의 인터페이스를 동시에 구현할 수 있음

추상 클래스와 다른 점

  • 추상 클래스는 추상 메소드가 없어도 상관 X
  • 인터페이스에는 추상 메소드가 무조건 있어야 함
  • 메소드 구현 X, 추상 메소드만 존재

📣 문법

  • 인터페이스에서 정의하는 모든 필드public static final이 자동 적용 → public한 상수
  • 인터페이스를 구현하는 클래스는 인터페이스의 모든 추상 메소드를 반드시 구현해야 함
  • 인터페이스 선언 시, class 키워드 대신 interface 키워드 사용
  • 인터페이스 구현 시, extends 키워드 대신 implements 키워드 사용
interface 인터페이스명 { ... } // default 접근 제한
public interface 인터페이스명 { ... } // public 접근 제한

🟠 예시

// 인터페이스 선언
public interface Phone {
	public final String CATEGORY = "phone"; // public final 생략 가능
    public abstract void sendCall(); // public abstract 생략 가능
    public abstract void receiveCall(); 
    public abstract void sendMessage(); 
    public abstract void receiveMessage(); 
}

// 인터페이스 구현
public class Samsung implements Phone {
	public boolean silence = false;
    
    @Override // 부모 클래스에 있는 메서드를 Override 했다는 것을 명시적으로 선언 (주석과 비슷)
    public abstract void sendCall() {
    	if(!silence) System.out.println("뚜루루 뚜루루");
    };
    @Override
    public abstract void receiveCall() {
    	if(!silence) System.out.println("전화 받아");
    }; 
    @Override
    public abstract void sendMessage() {
    	if(!silence) System.out.println("슉");
    }; 
    @Override
    public abstract void receiveMessage() {
    	if(!silence) System.out.println("문자 왔숑");
    }; 
}
profile
자아를 찾아 떠나는 중,,,

0개의 댓글

관련 채용 정보