1. 객체 지향 프로그램

Object Oriented Programming

객체

물리적으로 존재하거나 추상적인 것 중에서 자신의 속성(field)과 동작(method)을 가지는 모든 것

객체의 상호 작용

객체들은 서로 간에 기능(동작)을 이용하고 데이터를 주고 받음
→ 자바의 객체도 서로 간 method를 호출하고 결과를 받음

객체 간의 관계

객체들은 다른 객체들과 관계를 맺는데 세 가지 종류가 있음

집합 관계

완성품과 부품의 관계
(자동차 - 엔진 / 타이어 / 핸들)

사용 관계

객체가 다른 객체를 사용하는 관계
(사람 - 자동차)

상속 관계

종류 객체와 구체적인 사물 객체의 관계
(기계 - 자동차)

객체 지향 프로그래밍의 특징

캡슐화

객체의 field, method를 하나로 묶고 실제 구현 내용을 외부에 감추는 것 의미
외부 객체는 객체 내부의 구조를 알지 못하며 객체가 제공하는 field, method만 이용 가능
보호 이유는 외부의 잘못된 사용으로 인한 객체 손상을 방지하기 위함
접근 제한자를 이용해 캡슐화된 멤버를 공개할 지 숨길 지 결정

상속

상위(부모) 객체의 필드와 메소드를 하위(자식) 객체에게 물려주는 행위
하위 객체는 상위 객체를 확장하여 추가적인 필드와 메소드 가질 수 있음

상속의 효과

  • 상위 객체 재사용을 통해 하위 객체 빨리 개발 가능
  • 반복된 코드의 중복 줄여줌
  • 유지 보수의 편리성 제공
  • 객체의 다형성 구현 가능

다형성(Polymorphism)

같은 타입이지만 실행 결과가 다양한 객체를 대입할 수 있는 성질

  • 부모 타입에는 모든 자식 객체 대입 가능
  • 인터페이스 타입에는 모든 구현 객체 대입 가능

효과로는 유지보수가 용이하고, 객체를 부품화시킬 수 있다는 점이 있음

2. 인스턴스 멤버와 this

인스턴스 멤버

객체마다 가지고 있는 필드와 메소드 (인스턴스 필드 / 인스턴스 메소드)
객체에 소속된 멤버이므로 객체 없이는 사용 불가

public Class Car{
	int gas;
    void setSpeed(int speed){...}
}

Car myCar = new Car();
myCar.gas = 10;
myCar.setSpeed(60);

Car yourCar = new Car()l
yourCar.gas = 20;
yourCar.setSpeed(90);

this

객체 자신의 참조(주소값)을 가지도 있는 키워드로 객체 내부에서 인스턴스 멤버임을 명확하게 하기 위해 붙임
주로 매개변수필드명이 동일한 경우 인스턴스 필드임을 명확하게 하기 위해 사용

Car(String model){
	this.model = model;
}

void setModel(String model){
	this.model = model;
}

10 정적 멤버와 static

정적 멤버 (static member)

클래스에 고정된 필드와 메소드를 말하며 각각 정적 필드, 정적 메소드라고 부름
정적 멤버는 클래스에 소속되어 있지만 객체 내부에 존재하지 않고, 메소드 영역에 존재하여 객체 생성 과정 없이 클래스로 바로 접근해서 사용함

public class A{
	static [type] [field] = [초기값];
   	
    static [returnType] [methodName] (parameter, ...){...}

정적 멤버 사용 방법

클래스 이름과 함께 '.' 연산자로 접근
클래스.필드; 클래스.메소드(매개값);

public class Calculator {
	static double pi = 3.14159;
    static int plus(int x, int y){...}
    static int minus(int x, int y){...}
}

double result1 = 10 * 10 * Calculator.pi;
int result2 = Calculator.plus(10, 5);
int result3 = Calculator.minus(10, 5);

인스턴스 멤버 vs 정적 멤버

필드

객체마다 가지고 있어야하는 데이터 : 인스턴드 필드
공용적인 데이터 : 정적 필드

public class Calculator{
	String color; //계산기별로 다른 값 가질 수 있음
    static double pi = 3.14159; //모든 계산기가 동일한 값 가짐
}

메소드

인스턴스 필드로 작업해야하는 메소드 : 인스턴스 메소드
인스턴스 필드로 작업하지 않는 메소드 : 정적 메소드

public Calculator{
	String color;
    void setColor(String color){
    	this.color = color;
    }
    static int plus(int x, int y){
    	return x + y;
    }
    static int minus(int x, int y){
    	return x - y;
    }
}

정적 초기화 블록

클래스가 메소드 영역으로 로딩될 떄 자동으로 실행되는 블록으로 정적 필드의 복잡한 초기화 작업정적 메소드를 호출할 수 있으며, 여러 개가 선언되어도 선언한 순서대로 실행됨
정적 필드 값 초기화에 복잡한 연산(반복문, 조건문 등)이 필요한 경우 사용

public class Television{
	static String company = "Samsung";
    static String model = "LCD";
    static String info;
    static int From1To10Sum;
    
    static{
    	info = company + "-" + model;
        
        for(int i = 1 ; i <= 10 ; i++){
        	From1To10Sum += i;
        }
    }
}

11. final 필드와 상수

final 필드는 최종적인 값을 갖고 있는 필드로 값 변경이 불가능하며, 딱 한 번 초기값 지정할 수 있음

  • 필드 선언 시 초기화
  • 생성자를 통한 초기화
public class Person{
	final String nation = "Korea";
    final String snn;
    String name;
    
    public Person(String ssn, String name){
    	this.ssn = ssn;
        this.name = name;
    }
}

nation은 필드 선언과 함꼐 값을 초기화하여 변경이 불가능하며, ssn은 생성자에서 값이 주입되고 나면 변경이 불가능해짐

상수 (static final)

정적 final 필드

final과 static final의 차이

  • final : 객체마다 자기는 불변의 인스턴스 필드
  • static final : 객체들의 공용 데이터, 즉 객체마다 가지지 않고 클래스 별로 관리되는 불변의 정적 필드 (메소드 영역에서 관리됨)

상수 선언과 초기과 방법

상수 이름 : 전체 대문자 및 다른 단어 결합 시 _ 로 연결
초기화 방법

static final 타입 상수 [= 초기값];

static final 타입 상수;
static {
	상수 = 초기값;
}

13. 접근 제한자

접근 제한자

클래스 및 클래스의 구성 멤버에 대한 접근을 제한

  • 클래스 제한 : 다른 패키지에서 클래스를 사용하지 못하도록 제한
  • 생성자 제한 : 클래스로부터 객체를 생성하지 못하도록 제한
  • 필드와 메소드 제한 : 특정 필드와 메소드를 숨김 처리

접근 제한자 종류

접근제한적용 대상접근할 수 없는 클래스
public클래스, 필드, 생성자, 메소드없음
protected필드, 생성자, 메소드자식 클래스가 아닌 다른 패키지에 속한 클래스
default클래스, 필드, 생성자, 메소드다른 패키지에 소속된 클래스
private필드, 생성자, 메소드모든 외부 클래스

15. 어노테이션

프로그램에 추가적인 정보를 제공해주는 메타데이터

용도

  • 컴파일러에게 코드 작성 문법 에러를 체크하도록 정보 제공 (@Override)
  • 소프트웨어 개발 툴이 빌드나 배치 시 코드를 자동으로 생성할 수 있도록 정보 제공
  • 실행(런타임) 시 특정 기능을 실행하도록 정보 제공

타입 정의와 적용

//타입 정의
//파일 AnnotationName.java
public @interface AnnotationName {
}

//타입 적용
@Ovverride
public void toString(){...}

어노테이션의 element 멤버

어노테이션을 코드에 적용할 때, 외부의 값을 입력받을 수 있도록 하는 역할

  • element 선언
public @interface AnnotationName{
	타입 elementName() {default};
    ...
}

//example
public @interface AnnotationName{
	String elementName1();
    int elementName2() dafault 5;
}
  • 어노테이션 적용 시 엘리먼트 값 지정
@AnnotationName(elementName1="value", elementName2=3);

@AnnotationName(elementName1="value");

@AnnotationName("value");// 이 경우 모든 element 중 한 개를 제외한 나머지 elementsms default 값이 들어갔기 때문에 elementName1에 저장

어노테이션 적용 대상

코드상에서 어노테이션 적용할 수 있는 대상으로 java.lang.annotation.ElementType 열거 상수로 정의되어 있음

ElementType 열거 상수적용 대상
TYPE클래스, 어노테이션, 열거 타입
ANNOTATION_TYPE어노테이션
FIELD필드
CONSTRUCTOR생성자
METHOD메소드
LOCAL_VARIABLE로컬 변수
PACKAGE패키지

적용 대상 지정 방법

  • @Target 어노테이션으로 적용 대상 지정
  • 기본 element인 value의 타입은 ElementType 배열
@Target({ElementType.Type, ElementType.FIELD, ElementType.METHOD})
public @interface AnnotationName{}

//위와 같이 선언된 어노테이션 적용 예시

@AnnotationName
public class ClassName{
	@AnnotationName
    private String fieldName;
    
    @AnnotationName
    public void methodName(){
    }
    
    //불가능한 경우
    @public ClassName(){}
}

어노테이션 유지 정책

java.lang.annotation.RetentionPolicy 열거 상수로 지정되어 있어 어노테이션 적용 코드가 유지되는 시점을 지정함

RetentionPolicy 열거 상수설명
SOURCE소스 상에서만 어노테이션 정보를 유지한다. 소스 코드를 분석할 때만 의미가 있으며 바이트 코드 파일에는 정보 남지 않음
CLASS바이트 코드 배열까지 어노테이션 정보를 유지하지만 리플렉션을 이용해 어노테이션 정보 얻기는 불가능
RUNTIME바이트 코드 배열까지 어노테이션 정보를 유지하면서 리플렉션을 이용해 런타임에 어노테이션 정보 얻기 가능

Reflection : 런타임에 클래스의 메타 정보 얻는 기능

클래스가 가지고 있는 필드, 생성자, 메소드, 어노테이션 정보 얻기 가능
런타임 시 어노테이션 정보 얻으려면 유지 정책 RUNTIME으로 지정

유지 정책 지정 방법

  • @Retention 어노테이션으로 유지 정책 지정
  • @Retention의 기본 엘리먼트인 value 타입은 RetentionPolicy
@Target({ElementType.TYPE, ElementType.FIELD, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface AnnotationName{
}

런타임 시 어노테이션 정보 얻기

클래스에 적용된 어노테이션 정보

클래스.class의 어노테이션 정보 얻는 메소드 이용

필드, 생성자, 메소드에 적용된 어노테이션 정보

클래스.class의 다음 메소드 이용해 java.lang.reflect 패키지의 Field, Constructor, Method 클래스의 배열 얻어낸 다음, Field, Constructor, Method의 어노테이션 정보 얻는 메소드 이용

리턴타입메소드명(매개변수)설명
Field[]getField()필드 정보를 Field 배열로 리턴
Constructor[]getConstructor()생성자 정보를 Constructor 배열로 리턴
Method[]getDeclaredMethods()메소드 정보를 Method 배열로 리턴

어노테이션 정보 얻는 메소드

리턴타입메소드명(매개변수)설명
booleanisAnnotationPresent(Class<? extends Annotation> annotationClass)지정한 어노테이션이 적용되었는지 여부, Class에서 호출했을 경우 상위 클래스에 적용된 경우에도 true 리턴
AnnotationgetAnnotation(Class<T.> annotationClass)지정한 어노테이션이 적용되어 있으면 어노테이션을 리턴하고 그렇지 않다면 null 리턴, Class에서 호출했을 경우 상위 클래스에 적용된 경우에도 어노테이션 리턴
Annotation[]getAnnotations()적용된 모든 어노테이션을 리턴한다. Class에서 호출했을 경우 상위 클래스에 적용된 어노테이션도 모두 포함한다. 적용된 어노테이션이 없을 경우 길이가 0인 배열을 리턴한다.
Annotation[]getDeclaredAnnotations()직접 적용된 모든 어노테이션을 리턴한다. Class에서 호출했을 경우 상위 클래스에 적용된 어노테이션은 포함되지 않음
profile
🐥

0개의 댓글

Powered by GraphCDN, the GraphQL CDN