[20240126 TIL] JAVA 총 정리 ② - Java의 정석 [기초편]

Haizel·2024년 1월 26일
1
post-thumbnail

❗️ Information

  • 어제 있던 중간고사 시험을 위해 [Java의 정석 - 기초편]을 읽은 후, 필요한 내용에 대해서만 정리했습니다.

  • 따라서 각 개념들에 대해 내용이 다소 빈약할 수 있다는 점 양해해주세요. 🙇‍♀️


📌 클래스 & 인스턴스 만들기


class Tv {
	string color;
	boolean power;
	int channel;

	void power(boolean pow) {
		power = pow;
	}
	// 또는
	void power(boolean power) {
		this.power = power; 
	}

	void channelUp() {
		++channel;
	}
}

class TvTest {
	public static void main(String arg[]) {
		Tv t = new Tv();
		t.channel = 6;
		t.channelUp();
		System.out.println(t); // t = 7;
	}
}

class CaptionTv extends Tv {
	boolean caption;

	void displayCation (String text) {
		if(caption) {
			System.out.println(text);
		}
	}

}

📌 상속


  1. 생성자와 초기화 블록은 상속되지 않는다. 즉 멤버만 상속된다.
  2. 자손 클래스의 멤버 개수는 조상 클래스보다 항상 같거나 많다.

✔️ 상속관계

children --> parent

  • 자손 클래스의 인스턴스를 생성하면, 조상 클래스의 멤버와 자손 클래스의 멤버가 합쳐진 하나의 인스턴스로 생성된다.
  • 자바는 오직 단일 상속만 허용

✔️ 클래스 간의 관계

1. 포함관계

has-a : ~은 ~을 가지고 있다.

class Point {
	int x; 
	int y;
}

class Circle {
	Point c = new Point();
	int r;
}

2. 상속관계

is-a : ~은 ~이다.

class Circle extends Point {
	int r;
}

📌 오버로딩 / 오버라이딩


✔️ 오버로딩

  1. 메서드의 이름 동일해야함.
  2. 매개변수의 개수나 타입이 달라야함.

✔️ 오버라이딩

  1. 메서드의 이름이 동일해야함.
  2. 매개변수가 같아야 함.
  3. 반환타입이 같아야 함.

❗️ 오버라이딩하는 자손 클래스는 부모 클래스보다 접근 범위가 적으면 안된다.

  • 부모 : protected / 자식 : protected, public 👉 가능
  • 부모 : public / 자식 : protected 👉 불가능

📌 super와 super()


✔️ super

super : 자손클래스에서 조상클래스에게 상속받은 멤버를 참조하는 데 사용되는 참조 변수

  • 조상 클래스의 멤버와 자손 클래스의 멤버가 중복 정의되어 구별해야 하는 경우에만 super을 사용
  • 메서드와 마찬가지로, 클래스 메서드(static)는 super을 사용할 수 없다.

✔️ super()

super() : 조상 클래스의 생성자를 호출하는데 사용
❗️ 생성자와 초기화 블록은 상속되지 않는다. 즉 멤버만 상속된다.

  1. 자손 클래스의 인스턴스를 생성하면 → 자손의 멤버와 조상의 멤버가 모두 합쳐진 하나의 인스턴스가 생성됨
    • 그래서 자손 클래스의 인스턴스가 조상 클래스의 멤버를 사용할 수 있는 거임
  2. 이때 조상 클래스 멤버의 초기화 작업이 수행되어야 하기 때문에, 자손 클래스의 생성자에서 조상 클래스의 생성자가 호출되어야 한다.
    • 이를 하는 것이 super()임 !!!!
  • Object 클래스를 제외한 모든 클래스의 생성자 첫 줄에는 생성자.this() 또는 super()을 호출해야 한다.
    - 만약 조상 클래스 생성자가 매개 변수를 받지 않는다면 → 생략 가능 (컴파일러가 자동으로 삽입해줌)
    - 받는다면 → 무조건 작성 필요(아니면 컴파일 오류남)
class PointTest {
	public static void main(String args[]) {
		Point3D p3 = new Point3D(1, 2, 3);
	}
}

class Point {
	int x, y;

	Point(int x, int y) {
		this.x = x;
		this.y = y;
	}

    String getLocation() {
	    return "x : x + y";
    }
}

class Point3D extends Point {
	int z;

	Point3D(int x, int y, int z) {
		super(x, y); // extends 받은 조상 클래스 멤버의 초기화 작업 수행
		this.z = z;
	}
}

📌 제어자


1. static - 클래스의, 공통적인

  • use : 멤버변수, 메서드, 초기화 블럭

2. final - 마지막의, 변경될 수 없는

  • use: 클래스, 메서드, 멤버변수, 지역변수

3. abstract - 추상의, 미완성의

  • 메서드의 선언부만 작성하고, 실제 수행내영은 구현하지 않은 추상 메서드를 선언하는데 사용
  • use: 클래스, 메서드

✔️ 접근 제어자

use: 클래스, 멤버변수, 메서드, 생성자
캡슐화(은닉)을 위해 사용

  • private : 같은 클래스 내만 접근 가능 👉 메서드, 멤버 변수
  • default : 같은 패키지 내 👉 클래스, 메서드, 멤버변수
  • protected : 같은 패키지 내 (단 다른 패키지의 자손클래스에서 접근 가능) 👉 메서드, 멤버변수
  • public : 접근 제한 없음 👉 모두 가능

📌 abstract 추상 클래스 & 추상 메서드 / 인터페이스


✔️ 추상 클래스

  • 추상 클래스로는 인스턴스를 생성할 수 없다.
  • 추상클래스는 상속을 통해 자손클래스에 의해서만 완성될 수 있음
  • 추상클래스에도 메서드가 있으며, 멤버변수와 메서드도 가질 수 있음
  • 인터페이스도 일종의 추상 클래스임(단 추상 메서드는 갖지 못함)

✔️ 추상 메서드

  • 선언부만 작성하고 구현부는 작성하지 않은 메서드

✔️ 인터페이스

  • 인터페이스도 추상클래스처럼 그 자체로는 인스턴스를 생성할 수 없다.
  • 인터페이스는 구현한다는 의미인 implements 를 사용한다.
// 문법
class 클래스이름 implement 인터페이스이름 {
	// 인터페이스에서 정의된 추상메서드 구현
}

// 예제
class Fighter implement Fightable {
	public void move(int x, int y) {
		...
	}
	public void attack(Unit u) {
		...
	} 
}

만약 구현하는 인터페이스의 메서드 중 일부만 구현한다면, abstract을 붙여 추상 클래스로 선언해야 한다.

 abstract class Fighter implement Fightable {
	public void move(int x, int y) {
		...
	}
}

✔️ 인터페이스의 장점

  1. 개발 시간 단축
  2. 표준화 가능
  3. 서로 관계없는 클래스에게 관계를 맺어줄 수 있음
  4. 독립적인 프로그래밍 가능

📌 예외처리


에러 : 수습될 수 없는 심각한 오류
예외 : 수습될 수 있는 미약한 오류

✔️ 프로그램 오류

  • 컴파일 에러 : 컴파일 시 발생
  • 런타임 에러 : 실행 시 발생
  • 논리적 에러 : 실행은 되지만 의도와 다르게 동작

✔️ 예외 클래스의 계층 구조

  • exception
    - IOException
    - ClasNotFoundException
    - ...
    - RuntimeException
    - ArithmeticException
    - ClassCastException
    - NullPointException
    - ...
    - IndexOutBoundsException

✔️ 예외 발생시키기

  • 키워드 throw를 사용해 고의로 예외를 발생시킬 수 있음
  • try-catch문으로 예외 처리
// 1. new 연산자를 통해 예외 클래스의 객체를 만든다.
Exception e = new Exception('error');

// 2. throw 키워드로 예외 발생시킴
throw e;

✔️ 예외 처리

  • 또는 메서드 선언부에 키워드 throws를 사용해 메서드 내 발생할 수 있는 예외 처리
void method() throws Exception1, Exception2... {
  ...
}

✔️ finally

  • 예외 발생 여부에 상관 없이 실행됨 -> 즉 예외 발생 여부와 관계 없이 항상 수행되어야 할 코드를 해당 블록 안에 작성한다.
  • try-catch-finally 순

📌 컬렉션 프레임워크


✔️ List

List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);

numbers.stream().filter(x => x % 2 == 0);

✔️ ArrayList

  • 가장 많이 사용되는 컬렉션 클래스
  • 데이터 저장 순서 유지, 중복 허용
  • 모든 종류의 객체 담을 수 있음
ArrayList list = new ArrayList();

✔️ LinkedList

  • 데이터 접근시간이 가장 빠르다
  • 크기 변경 불가능

✔️ ArrayList vs LinkedList

  1. 순차적으로 추가/삭제만 하는 경우 👉 ArrayList
  2. 중간 데이터를 추가/삭제하는 경우 👉 LinkedList

✔️ MAP

Map<String, Integer> map = Map.of("A", 3, "B", 5, "C", 10);

✔️ Collections과 동기화(Syncronized)

  • 가장 많이 쓰이는 ArrayList, HashMap같은 컬렉션은 자체적인 동기화를 지원하지 않고, Syncronized 👈 동기화 메서드를 사용해 동기화 작업을 처리한다.
List syncList = Collections.syncronizedList(new ArrayList(..));

📌 제네릭(generics)


✔️ 제네릭이란?

  • 다양한 타입의 객체들을 다루는 메서드나 컬렉션 클래스에 컴파일 시 타입 체크를 해주는 기능
  • 객체의 타입을 컴파일 시 체크하기 때문에 👉 객체의 타입 안정성을 높이고 && 형변환의 번거로움을 줄일 수 있다.
    - 타입 안정성 : 의도하지 않은 타입으로 잘못 형변환되는 걸 방지
  • 제네릭 타입은 컴파일 할때만 사용되고 제거된다.

① 제네릭 클래스 선언

// 원래 코드
class Box {
	Object item;

	void setItem(Oject item) {
		this.item = item;
	}

	Object getItem() {
		return item;
	}
}

⬇️

// 타입 변수로 바꿔줌
class Box<T> { // T : 타입 변수
	T item;

	void setItem(T item) {
		this.item = item;
	}

	 T getItem() {
		return item;
	}
}

타입 변수 : 임의의 참조형 타입을 의미

② 제네릭 타입 호출

이후 제네릭 클래스가 된 Box 클래스의 객체 생성 시 👉 실제 타입을 지정

// 제네릭의 실제 타입 지정해줌
Box<String> b = new Box<String>(); // 타입 T대신 실제 타입 지정
b.setItem('abc'); // ok
  • 제네릭 클래스 Box의 객체를 생성할 때, 객체별로 다른 타입을 지정하는 것이 적절하다.
    - 제네릭은 인스턴스별로 다르게 동작하도록 만든 기능이기 때문
  • 단 모든 객체에 대해 동일하게 작동해야 하는 static 멤버에 타입 변수 T를 이용할 수 없다.
    - 사실 애초에 static 멤버는 인스턴스 변수를 참조할 수 없음
ArrayList<T> list = new ArrayList<T>();

✔️ 결과

  • T 👉 String타입으로 지정된 것과 같음.

✔️ 용어 정리

  • Box<T> : 제네릭 클래스
  • T : 타입 변수 / 타입 매개 변수
  • Box : 원시 타입(raw type)
  • String : 매개변수화된 타입

📌 열거형(Enumeration)


✔️ 열거형(Enumeration)이란

  • 서로 관련된 상수를 편리하게 선언하기 위한 것, 여러 상수를 정의할 때 유용
  • 값 뿐만 아니라 타입도 관리 가능
    - 값이 같아도 타입이 다르면 컴파일 에러 발생
  • 열거형의 생성자는 제어자가 묵시적으로 private로 지정됨
// 기본 문법
enum 열거형이름 {상수1, 상수2, 상수3, ...}

// 예제
class Card {
	enum Kind { CLOVER, HEART, DIAMOND }
	enum value { TWO, THREE, FOUR }

	final Kind kind;
	final Value value;
}

📌 애너테이션(Annotation)


애너테이션은 주석처럼 코드에 영향을 미치지 않으면서 프로그램에게 유용한 정보를 제공할 수 있다.


✔️ 표준 애너테이션

자바는 기본적으로 제공하는 애너테이션이 몇게 없다.
그 중 일부는 메타 애너테이션으로 애너테이션을 정의하는데 사용되는 애너테이션이다.

Annotation설명
@Override컴파일러에게 오버라이딩하는 메서드라는 것을 알림
@Deprecated앞으로 사용하지 않을 것을 권장하는 대상에 붙임
@FunctionalInterface함수형 인터페이스라는 것을 알림
profile
한입 크기로 베어먹는 개발지식 🍰

0개의 댓글

관련 채용 정보