[DEV] study&learn
article thumbnail
Published 2022. 11. 18. 17:51
[TIL 항해 12일 차] JAVA 카테고리 없음

 

소인은 시작은 있으되 끝이 없다. 
- 진서(晋書) 

 

1. Java 기본

변수(variable) - 변할 수 있는 값을 저장하는 곳

  • 하나의 변수는 단 하나의 값만 저장할 수 있다.
  • 변수에 저장된 값은 재할당을 통해 변경될 수 있다.
  • java에서의 변수는 값의 형태에 맞는 자료형을 지정해주어야 한다.
  • 소문자로 시작해야하며, 숫자로 시작할 수 없다.
  • 대소문자를 구분하며, 공백이 포함될수 없다.
  • 변수 안에서 단어 간의 구분은 카멜 케이스를 주로 이용한다. ( myName )

상수(constant, final variable) - 불변 값을 저장하는 곳

  • final 키워드를 자료형 앞에 붙여서 선언한다.
  • 한 번 값이 할당 된 상수는 다른 값으로 재할당 할 수 없다.

자료형(data type)

  • 기본형
    1. int
      • 타입 : 정수형
      • 크기 : 4 바이트
    2. double
      • 타입 : 실수형
      • 크기 : 8.바이트
    3.  boolean
      • 타입 : 논리형
      • 크기 : 1 바이트
  • 참조형 - 기본형을 제외한 모든 자료형은 참조형에 해당한다. 참조형의 가장 큰 특징은 값 자체가 변수에 저장되는 것이 아니라 메모리 어딘가에 위치한 값의 주소를 저장하고 활용한다는 것이다.
    1. String
      • 타입: 문자열
      • 크기: 문자의 갯수에 따라 가변적
    2. Integer
      • 타입 : 정수형
      • 특징
        • int 형과는 다르게 null 값을 할당할 수 있음
        • List나 Map 등의 자료 구조에서 정수형으로 요소를 제한할 때 사용
          예) List<Integer>
        • int 형에서 지원되지 않는 각종 함수 지원

연산자

  • 산술 연산자
  • 비교 연산자 - 수행 결과는 true/false 즉, 참/거짓으로만 결정
  • 논리 연산자 - 수행 결과는 true/false 즉, 참/거짓으로만 결정
    1. && - AND
      결합된 모든 피연산자가 true 여야만 true 반환
    2. || - OR
      결합된 모든 피연산자 중 하만 true 여도 true 반환
  • 대입 연산자

흐름 제어

  • 조건문
    1. if () {---} / if () {---} else {---} / if () {---} else if () {---} else {---}
      • if 뒤에 이어지는 괄호 안에 조건을 넣고 이 조건이 true 면 중괄호 안의 소스를 실행
    2. swich () {---}
  • 반복문
    1. while () {---}
      • 괄호 안의 조건이 true 일 경우 블록 내부의 소스를 실행.
      • 만약 true 에서 false 로 바뀌지 않는다면 무한루프에 빠지게 되어 시스템에 큰 악영향을 미칠 수 있음.
    2. for (초기화; 조건식; 증감식) {---}
      • 조건식이 true 일 경우 블록 내부 코드를 실행.

자료 구조

컴퓨터의 한정된 자원으로 최고의 성능을 내기 위해서는 활용하는 데이터가 잘 구조화 되어 있어야한다.

  • 배열(Array) 
    • 배열은 동일한 자료형의 데이터를 여러 개 담을 수 있는 공간이며, 
      복수의 데이터를 다룰 때에 사용되는 아주 기본적인 형태이다. 
    • 최초 선언 시, 자료형 뒤에 [ ] 를 붙여주면 해당 자료형의 배열을 선언할 수 있다.
    • System.out.println(배열변수) 와 같이 직접 배열 변수를 함수에게 전달하면 우리의 예상과 다른 내용이 출력된다.
      WHY? 이는 기본형 외의 자료형을 담는 변수가 값 자체가 아닌 주소를 가지기 때문이다!!!!!!
    • 배열변수[인덱스] = 값 의 형태로 기존 요소의 값을 덮어쓸 수 있다.
  • 리스트(List)
    • 리스트는 순서를 구분하며 값의 중복을 허용하는 데이터의 모음이다.
    • Vector, ArrayList, LinkedList 등이 있다.
    • ArrayList
      • 기본적으로  Object, 즉 모든 java 객체를 담을 수 있다.
      • 하지만 시스템 안정성을 위해 요소의 자료형을 제한해야할 경우
        ArrayList<Integer> 의 형식으로 제한할 수 있다.
      • add() 함수를 통해 요소를 추가할 수 있다.
      • ArrayList 의 크기, 요소의 갯수를 확인하기 위해서는 size() 함수를 사용한다.
      • 특정 인덱스의 값을 사용하기 위해서는 ArrayList변수.get(인덱스) 와 같이 작성한다.
  • 맵(Map)
    • 맵은 키와 값을 쌍으로 하는 데이터의 모음이다.
    • 순서를 따지지 않는다는 점이 리스트와 구분된다.
    • 키의 중복은 허용하지 않지만 값의 중복은 허용한다.
    • 다양한 구현체가 있으며, HashMap 이라는 활용도가 높은 구현체가 있다.
    • HashMap
      • HashMap 의 요소는 키와 값으로 구성되며, Spring 개발 시 활용되는 JSON 형식의 데이터로 변환시 빈번하게 사용
      • 데이터의 입력은 HashMap변수.put(키, value)
      • 데이터를 불러오기는 HashMap변수.get(키)
      • ArrayList 와 같이 HashMap<String, String> 와 같은 형식으로 변수를 선언하면 입력되는 데이터의 자료형을 제한 할 수 있다.

2. Java 도약

객체지향이란?

객체(Object)라는 단어를 사물에 빗대어 설명해보자.

사물은 일반적으로 속성과 기능을 가지게 되며, 연관성이 있는 사물은 같은 분류로 묶을 수 있다. (묶는 작업 굉장히 중요)

공통적으로 가지고 있는 특성을 묶어 그 관계를 구조화하는 것이 java 코드에서도 적용된다.

 

 

스마트폰을 예를 들어보자

대표적인 제조사 두 곳을 기준으로 나누고,

그 나누어진 분류를 다시 모델에 따라 새로운 분류로 나뉜다.

스마트폰의 구성요소를 속성과 기능으로 나타내면 다음과 같다.

  • 속성 : AP, RAM 용량, 카메라 등
  • 기능 : 통화 하기, 사진 찍기 등

속성은 대체로 정적인 정보를 다루며, 기능은 작업에 대한 수행을 나타낸다.

사물이 가진 속성과 기능이 프로그래밍 세계에서는 각각 멤버변수와 메서드(함수)에 대응되고

우리는 이방식으로 java 생태계에서 사용되는 프로그램을 작성한다.

 

스마트폰이 실제로 만지고 사용할 수 있는 형태로 소비자에게 전달되려면 설계에 맞게 생산한는 과정을 거쳐야한다.

이 때, 설계도 역할을 하는 것이 클래스(Class), 생산된 스마트폰이 인스턴스(Instance)이다.

인스턴스는 번역에 따라 객체, 혹은 개체라고 부르기도한다.

 

클래스와 인스턴스

사물이 가진 속성과 기능을 멤버변수와 매서드로 나타내는 것이 객체지향 구현의 첫 걸음!

어떤 사물의 속성과 기능을 뽑아내어 멤버변수와 메서드로 표현하게 되면 인스턴스를 생성하기 위한 설계도인 클래스가 된다.

 

설계도가 있다고 해서 그 기능을 사용할 수 없듯이 클래스에서 인스턴스를 생성하지 않으면 이를 활용하는 것은 불가능하다.

 

생성자

클래스로부터 인스턴스를 생성하는 방법과 규칙을 익히기 위해 생성자에 대해 알아보자.

 

생성자는 클래스로부터 인스턴스를 생성하는 메서드의 한 종류이다.

클래스 내부에 정의하며, 메서드명이 클래스명과 일치해야한다는 규칙이 있다.

Class Car {
	//멤버변수
    int price;
    int model;
    int year;
    
    //메서드(함수)
    void axel() { } //악셀 기능
    void stop() { } //브레이크 기능
    
    //기본 생성자
    Car() {
    	// 인스턴스 생성시 수행할 명령
        // 인스턴스의 멤버변수 초깃값 설정
    }
}

생성자 내부에는 일반적으로 인스턴스 생성시 수행할 명령과 멤버변수의 초기값을 설정하는 코드를 작성한다.

여기서 인스턴스를 생성시키려면 한가지 작업이 더 필요하다.

Car genesis = new car();

위와 같이 클래스 내부에 정의된 생성자는 반드시 new 연산자와 함께 쓰여야 새로운 인스턴스를 생성할 수 있다.

이렇게 생성된 인스턴스는 서로 다른 변수에 할당된 후 프로그램 내부에서 활용된다.

 

만약 클래스 내부에 생성자가 하나도 정의되어 있지 않다면?

쓸모 없는 클래스가 되는 것일까?

아니다!

java 컴파일러가 위와 같은 경우에 public 클래스명() { } 과 같이 파라미터가 없는 생성자를 자동으로 추가하여 컴파일하며, 이 때 추가되는 생성자를 기본 생성자라고 한다.

만약 파라미터가 있는 생성자를 클래스에 정의하게 되면 기본 생성자가 자동으로 생성되지 않기 때문에 직접 작성해주어야 한다.

 

Class Car {
	//멤버변수
    int price;
    int model;
    int year;
    
    //메서드(함수)
    void axel() { } //악셀 기능
    void stop() { } //브레이크 기능
    
    //기본 생성자
    Car() {
    	// 인스턴스 생성시 수행할 명령
        // 인스턴스의 멤버변수 초깃값 설정
    }
    
    Car(int price, String model) {
    	this.pirce = price;
        this.model = model;
    }
}

파라미터를 활용한 생성자를 보면 this 라는 키워드가 보인다.

이는 인스턴스 자기 자신을 가리키는 특수한 변수이며,

좌측은 생성될 인스턴스의 변수를, 우측의 파라미터로 넘겨받아 할당하겠다는 것을 의미한다.

 

상속(inheritance)

은행을 예로 들어 설명해보자.

은행에서 만드는 계좌의 종류는 수백 가지에 달할 정도로 많다. 하지만 계좌라면 공통적으로 가져아하는 속성들이 있다.

프로그래밍으로 공통 속성을 일일이 구현한다? 매우 비효율적이다.

이보다 더 큰 문제점은 공통 속성에 수정 사항이 생겼을 때, 각각의 전체 계좌 객체에 변경사항을 일일이 적용하려면 신속한 대응과 유지보수에 큰 걸림돌이 되는 것이다.

 

객체 간의 상속 관계에서 상속을 해주는 클래스는 부모 클래스, 상속을 받는 클래스는 자식 클래스라고 한다.

class 자식클래스 extends 부모클래스 와 같이 extends 키워드로 연결해주면 클래스간의 상속 관계가 형성됩니다.

 

오버로딩, 오버라이딩

  • 오버로딩(Overloading - 과적)
    • 조상 클래스에서 상속받은 메서드에서 파라미터를 변경하여 새로운 메서드를 정의하는 것
  • 오버라이딩(Overiding - 덮어쓰기)
    • 조상 클래스에서 상속받은 메서드의 내용을 자식 클래스에서 상황에 맞게 변경해서 정의하는 것
    • 오버로딩된 메서드와 다르게 부모 클래스의 파라미터 설정을 그대로 따른다.

접근 제어자(Access Modifier)

접근 제어자는 용어 그대로 클래스, 멤버 변수, 메서드, 생성자 등에 대한 접근을 제한하는 역할을 수행하는 키워드이다.

그 중 접근 제어자가 중요한 역할을 하는 곳이 바로 멤버 변수이다.

 

멤버 변수에 private 를 설정하지 않으면 객체의 멤버 변수에 대해 무분별한 접근 및 수정을 막을수 없어

보안과 안정성에서 큰 문제를 야기할 수 있다.

가령 4자리만 설정될 수 있는 int 형의 password 라는 변수에 this.password = 123456; 과 같이 의도치 않게 6자리의 값이 할당되어도 제어할 있는 방법이 없다. 

즉, 값을 조회하고 할당하는 것은 this.멤버변수 와 같이 직접 호출을 하는 것이 아니라 전용 메서드르 생성하여 처리해야한다.

 

또한, 굳이 공개될 필요가 없는 시스템 내부의 값들을 가리는 데에도 private 제어자가 사용된다.

이렇게 정보 일부를 가리는 것을 정보 은닉, 혹은 캡슐화라고 한다. (엑셀에서 불필요한 컬럼을 숨김 처리 하는 것과 비슷)

 

  • private 접근 제어자

  • public 접근 제어자

  • default 접근 제어자

  • protected 접근 제어자

 

Getter/Setter

멤버 변수를 직접 호출하지 않고 값을 조회/할당하기 위해서 사용되는 함수를 각각 Getter/Setter 라고 한다.

  1. Getter
    • 멤버 변수의 값을 조회하기 위한 메서드
    • get.멤버변수명() 의 형식으로 명명
    • 객체변수.get멤버변수명() 의 형식으로 사용
  2. Setter
    • 맴버 변수에 값을 할당하기 위한 메서드
    • set멤버변수명(파라미터) 의 형식으로 명명
    • 객체변수.set멤버변수명(파라미터) 의 형식으로 사용

 

인터페이스(Interface)

인터페이스는 설계 이전 스케치 수준의 클래스입니다.

메서드의 이름과 파라미터, 반환 형식만 가질 뿐 실제 구현부는 가질 수 없습니다.

클래스처럼 인스턴스를 생성하는 것도 불가능하다.

 

그럼 인터페이스는 왜 등장하게 된 것일까?

인터페이스는 기능의 표준화를 달성하도록 하는 도구이다.

공통적인 기능을 일정한 단위로 인터페이스로 묶어 처리한 다음 이를 구현할 클래에서

각 업무 로직에 맞게 구현할 수 있다.

 

만약 여러 클래스에 걸쳐 신규 기능이 생기거나 삭제 기능이 있다면

인터페이스라는 표준화 도구를 통해 효율적인 코드 작성이 가능해진다.

 

메서드 구현은 implements 키워드를 사용하여 별도의 클래스 파일에서 해주어야 한다.

 

 

profile

[DEV] study&learn

@devjuni

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!