백엔드 과정/Java

[Java] day10. 클래스와 객체 / 캡슐화 / 생성자

mim 2021. 12. 29. 14:53
반응형

다들 객체까지는 예습하라고 했는데, 안했기 때문에 두렵다..

객체지향언어 OOP 제발 이해할 수 있길.

 


 

클래스

클래스는 서로 다른 자료형의 데이터들 을 사용자 개발자 ) 정의로 하나로 묶어 새로운 타입을 정의
배열과 달리 다른 자료형들의 값을 하나로 묶을 수 있음

다른 곳에서 클래스의 필드에 접근하기 위해 '.' (참조연산자)를 활용.

 

 

클래스 내부에는 메소드를 작성하지 않고 바로 변수를 선언할 수 도 있다.
이것을 전역변수( 필드 == 인스턴스 변수 == 속성)라고 부른다.  

 

필드에 접근하기 위해서는 레퍼런스명.필드명 으로 접근한다.
 ' . '은 참조연산자 라고 하는데, 레퍼런스 변수가 참조하고 있는 주소로 접근한다는 의미를 가진다.
 각 공간을 필드명으로 접근한다. (배열은 인덱스로 접근, 객체는 필드명으로 접근)

 

 

필드에 직접 접근 시 문제점

1. 잘못된 값이 대입될 수 있다.

2. 필드명이 변경되면 관련된 코드를 일일히 수정해야한다. ( 유지보수성 ↓)

 

해결 방법

필드에 직접 접근하지 않고 메소드를 이용하여 간접 접근하도록 하면

올바르지 않은 범위의 값으로 변경되는 것도 막을 수 있고,
필드 값의 변경이 발생하더라도 사용자는 코드를 변경하지 않아도 된다.

 

 

필드에 직접 접근을 제한하는 방식

접근 제한자

클래스 혹은 클래스의 멤버에 참조연산자로 접근할 수 있는 범위를 제한하기 위한 키워드이다.
 1. public : 모든 패키지에 접근 허용
 2. protected : 동일 패키지에 접근 허용. 단 상속관꼐에 있는 경우 다른 패키지에서도 접근 가능
 3. default : 동일 패키지 내에서만 접근 허용. (작성하지 않는 것이 default)
 4. private : 해당 클래스 내부에서만 접근 허용

 

구분 해당클래스내부 같은패키지내 후손클래스내 전체
+ public O O O O
# protected O O O  
~ default O O    
-  private O      

위에 네 가지 접근 제한자는 클래스의 멤버(필드, 메소드)에 모두 사용가능하다.
단, 클래스 선언 시 사용하는 접근 제한자는 public과 default만 사용 가능하다.

 

캡슐화(encapsulation)

선언한 필드대로 공간은 생성되어 있지만 직접 접근 못하고
public으로 접근을 허용한 메소드만 이용할 수 있도록 해놓은 것이다.

=> 캡슐화는 유지보수성 증가를 위해 필드에 직접 접근을 제한하고

public 메소드를 이용해서 간접적으로 접근하여 사용할 수 있도록 만든 기술
클래스 작성 시 특별한 목적이 아닌 이상 캡슐화가 기본 원칙으로 사용되고 있다.

 

 


객체 지향 언어

객체 지향 언어란 ?
현실 세계 는 사물이나 개념처럼 독립되고 구분되는 각각의 객체 로 이루어져 있으며
발생하는 모든 사건들은 객체 간의 상호작용 이다
이 세계관을 프로그래밍 언어에 도입하여 만들어진 언어가 객체 지향 언어 이다

클래스(class) 란 ?
객체를 추상화 한 것으로 인스턴스를 생성 할 목적 으로 정의 해놓은 소스 코드 작성 단위
자바에서 객체를 구현하기 위한 매커니즘으로 클래스를 사용한다


객체의 할당
new 연산자와 생성자를 사용하여 객체 생성 시 heap 메모리 공간에 서로 다른 자료형
데이터가 연속으로 나열 할당 된 인스턴스 공간

 

추상화 ( abstraction )란 ?
유연성을 확보하기 위해 구체적인 것은 제거한다는 의미
프로그램에서 필요한 공통점을 추출 하고 , 불필요한 공통점을 제거 하는 과정

 

 

 캡슐화의 원칙에 일부 어긋나긴 하지만 매번 추상화를 하지 않아도 되는 객체도 존재한다.
 행위 위주가 아닌 데이터를 하나로 뭉치기 위한 객체(Data Transfer Object)의 경우이다.
 
 값 객체를 설계할 때는 행위가 아닌 데이터 위주이며, 캡슐화 원칙을 준수하려
 모든 필드를 private로 직접 접근을 막고, 각 필드값을 변경하거나 반환하는 메소드를 세트로 미리 작성해둔다.
 private 필드와 필드값을 수정하는 설정자(setter), 필드에 접근하는 접근자(getter)들로 구성된다.

 

private로 만들면 필드에 직접 접근이 제한되므로 public으로 접근을 허용하는
 설정자/접근자를 통해 간접 접근할 수 있도록 한다.

설정자(setter) / 접근자(getter)의 경우 실무에서 암묵적으로 통용되는 작성 규칙이 존재한다.
 
설정자(setter) 작성규칙
 : 필드값을 변경할 목적의 매개변수를 변결하려는 필드와 같은 자료형으로 선언하고,
 호출 당시 전달되는 매개변수의 값을 이용하여 필드의 값을 변경한다.
 

[표현식]
 public void set필드명(매개변수){
 	필드 = 매개변수;
 }

[작성예시]
 
 public void setName(String name) {
 	this.name = name;
 }


 접근자(getter) 작성규칙
 : 필드의 값을 반환 받을 목적의 메소드 집합을 의미한다.
 각 접근자는 하나의 필드에만 접근하도록 한다.
 필드에 접근해서 기록된 값을 return을 이용하여 반환하며, 이 때 반환 타입은 반환하려는 값의 자료형과 일치시킨다.
 

 [표현식]
 public 반환형 get필드명() {
   return;
 }
  
 [작성예시]
 
public String getName() {
 	return this.name;
}

/*boolean인 접근자는 get으로 시작하지 않고 is로 시작하는 것이 관례이다.*/
public boolean isActivated() {
		return isActivated;
}

 

 


생성자 ( Constructor ) 란?
객체가 new 연산자 를 통해 Heap 메모리 영역에 할당될 때 1 회성으로 호출되는 리턴타입이 없는 메소드
인스턴스 생성 시 필드 초기화 목적 으로 주로 사용 된다

생성자 작성 규칙
생성자의 선언은 메소드 선언과 유사하지만 반환값이 없음
생성자명을 클래스명과 동일해야 함

 * 지금까지 우리가 객체를 생성할 때
 * 클래스명 래퍼런스변수 = new 클래스명(); 이라고 작성했으나
 * new 뒤의 클래스명은 사실 생성자 (constructor)라 불리는 메소를 호출하는 구문이다.
 * 정확히 말하자면 클래스명 레퍼런스변수 = new 생성자(); 라고 표현한다.*/
		
		
* 생성자란?
* 인스턴스를 생성할 때 초기 수행할 명령이 있는 경우 미리 작성해두고, 인스턴스를 생성할 때 호출된다.
* 생성자 함수에 매개변수가 없는 생성자를 기본 생성자( default constructor) 라고 하며,
* 기본 생성자는 컴파일러에 의해 자동으로 추가되었기 때문에 지금까지 명시적으로 작성하지 않고 사용할 수 있었다.
* -> 매개변수가 있는 생성자가 한 개라도 존재하는 경우 컴파일러는 기본 생성자를 
*    자동으로 추가해주지 않으니 주의!
* 
* 기본 생성자를 통해 인스턴스를 생성하게 되면 자료형별 초기값을 이용해 필드를 초기화 한다.
* 필드의 초기값을 사용자가 원하는대로 설정하고 싶은 경우 생성자의 호출 시
* 인자로 값을 전달하여 호출할 수 있다. 
* 이러한 인자를 받아 필드를 초기화 할 목적의 생성자를 매개변수가 있는 생성자 라고 한다. 
* *

 

생성자의 작성위치

작성 위치는 문법적으로 클래스 내부에 작성하면 되지만,
통상적으로는 필드 선언부와 메소드 선언부 사이에 작성하는 것이 관례이다.

 


생성자의 사용목적

  1. 인스턴스 생성 시점에 수행할 명령이 있는 경우 사용한다.
  2. 매개변수 있는 생성자의 경우 매개변수로 전달받은 값으로 필드를 초기화하며
    인스턴스를 생성할 목적으로 주로 사용된다.
  3. 작성한 생성자 외에는 인스턴스를 생성하는 방법을 제공하지 않는다는 의미를 가진다.
    따라서, 인스턴스를 생성하는 방법을 제한하기 위한 용도로 사용할 수도 있다. (초기값 전달 강제화)

 


생성자 작성 방법

[표현식]
접근제한자 클래스명(매개변수) {
	인스턴스 생성 시점에 수행할 명령기술 (주로 필드 초기화);
	this.필드명 = 매개변수; //설정자(setter) 여러 개의 기능을 한 번의 호출로 수행할 수 있다.
}

 

this 는 인스턴스가 생성되었을 때 자신의 주소를 저장하는 래퍼런스 변수이다.
지역변수와 전역변수의 이름이 동일한 경우 지역변수를 우선적으로 접근하기 때문에
전역변수에 접근하기 위해서 this. 을 명시해야 한다.

 

 

 

반응형