📌 순천향대학교 멋쟁이 사자처럼 동아리 백엔드 트랙에서 배운 내용을 정리하여 올립니다.
데이터 군을 저장하는 클래스들을 표준화한 설계
- 컬렉션: 다수의 데이터(데이터 그룹)
- 프레임워크: 표준화된 프로그래밍 방식
JDK1.2부터 컬렉션 프레임웍이 등장하면서 다양한 종류의 컬렉션 클래스가 추가되고
모든 클래스를 표준화된 방식으로 다룰 수 있도록 체계화 됨
- 다양하고 풍부한 클래스를 제공하므로 프로그래머의 짐을 상당히 덜어줌
- 인터페이스와 다형성을 이용한 객체지향적 설계를 통한 표준화 -> 사용법 익히기 편리
- 재사용성이 높은 코드 작성
컬렉션 데이터 그룹을 크게 3가지 타입으로 나눔
1. List
2. Set
3. Map // 위 둘과 전혀 다른 형태로 컬렉션을 다루므로 상속계층도에 포함되지 않음
List와 Set을 구현한 클래스들은 서로 많은 공통 부분 존재
= 공통된 부분을 다시 뽑아 Collection 인터페이스 정의
인터페이스 | 특징 |
---|---|
List | 순서 유지 O 데이터의 집합, 데이터 중복 O |
Set | 순서 유지 X 데이터 집합, 데이터 중복 X |
Map | key, Value의 쌍으로 이루어진 데이터 집합, 순서 유지X, Key 중복 X & Value 중복 O |
① 컬렉션 프레임웍의 모든 컬렉션 클래스들은 List, Set, Map 중의 하나 구현
② 구현한 인터페이스의 이름이 클래스의 이름에 포함되어 있어서 이름만으로 클래스의 특징을 쉽게 앎
Vector, Stack, Hashtable, Properties
와 같은 클래스들은 컬렉션 프레임웍의 이전에 존재
따라서 ② 컬렉션 프레임웍의 명명법을 따르지 않음
Vector, Hashtabl과 같은 기존의 컬렉션 클래스들은 호환을 위해 설계 변경
But, 가능하면 ArrayList, HashMap 사용!
- 연관 배열(Associative Array), 해시(Hash), 딕셔너리(Dictionary)라고 함
- Key & Value 대응 관계에 있는 데이터 모임
LinkedMap, HashMap, TreeMap 등 존재, HashMap 가장 많이 사용
- 해싱(Hashing)을 사용하므로 많은 양의 데이터 검색에 뛰어난 성능
HashMap은 키와 값을 각각 Object 타입으로 저장.
즉, (Object, Object)의 형태로 저장하므로 어떠한 객체도 저장O
- 키(Key): 컬렉션 내의 키(Key) 중에서 유일해야 함
- 값(Value): 키(Key)와 달리 데이터의 중복 허용
생성자 / 메서드 | 설명 |
---|---|
HashMap() | HashMap 객체 생성 |
HashMap(int initialCapacity) | 지정된 값을 초기 용량으로 하는 HashMap 객체 생성 |
Object put(key, value) | 지정된 키와 값을 HashMap에 저장 |
Object get(key) | 지정된 키(key)의 값(객체) 반환, 못 찾으면 Null 반환 |
Object getOrDefault(key, defaultValue) | 지정된 키(key)의 값(객체) 반환, 못 찾으면 defaultValue로 지정된 객체 반환 |
boolean containsKey(key) | HashMap에 지정된 키(Key) 포함 여부 반환 |
Object remove(key) | HashMap에 지정된 키로 저장된 값 제거 |
int size() | HashMap에 저장된 요소 개수 반환 |
Set keySet() | HashMap에 저장된 모든 키가 저장된 Set 반환 |
import java.util.HashMap;
public class Sample{
public static void main(String[] args){
HashMap<String, String> map = new HashMap<>();
map.put("people", "사람");
map.put("baseball", "야구");
System.out.println(map.get("people"))
System.out.println(map.get("java"))
System.out.println(map.getOrDefault("java","자바"))
System.out.println(map.containsKey("people"))
System.out.println(map.remove("people"))
System.out.println(map.size());
System.out.println(map.keySet());
}
}
사람
NULL
자바
true
사람
2
[baseball, people]
- 프로그램 실행 중 어떤 원인에 의해 오작동 & 비정상 종료 = 프로그램 에러, 오류
- 발생 시점에 따라 컴파일 에러, 런타임 에러로 나뉨. 그 외 논리적 에러로도
나뉨
- 컴파일 에러: 컴파일 시에 발생하는 에러
- 런타임 에러: 프로그램 실행 도중에 발생하는 에러
- 논리적 에러: 컴파일 & 실행은 잘 되나 의도와 다르게 동작
ex) 창고의 재고 음수, 맞아도 죽지 않음 등
컴파일러가 실행도중에 발생할 수 있는 잠재적 오류까지 검사할 수 없음.
자바에서는 런타임시 발생할 수 있는 프로그램 오류를 에러(error) 와 예외(Exception) 두 가지로 구분.
에러(error): 메모리 부족, 스택 오버플로우 같은, 발생하면 복구할 수 없는 심각한 오류
예외(Exception): 발생하더라도 수습될 수 있는 다소 미약한 오류
모든 예외의 최고 조상은 Excption 클래스
예외 클래스들은 아래와 같이 두 그룹으로 나뉨
1. Exception 클래스와 그 자손들
2. RuntimeException클래스와 그 자손들
RuntimeException 클래스: 프로그래머의 실수로 발생하는 예외
Exception 클래스: 사용자의 실수와 같은 외적인 요인에 의해 발생하는 예외
발생한 예외를 처리하지 못하면, 비정상 종료 & JVM의 예외처리기가 받아서 예외의 원인을 화면에 출력
- try 내부 문장에서 오류가 발생한다면 catch문 코드 실행
- try 내부 코드가 정상적으로 작동한다면 catch문 코드 실행X
// try-catch문 구조
try {
// 예외가 발생할 가능성이 있는 문장
} catch (Exception1 e1) {
// Exception1이 발생한 경우, 이를 처리하기 위한 문장
} catch (Exception2 e2) {
// Exception2가 발생한 경우, 이를 처리하기 위한 문장
} catch (ExceptionN eN) {
// ExceptionN이 발생한 경우, 이를 처리하기 위한 문장
}
finally 블럭은 예외 발생 여부에 상관없이 실행되어야할 코드를 포함시킬 목적으로 사용됨
public void shouldBeRun(){
System.out.println("this code should be run");
}
public static void main(String[] args){
int c;
try {
c=4/0;
} catch (Exception1 e1) {
c=-1;
} finally {
shouldBeRun(); // 이 코드는 무조건 실행됨
}
}
객체지향 이론의 기본 개념
'실제 세계는 사물(객체)로 이루어져있으며, 발생하는 모든 사건들은 사물간의 상호작용이다.'
- 클래스의 인스턴스화(instanitiate): 클래스로부터 객체를 만드는 과정
- 인스턴스 (instance): 어떤 클래스로부터 만들어진 객체
객체: 속성과 기능의 집합
속성: 멤버 변수, 특성, 필드, 상태
기능: 메서드, 함수, 행위
1) 추상화
2) 캡슐화
낮은 결합도의 장점: 코드 오류의 연쇄를 막을 수 있음
3) 상속
장점
- 재사용으로 인한 코드가 줄어듦
- 범용적 사용이 가능함
- 자료와 메서드의 자유로운 사용 & 추가 가능
단점
- 상위 클래스의 변경이 어려움
- 불필요한 클래스가 증가할 수 있음
- 상속이 잘못 사용될 수 있음
4) 다형성
오버라이딩
- 상위 클래스가 가지고 있는 메소드를 하위 클래스가 재정의해서 사용하는 것
오버로딩
- 같은 이름의 메서드가 인자의 개수나 자료형에 따라 다른 기능을 하는 것
장점 | 단점 |
---|---|
클래스 단위의 모듈화 개발을 통해 업무 분담 편리 & 대규모 개발에 적합 | 처리 속도가 상대적으로 느림 |
클래스 단위로 수정 가능 = 유지 보수 편리 | 객체의 수가 많아짐에 따라 용량이 커질 수 있음 |
클래스를 재사용 하거나 상속을 통해 확장하여 코드 재사용 용이 | 설계시 많은 시간과 노력이 필요함 |
SOLID 원칙 = 객체지향 설계 원칙
1. 단일 책임 원칙(SRP, Single Responsibility Principle)
- 하나의 클래스는 하나의 책임만을 가져야 한다.
2. 개방-폐쇄 원칙(OCP, Open/Closed Principle)
- 소프트웨어 요소는 확장에는 열려 있으나 변경에는 닫혀 있어야 한다.
3. 리스코프 치환 원칙(LSP, Liskov Subsitiution Pinciple)
- 객체는 프로그램의 정확성을 깨지 않으면서 하위 타입의 인스턴스로 바꿀 수 있어야 함
- 상위 타입의 객체를 하위 타입의 객체로 치환해도, 상위 타입의 프로그램은 정상 작동해야 함
4. 인터페이 분리 원칙(ISP, Interface Segregation Principle)
- 하나의 인터페이스 보다 여러 개의 인터페이스로 분리하는 것이 좋음
- 인터페이스는 사용자(클라이언트)를 기준으로 분리해야 함
5. 의존관계 역전 원칙(DIP, Dependenct Inversion Principle)
- 추상화가 아닌 구체화에 의존해선 안 됨
- 고수준 모듈은 저수준 모듈의 구현에 의존해선 안 됨
- 저수준 모듈은 고수준 모듈에서 정의한 추상 타입에 의존해야 함
// 동물을 예시로 다양한 Animal 객체를 만들 수 있음
class Animal{
String name;
public void setName(String name){
this.name = name;
}
}
public class Sample{
public static void main(String[] args){
Animal cat = new Animal();
cat.setName("Navi");
Animal dog = new Animal();
dog.setName("happy");
System.out.println(cat.name);
System.out.println(dog.name);
}
}
객체 변수는 객체의 고유한 값이며, 다른 객체와 공유하지 않는다.
class Animal{
String name;
public void setName(String name){
this.name = name;
}
}
class Dog extends Animal{ // Animal 클래스를 상속 받음
void sleep(){
System.out.println(this.name+" zzz...");
}
void sleep(int hour){ // 메서드 오버로딩
System.out.println(this.name+" zzz for "+ hour);
}
}
class HouseDog extends Dog{
void sleep(){ // 메서드 오버라이딩
System.out.println(this.name+" zzz in house");
}
}
public class Sample{
public static void main(String[] args){
Dog dog = new Dog();
HouseDog houseDog = new HouseDog();
dog.setName("happy");
houseDog.setName("0woy");
dog.sleep() // happy zzz... 출력
houseDog.sleep(); // 0woy zzz in house 출력
houseDog.sleep(5); // 0woy zzz for 5 출력
}
}
📖 생성자(Constructor)
// 생성자 오버로딩
class HouseDog extends Dog{
HouseDog(String name){ // String 자료형으로 입력 받는 생성자
this.setName(name);
}
HouseDog(int type){ // int 자료형으로 입력 받는 생성자
if(type==1)
this.setName("yorkshire");
else if(type==2)
this.setName("bulldog");
}
}
public class Sample{
public static void main(String[] args){
HouseDog happy = new HouseDog("happy");
HouseDog yorkshire = new HouseDog(1);
}
}
📖 접근 제어자(Access Modifier)
변수나 메서드의 사용권한은 다음과 같은 접근 제어자를 사용하여 설정
private > default > protected > public
private
해당 클래스에서만 접근 가능
default
접근제어자를 별도로 설정하지 않으면 자동으로 default 제어자
해당 패키지 내에서만 접근 가능
protected
동일 패키지 클래스 또는 해당 클래스를 상속 받는 다른 패키지의 클래스에서만 접근 가능
패키지(Package)
- 비슷한 성격의 자바 클래스들을 모아 놓은 자바의 디렉토리
- 패키지 명이 다르면 클래스명이 동일해도 충돌 없이 사용 가능