Notice
Recent Posts
Recent Comments
Link
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
Archives
Today
Total
관리 메뉴

DD: Development Diary

[JAVA] 혼공자바 3주차_클래스 본문

카테고리 없음

[JAVA] 혼공자바 3주차_클래스

찹쌀주 2024. 1. 21. 19:32

기본 미션

그림 1. 클래스 개념 혼공 노트에 정리

선택 미션

각각의 속성을 가지고 기능을 수행하는 여러 개의 객체를 조립해서 프로그램을 만드는 상향식 기법을 객체 프로그래밍이라 한다. 예를 들어, 지금 내가 공부하고 있는 도서관을 만들기 위해

책장(속성: 틀, 칸막이, 청구기호와 분류가 적힌 표지판 / 기능: 책을 보관함),

도서 대출 반납기(속성: 모니터, 바코드 스캐너, 스피커 / 기능: 이용자가 원하는 책을 대출하거나 반납하는 전산 과정),

서로 다른 책 등을 필요한 만큼 만들고, 제 위치에 배치하는(조립하는) 과정을 거치는 것이다. 

그림 2. 객체 지향 프로그래밍 도서관 예

객체 지향 프로그래밍

객체, 클래스란

객체

  • 물리적으로 존재하거나, 추상적으로 생각할 수 있는 것 중 자신의 속성을 가지고 있으면서 식별 가능한 것
  • 속성동작으로 구성되며, 각각 필드(Field), 메소드(Method)라 부른다.
  • 현실 세계의 객체 -> 소프트웨어: 객체 모델링
  • 클래스로부터 생성된 객체는 특히 인스턴스(instance)라 한다.

클래스

  • 여러 개의 유사한 객체를 묶는 추상적인 집합 개념으로, 동작, 기능, 속성을 포함

객체 간의 관계

선택 미션의 도서관 비유를 이어나가자면, 도서관을 비롯한 객체들은 서로 관계를 맺는다. 객체들 간의 관계는 총 세 가지가 있는데, 집합 관계, 사용 관계, 상속 관계가 그것이다.

집합 관계는 도서관을 구성하는 (책장, 대출반납기, 책상)와 도서관의 관계,

사용 관계는 이용자가 도서관을 사용하는 관계,

상속 관계는 공공기관 객체에 도서관이 포함되는 상/하위 관계

그림 3. 객체 간의 관계도

 

✔️클래스는 설계도, 객체는 설계도 바탕의 실체

그리고 이러한 책장, 책상, 도서 대출 반납기는 도서관의 규모에 따라 한 개가 있을 수도 있고, 모두 세기 힘들 정도로 많을 수도 있다. 개별 책장과 대출 반납기에 따라 그 기능이 추가되거나 축소되었을 수도 있다. 또한 도서관의 제약 조건을 따르고, 필요에 따라 크기가 제한되기 때문에 설계도를 먼저 구성하고, 그를 바탕으로 실체화 해야한다.

이러한 설계도 역할을 하는 것이 클래스이다! 이전에 봤던 어느 교재에서는 클래스를 붕어빵 틀로, 객체를 붕어빵으로 설명해두었었는데, 나는 클래스가 추상적인 개념이고, 동작, 기능을 내포한다는 점에서 설계도 쪽이 더 명료하게 해석된 것 같다.

클래스 생성

클래스는 별도의 .java 파일을 만들어 생성하는 경우가 대부분이다. 하나의 파일에 여러 개의 클래스를 선언하고 정의할 수도 있지만, 보통 클래스 이름을 파일 이름으로 하는 클래스 하나를 정의한다.

접근 권한은 아직 배우지 않았지만 public 을 먼저 작성하고 class 소문자를 사용한 다음 클래스 이름을 작성한다.

※JAVA는 영문자의 대소문자를 구분하기 때문에 파일 제목을 작성할 때도 구분해주어야 하고, 클래스 이름은 주로 대문자로 시작한다.

클래스는 크게 필드/생성자/메소드로 구성되어 있다. 

 

생성자

  • new 연산자로 호출됨
  • 객체 생성 시 초기화를 담당
  • 메소드 이름이 클래스 이름과 같은 메소드로 생각할 수 있지만 별도로 호출할 수 없고 리턴 타입이 없음

메소드

  • 객체의 동작에 해당
  • 외부에서 값을 받아 실행에 이용하고 리턴하기도 함
  • 객체 내부 필드와 상호작용 할 수도 있음

객체 생성

만들어진 class로부터 객체(instance)를 생성할 수 있다. new 연산자를 통해 생성할 수 있으며, 이 때 '=' 좌측의 변수는 클래스 변수, 우측은 new 연산자를 포함한 객체 생성문이다. Class 변수는 Class이름 변수 이름의 형태로 선언해야 한다.

 

필드

  • 변수와 유사하며 객체의 고유 데이터, 부품 객체, 상태 정보 등을 저장하는 곳(하지만 변수라고 칭하지는 않음)
  • 생성자와 메소드 전체에서 사용됨
  • 객체가 소멸되기 전까지 존재(힙 영역, 객체와 동시에 객체 내부에 생성됨)

주의 사항

  • 클래스 중괄호{} 내부 어디든 필드를 선언할 수 있지만 생성자와 메소드 내부에서 선언하면 로컬 변수(O) 필드(X)
  • 클래스 내에서 필드를 사용할 때엔 별 제약이 없음
  • 초기값이 지정되지 않은 필드는 객체 생성 시 자동으로 기본 초기값으로 설정됨

생성자

  • 생성자는 클래스로부터 객체를 생성할 때 호출되는 함수로, new 연산자로 호출할 수 있음
  • 객체 생성과 동시에 초기화 작업 수행
  • 모든 클래스에는 기본 생성자가 존재
  • 개발자가 직접 생성자를 선언하면 기본 생성자를 사용할 수 없음(그래도 명시된 생성자를 사용하자!) 
  • this()를 사용해 중복되는 생성자 코드를 줄일 수 있음. 내가 원하는 값으로 명시할 수 있는 생성자
    생성자 내부 블럭에서 첫번째 줄에만 사용 가능

메소드

  • 객체의 동작에 해당
  • 외부에서 값을 받아 실행에 이용하고 리턴하기도 함
  • 객체 내부 필드와 상호작용 할 수도 있음

 

🔍궁금한 점

메소드에서 배열을 매개변수로 받을 때 쓸 수 있는 ... 연산자는 어떻게 작성하는 건가요? 그냥 온점을 세 개 찍을 때도, … 기호를 사용해도 문법상 오류가 생겼다고 떠요! 3주차 다른 분들 블로그 보면서 알아가야지🫠

그림 4. 메소드에서 배열을 매개변수로 받는 방법 오류 화면

 

오버로딩

  • 서로 다른 메소드에서 매개변수를 다르게 하여 여러 개의 메소드를 정의하는 것을 의미
  • 리턴 방식이 다르고, 매개변수가 같은 경우에는 오버로딩X

책에서는 예시로 Car 클래스를 선언했는데, 이 때 매개변수를
아무것도 받지 않는 생성자,

차의 종류(자가용, 택시, 버스)를 매개변수로 받는 생성자,

차의 종류색깔을 매개변수로 받는 생성자,

차의 종류색깔, 최고속도를 인자로 받는 생성자를 선언했다.

순서를 다르게 함으로써 오버로딩 할 수도 있지만, 생성자를 사용할 때 헷갈릴 수 있으니 순서는 동일하게 구성하는 것을 추천한다! 

 

++비슷한 이름! 오버로딩, 오버라이딩을 비교해보자면!

오버로딩은 메소드의 이름은 같지만 인수를 받는 자료형과 개수를 달리해 여러 기능을 정의하는 것

오버라이딩은 상위 클래스에서 정의한 메소드와 이름이 같지만 메소드 안의 실행 코드를 자식 클래스에서 재정의할 수 있는 것, 상속을 공부한 뒤에 보면 더 좋을 것 같다.

확인문제

해당 멤버의 필드, 생성자, 메소드 구분

package sec03.exam04;

public class Car {
	// 1. 필드 
	String company = "현대자동차";
	String model;
	
	// 2. 생성자
	Car(){
		
	}
	
	Car(String model){
		this.model = model;
	}
    
	
	// 3. 메소드
	void setModel(String model) {
		this.model = model;
	}
}

this()를 활용해 중복 코드 제거

public class Car {
	String company = "현대자동차";
	String model;
	String color;
	int maxSpeed;

	Car(){
		
	}
	
	Car(String model){
		this(model, "은색", 250);
	}
	
	Car(String model, String color){
		this(model, color, 250);
	}
	
	Car(String model, String color, int maxSpeed){
		this.model = model;
		this.color = color;
		this.maxSpeed = maxSpeed;
	}
}

인스턴스 멤버와 정적 멤버

인스턴스 멤버는 객체마다 가지고 있는 멤버, 정적 멤버는 클래스에서 가지고 있어서 객체마다 설정해줄 필요가 없는 멤버

인스턴스 메소드는 메소드 영역에 생성되는데, 실행 코드블럭이 저장되기 때문에 힙 영역의 객체에 생성될 필요가 없기 때문이다. 다만, 객체가 생성되고, 객체의 필드를 필요로 하는 메소드가 있는 가능성을 바탕으로 인스턴스 메소드라 부른다. 다른 말로 하면 객체의 필드를 필요로 하지 않는 메소드가 정적 메소드가 될 수 있다.

 

정적 멤버

static은 '고정된'이라는 의미로, 객체를 생성하지 않아도 클래스에 고정된 멤버를 의미한다. 정적 필드와 메소드를 선언하려면 선언 시 각각 타입과 리턴 타입 앞에 static을 붙여주면 된다.

정적 멤버는 (클래스.멤버)로 사용할 수 있고, 호출할 수 있다. (객체.멤버)로 사용할 수도 있는데, 이클립스를 사용하면 이 때에는 경고를 띄어준다고 한다.

 

싱글톤

요즘 정보처리기사 자격증 준비를 하고 있는데, 내가 학습한 내용으로는 싱글톤은 하나의 객체를 모든 곳에서 호출할 수 있되, 동시에 호출할 수는 없고 오직 하나의 객체만 사용해 메모리를 줄이는 GoF의 구조패턴 종류 중 하나이다.

교재에서는 싱글톤을 생성하는 방법을 제시한다.

  1. 싱글톤이 되려면 프로그램 전체에서 한 개의 객체만 가지고 있어야 하므로, new 연산자로 생성자를 호출할 수 없도록 막아야 한다.
  2. 외부에서 호출해 객체를 만들 수 없도록 생성자에 private 접근 제한자를 붙여준다.

 

final 필드

  • final 필드는 초기값이 곧 최종값이 되어 변경할 수 없는 필드

final 필드는 어떤 때에 쓰이면 좋을까? 수정되면 안 되는 값을 저장할 때 쓰면 좋을 것 같다. 상수는 static 기능에 final 기능이 추가되어 불변의 값을 선언하기 위해 사용된다. 객체마다 저장할 필요가 없는 필드이다.

패키지와 접근 제한자

패키지

  • 클래스를 포함하는 역할
  • 파일 시스템 폴더이며 클래스를 유일하게 만들어주는 식별자 역할 수행

패키지가 상하위로 구분되어 있다면 도트로 표현할 수 있다(상위패키지.하위패키지.클래스)

import문으로 기존에 만들어진 클래스와 패키지를 사용할 수 있다.

 

접근 제한은 다음과 같은 수준으로 이루어진다.

그림 5. 접근제한자 수준 다이어그램

public: 다른 패키지에서도 자유롭게 해당 클래스에 접근할 수 있다.

protected: public에서 하위 클래스를 제외한 다른 패키지 접근이 제한된다. = 다른 패키지에서는 하위 클래스만 접근 가능

default: protected에서 다른 패키지에 위치한 하위 클래스의 접근이 제한된다. = 동일 패키지 내에서만 접근 가능

private: default에서 동일 패키지 내부에서의 접근이 제한된다. = 동일 클래스 내에서만 접근 가능

이렇기 때문에 생성자에 private 접근 제한자를 걸어주면 클래스 외부에서 객체를 생성할 수 없게 된다.

후기

2주차에 올려주신 글들도 열심히 보고 참고했다! 작성할 때는 몰랐는데, 내 블로그엔 글이 너무 많았다! 정리가 하나도 안 되는 기분이라 다시 볼 때 한 눈에 볼 수 있게끔 정리해야지~ 하고 이번주는 많이 의식해서 적은 것 같다. 이전보다 내용이 눈에 잘 들어오고, 정리가 잘 된 느낌을 받을 수 있어 만족한다! 앞으로는 이런 양상의 글을 많이 적을 것 같다. 다만, 문제가 하나 있는데 글자 크기가 왔다갔다 한다는 거... 스킨 설정이 잘못 된 것 같다😂 읽기 불편할텐데 읽어주시는 분들 다들 감사합니다! 혼공 족장님 2주차 우수혼공족 선물 잘 받았습니다❤️~ 맛있게 먹고 열심히 공부할게요! 추운 겨울, 함께 건강하게 보내요! 건강 최고!