본문 바로가기
생각 정리

[패스트캠퍼스] Java & SpringBoot로 시작하는 웹 프로그래밍 : 자바 인강_4주차 학습일지

by jaeyoungb 2022. 7. 7.

# 상속이 사용되는 관계들

   1. IS - A 관계 ( is a relationship : inheritance )

      1) 일반적인 클래스와 구체화된 클래스 간의 관계

      2) 상위 클래스 & 하위 클래스 간의 관계
      3) 클래스 간의 결합도가 높다.

      4) 계층 구조가 복잡하거나 hierarchy가 높으면 좋지 않다.

 

   2. HAS - A 관계 ( composition )

      1) 포함하는 관계

      2) 코드 재사용의 가장 일반적인 방법

      3) 상속하지 않는다.

      4) 예시 : Subject 클래스를 포함하는 Student 클래스

 

클래스를 재활용하고 싶다고 해서 무조건 상속을 하진 않는다. HAS - A 관계를 정의해서 재사용하는 방법이 있다.

 

# 다운 캐스팅 ( downcasting )

   1. 업캐스팅 된 클래스를 다시 원래의 타입으로 형 변환하는 것

   2. 업캐스팅과는 다르게 명시적으로 해야 한다.

   Customer vc = new VIPCustomer();     //  묵시적인 업 캐스팅

   VIPCustomer vCustomer = (VIPCustomer)vc;     //  명시적인 다운 캐스팅

 

# instanceof를 이용한 인스턴스의 형 체크

 

instanceof 키워드로 인스턴스의 형이 원래의 형과 맞는지 체크하여 맞으면 true 틀리면 false를 반환한다.

 

# 추상 클래스 ( abstract class )

<==> 구체적인 클래스 ( concrete class )

   1. 구현부가 없는 추상 메서드가 선언만 되어 있는 클래스

   2. public abstract class A {}

   3. 메서드가 있어도 구현할 것이 없기 때문에, 추상 클래스는 new할 수 없다. ( 인스턴스화할 수 없다. )

   4. 모든 메서드가 구현이 되어 있어도 abstract로 선언되면 추상 클래스다.

   5. 추상 클래스 내의 추상 메서드는 하위 클래스에서 구현한다.

   6. 추상 클래스 내의 구현된 메서드는 하위 클래스들이 공통적으로 쓰는 메서드이고, 재정의 또한 가능하다.

 

※ 상속받을 하위 클래스들이 특정 메서드를 어떻게 구현할지 아직 모를 때, 상위 클래스에서 추상 메서드를 사용한다.

추상 클래스는 상속을 하기 위해 만든 클래스다.

※ 메서드 구현을 다 했지만, abstract class로 선언하는 경우는 new를 안하고 상속만 해줄 클래스라는 뜻이다.

 

# final 예약어

   1. 변수에 쓰이면 상수

   2. 클래스에 쓰이면 상속 불가

   3. 메서드에 쓰이면 재정의 불가

 

# 템플릿 메서드 ( 추상 클래스 응용 )

   1. framework에서 많이 사용되는 패턴

   2. 정해진 시나리오대로 움직이는 패턴

   3. 틀을 가진 메서드를 포함

   4. 상위 클래스에서는 공통으로 구현될 메서드를 구현하면 되고, 그렇지 않은 메서드는 추상 메서드로 남겨놓는다. 공통으로 구현될 메서드는 하위 클래스에서 재정의가 가능하고, 절대 재정의를 하면 안되는 메서드는 final로 선언한다.

 

run() 메서드는 정해진 시나리오를 호출한다.

 

상위 클래스라고 상위 클래스의 모든 메서드들을 빠짐없이 재정의해줄 필요는 없다. 재정의가 필요한 메서드만 재정의 해주면 된다.

 

# 인터페이스 ( interface )

   1. 모든 메서드가 추상 메서드로 선언 ex) public abstract

   2. 모든 변수는 상수로 선언 ex) public static final

   3. java 8 부터 default methodstatic moethod 기능의 제공으로 일부 구현 코드가 있긴 하다.

 

※ 클래스 상속 ==> 상위 클래스에서 구현된 메서드를 하위 클래스에서 재사용

※ 인터페이스 구현 ==> 구현되지 않은 메서드를 구현

 

# 인터페이스 구현과 형 변환

   1. 인터페이스를 구현한 클래스는 인터페이스 형으로 선언한 변수로 형 변환할 수 있다.

Calc calc = new CompleteCalc();

=> 인스턴스는 CompleteCalc로 생성된 것이지만, Calc 타입이다. 여기서, Calc의 변수나 메서드만 사용 가능하고, 재정의된 메서드가 있는 경우에는 그 재정의된 메서드가 적용된다.

   2. 상속에서의 형 변환 ( 업캐스팅 ) 과 같은 의미

 

추상 클래스인터페이스의 공통점과 차이점

   공통점 : 추상 메서드를 사용한다.

   차이점 : 인터페이스implements 키워드를 이용해서 그 클래스가 원하는 기능의 목적에 맞게 구현을 하는 것이 목적이고, 추상 클래스extends 키워드를 이용해서 하위 클래스로 하여금 기능을 확장시키는데에 초점을 맞춘 것이다.

 

# 인터페이스의 사용 목적

   1. 클래스나 프로그램이 어떤 걸 하려는지 알려주는 일을 한다.

   2. client는 interface만 보고 구현하면 된다. ( server 코드까지 들춰볼 필요가 없다. )

   3. 일종의 client 코드와의 약속이며 클래스나 프로그램이 제공하는 명세다.

   4. 인터페이스를 구현한 다양한 객체를 사용한다 - 다형성

 

# 인터페이스의 여러가지 요소

   1. 상수

   public static final의 형태로 들어가고, 반드시 초기화가 필요하다.

 

final 예약어를 안써줘도 자동으로 인식된다. 인터페이스 상수의 예시

 

2. 추상 메서드

   모든 선언된 메서드는 추상 메서드 ( public abstract ) 이다.

 

인터페이스 추상 메서드 예시

 

3. default 메서드 ( java 8 이후 )

   1) 구현부가 있고, 인터페이스를 구현하는 클래스들에서 공통으로 사용할 수 있는 기본 메서드

   2) default 키워드 사용

   3) 구현하는 클래스에서 재정의할 수 있다.

   4) 인터페이스를 구현한 클래스에서 인스턴스가 생성되어야 사용 가능하다.

   5) 여러 인터페이스의 default 메서드가 중복되는 경우는 구현하는 클래스에서 반드시 재정의 해야 한다.

 

인터페이스 default 메서드 예시

 

4. static 메서드 ( java 8 이후 )

   1) 인스턴스 생성과 상관없이 인터페이스 참조로 사용할 수 있는 메서드

   2) static 키워드 사용 

 

인터페이스 static 메서드 예시

 

5. private 메서드 ( java 9 이후 )

   1) 인터페이스를 구현한 클래스에서 재정의할 수 없다.

   2) 인터페이스 내부에서만 사용하기 위해 구현하는 메서드

   3) default 메서드나 static 메서드에서 사용한다.

 

인터페이스의 private 메서드 예시

 

# 인터페이스 상속

   1. 인터페이스 간의 상속도 가능하다.

   2. extends 키워드 사용

   3. 인터페이스는 다중 상속이 가능하고 구현 코드의 상속이 아니므로 타입 상속이라고 한다. 

 

# Object 클래스

   1. 모든 클래스의 최상위 클래스, java.lang 패키지 안에 들어있다, 자동으로 import 된다.

   2. 모든 클래스는 Object 클래스를 상속 받는다 = 모든 클래스는 Object 클래스에 정의된 메서드들을 사용할 수 있고, 재정의도 할 수 있다 ( final 로 선언되지 않는 메서드에 한해서만 )

   3. class Student => class Student extends Object (컴파일러가 자동으로 extends Object를 뒤에 붙여준다.)

 

# Object클래스의 여러 메서드들

   1. toString() : 객체의 정보를 문자열로 바꾸어서 사용할 때 쓰인다. toString()은 자동으로 호출된다.

 

 

   2. equals() 메서드

      1) 두 인스턴스 주소 값을 비교해서 같으면 True / 다르면 False를 반환한다.

      2) 두 인스턴스가 물리적으로 다른 힙 메모리에 저장이 되었더라도, equals() 메서드를 재정의하여 논리적으로 동일한 경우 True를 반환하도록 할 수 있다.

 

   3. hashCode() 메서드

      1) 인스턴스의 저장 주소를 반환한다.

      2) 힙 메모리에 인스턴스가 저장되는 방식을 hash 방식이라고 한다.

자료의 키 값에 대한 저장 위치를 반환해준다.

      3) 두 인스턴스의 equals() 메서드 반환값이 True라면, 동일한 hashcode() 값을 반환한다.

      4) 논리적으로 동일함을 위해 equals() 메서드를 재정의하였다면, hashcode() 메서드 또한 재정의해줘서 동일한 hashcode 값이 반환되도록 한다.

 

   4. clone() 메서드

      1) 객체의 원본을 복제하는데 사용하는 메서드

      2) private 변수 또한 복제되기 때문에, OOP의 정보 은닉 관점에서는 위배될 수 있다.

      3) 해당 클래스를 복제해도 된다는 의미로 public class A implements Cloneable{} 을 써준다.

 

# String 클래스

String 선언 방법 2가지

   1. String str1 = new String("abc");

   2. String str1 = "abc";

 

   1번 방법은 힙 메모리에 새로운 인스턴스가 생성되는 경우

   2번 방법은 상수 풀에 있는 abc 문자열의 주소를 가리키는 경우

 

※ 한 번 생성된 String은 불변이다.

※ String과 String을 연결하면 기존의 String에 연결되는 것이 아닌, 새로운 문자열이 생성된다. ( 메모리 낭비 증가 )

 

# StringBuilder, StringBuffer

   1. 문자열을 여러 번 연결하거나 변경할 때 사용하면 유용하다.

   2. 새로운 인스턴스를 생성하지 않고 char[]를 변경한다. ( 메모리 낭비가 감소 )

   3. StringBuffer는 StringBuilder와는 다르게 Multi Thread Programming에서 Synchronization을 보장한다.

   4. 단일 Thread에서는 StringBuilder를 추천

 

# TextBlock

   1. 문자열을 """ """ 사이에 이어서 만들 수 있다.

   2. html, json 문자열을 만드는데 유용하게 사용할 수 있다.

 

TextBlock 예시

 

# Class 클래스 사용하기

   1. 자바의 모든 클래스와 인터페이스는 컴파일 후에 class 파일이 생성된다.

   2. Class 클래스는 컴파일 된 class 파일을 로드하여 객체를 동적 로드하고, 정보를 가져오는 메서드가 제공된다.

      ==> Class c = Class.forName("java.lang.String");

 

      1) 클래스 이름으로 직접 Class 클래스 가져오기

      ==> Class c = String.class;

 

      2) 생성된 인스턴스에서 Class 클래스 가져오기

      ==> String s = new String();

      ==> Class c = s.getClass();      // getClass 는 Object의 메서드

 

# 동적 로딩

   1. 컴파일 시가 아닌, 실행 중에 데이터 타입을 binding하는 방법

   2. 런타임 시에 원하는 클래스를 로딩하여 binding할 수 있다는 장점이 있다.

   3. 컴파일 시에 타입이 정해지지 않으므로 동적 로딩시 오류가 발생하면 프로그램의 심각한 장애가 발생한다.

 

# Class의 newInstance() 메서드로 인스턴스를 생성한다.

(new 키워드를 사용하지 않고, 클래스 정보를 활용하여 인스턴스를 생성할 수 있다.)

 

# 클래스 정보 알아보기

   1. reflection 프로그래밍 : Class 클래스를 사용해서 클래스의 정보, 인스턴스 생성, 메서드 호출 등을 하는 프로그래밍 방식

   2. 로컬 메모리에 객체가 없거나 원격 프로그래밍, 객체의 타입을 알 수 없는 경우에 주로 사용한다.

   3. java.lang.reflect 패키지의 클래스를 활용한다.

   4. 일반적으로 자료형을 알고 있는 경우에는 사용하지 않는다.