본문 바로가기
JAVA

CH04. 객체지향, 클래스와 객체, 변수와 메서드, 오버로딩, 생성자, this레퍼런스, 변수 초기화

by MINNI_ 2021. 4. 29.

[ CH04. 객체지향개념 ]

 

1. 객체 지향 

1.1 객체 지향 언어 개념

  • 객체 정의
    - 클래스의 모양 그대로 찍어낸 실체
    - 객체마다 고유한 특성(state)과 행동(behavior)을 가짐
    - 다른 객체들과 상호작용
  • 객체 지향 언어 목적
    - 소프트웨어의 생산성 향상 : sw 생명주기 단축, 객체 지향 언어
    - 실세계에 대한 쉬운 모델링
  • 절차 지향 프로그래밍 vs 객체 지향 프로그래밍
    - 절차 지향 프로그래밍
       - 작업 순서 표현
       - 작업을 함수로 작성한 함수들의 집합
    - 객체 지향 프로그래밍
       - 객체들간의 상호작용 표현
       - 클래스 혹은 객체들의 집합으로 프로그램 작성

1.2 객체 지향 특성

  • 1) 캡슐화
    - 객체를 캡슐(클래스)로 싸서 내부를 볼 수 없게 하는 것
    - 외부의 접근으로부터 객체 보호

  • 2) 상속
    - 자식 클래스가 부모 클래스의 속성을 물려받고, 기능 확장
       - 부모 클래스: 슈퍼 클래스
       - 자식 클래스: 서브 클래스, 슈퍼 클러스를 재사용하고 새로운 특성 추가 가능
    - 다중상속 X (cf. 인터페이스 : 다중 상속 O)

  • 3) 다형성
    - 같은 이름의 메소드가 클래스나 객체에 따라 다르게 동작하도록 구현
       - 메소드 오버로딩 : 같은 이름이지만 다르게 작동하는 여러 메소드
       - 메소드 오버라이딩 : 슈퍼클래스의 메소드를 서브 클래스마다 다르게 구현

 


2. 클래스와 객체

2.1 클래스

  • 정의
    - 객체를 만들어내기 위한 설계도 혹은 틀
    - 메소드(멤버 함수)와 필드(멤버 변수)는 모두 클래스 내에 구현
  • 구성
    - 클래스 선언
       - class 키워드로 선언
       - 모든 필드와 메소드 구현
    - 접근 권한
       - public: 어디서나 마음대로 접근 호출 가능
       - default: 동일한 패키지만 접근 호출 가능
    - 필드와 메소드
       - 필드(field): 객체 내에 값을 저장하는 멤버 변수
       - 메소드(method): 함수이며, 객체의 행동(행위)을 구현
    - 필드, 메소드의 접근 지정자
       - 필드나 메소드 앞에 붙어 다른 클래스의 접근 허용을 표시
    - 생성자
       - 클래스의 이름과 동일한 메소드
       - 객체가 생성될 때 자동으로 한 번 호출되는 메소드

2.2 객체(=인스턴스)

  • 개념
    - 클래스의 모양 그대로 찍어낸 실체, 메모리 공간을 갖는 구체적인 실체
    - 필드(멤버 변수)와 메소드(멤버 함수)으로 구성
    - 클래스의 접근지정자를 통해 객체 내 데이터에 대한 보호, 외부 접근 제한
       - 객체 외부에서 비공개 멤버(필드, 메소드)에 직접 접근 X → 공개된 메소드를 통해 비공개 멤버 접근 O
  • 클래스와 객체와의 관계
    - 예시:
             클래스: 소나타자동차 → 객체: 출고된 실제 소나타 100
             클래스: 사람 → 객체: , , 윗집사람, 아랫집사람
             클래스: 붕어빵틀 → 객체: 구워낸 붕어빵들
  • 객체 생성
    - 클래스명 참조변수명;               // 객체에 대한 참조 변수 선언
    - 참조변수명 = new 클래스명();    //  new 키워드 이용하여 객체 생성
       - new는 객체의 생성자 호출
       - 클래스 타입 크기의 메모리 할당
  • 객체의 멤버 접근
    - 객체 레퍼런스.멤버

public class Circle {

	int radius;
	String name;
	
	public Circle() {}
	
	public double getArea() {
		return 3.14*radius*radius;
	}
	
	public static void main(String[] args) {
		
		Circle pizza;
		pizza = new Circle();
		pizza.radius = 10;
		pizza.name = "자바 피자";
		double area = pizza.getArea();
		System.out.println(pizza.name + "의 면적은 " + area);
		
		Circle donut;
		donut = new Circle();
		donut.radius = 2;
		donut.name = "자바 도넛";
		area = donut.getArea();
		System.out.println(donut.name + "의 면적은 " + area);	
	}
}
  • 객체의 치환
    - 객체가 복사되는 것이 아닌 레퍼런스가 복사되는 것

2.3 객체 소멸과 가비지 컬렉션

  • 객체 소멸
    - new에 의해 할당된 객체 메모리를 자바 가상 기계의 가용 메모리로 되돌려 주는 행위
    - 자바 응용프로그램에서 임의로 객체를 소멸할 수 없음
       - 개발자가 할당받은 객체를 직접 되돌려 주지 않아도 됨
  • 가비지
    - 가리키는 레퍼런스가 하나도 없는 객체

  • 가비지 컬렉션
    - 자바 가상 기계의 가비지 컬렉터 스레드가 자동으로 가비지를 자동 회수하는 과정 (-> 가용 메모리로 반환)
    - 개발자에 의한 강제 가비지 컬렉션
       - System 또는 Runtime 객체의 gc() 메소드 호출
       - 자바 가상 기계에 강력한 가비지 컬렉션 요청
System.gc(); // 가비지 컬렉션 자동 요청

2.4 객체 배열

  • 개념
    - 참조변수들을 하나로 묶은 참조 변수 배열
    - 객체 배열안에 객체의 주소 저장
  • 생성 및 사용, 초기화
// 참조변수 배열(객체배열) 생성 : Circle 배열에 대한 참조 변수 c 선언
Circle[] c = new Circle[5];

// 객체배열의 각 요소에 객체 생성
for(int i=0; i<c.length; i++){
	c[i] = new Circle(i); // 배열의 각 원소 객체 생성
    System.out.println((int)(c[i].getArea()) + " "); // 배열의 원소 객체 사용
}

// 객체 배열 초기화
Circle[] c[] = { new Circle(1), new Circle(2), new Circle(3) };

3. 변수와 메서드

3.1 선언 위치에 따른 변수의 종류

  • 변수의 선언 위치가 변수의 종류와 범위 결정

  • 1) 클래스 변수(class variable)
    - 같은 클래스모든 인스턴스들이 공유하는 변수. 하나의 저장공간 공유
    - 인스턴스 생성없이 '클래스이름.클래스변수명'으로 접근
    - 클래스가 로딩될 때 생성되고, 프로그램이 종료될 때 소멸
  • 2) 인스턴스 변수(instance variable)
    - 각 인스턴스의 개별적인 저장공간. 인스턴스마다 다른 값 저장 가능
    - 인스턴스 생성 수, '참조변수.인스턴스변수명'으로 접근
    - 인스턴스를 생성할 때 생성되고, 참조변수가 없을 때 가비지컬렉터에 의해 자동 제거
  • 3) 지역 변수(local varialbe)
    - 메서드 내에 선언, 메서드의 종료와 함께 소멸
    - 조건문, 반복문의 블록{}내에 선언된 지역변수는 블록을 벗어나면 소멸

3.2 메서드(method)

  • 정의
    - 클래스의 멤버 함수
    - 작업을 수행하기 위한 명령문의 집합
    - 입력값을 받아 처리하고 그 결과 반환
       - 입력값이 없을 수도 반환값이 없을 수도 있음
  • 작성지침
    - 반복적으로 수행되는 여러 문장을 메서드로 작성
    - 하나의 메서드는 한 가지 기능만 수행하도록 작성하는 것이 좋음
  • 메서드 선언부 구성
    - 클래스 영역 안에서만 정의 가능
    - 접근 지정자
       - public, private, protected, default(접근 지정자 생략)
    - 리턴 타입
       - 메소드가 반환하는 값의 데이터 타입
       - 반환값이 없는 경우 리턴 타입으로 void 사용
    - 메서드 이름
       - 변수의 명명규칙 따름
       - 메서드의 기능을 나타내는 함축적 이름 사용
    - 메서드의 매개변수
       - 메서드에 필요한 값을 제공하기 위한 변수
       - 매개변수 여러개 → 쉼표','로 연결, 변수의 타입 같아도 변수의 타입 생략 X
         매개변수 X → 입력받을 값 없다면, 없어도 됨

  • 메서드 구현부 구성
    - 메서드 구현부 : 괄호{} 안에 메서드 호출시 수행할 메서드 코드
    - return문
       - 현재 실행중인 메서드를 종료하고, 호출한 메서드로 돌아가 반환값 전달
       - 리턴타입이 void → return 생략 O
         리턴타입이 void X → return 반환값
       - 리턴타입과 반환값의 타입이 일치하거나, 자동 형변환이 가능한 것이어야 함
    - 지역변수(local variable)
       - 메서드 내에 선언된 변수
       - 메서드 내에서만 사용 가능 O
       - 서로 다른 메서드라면, 같은 이름의 변수 선언 가능 O
       - 매개변수도 지역변수

3.3 메서드 호출

  • 서드 호출 ⇒ 구현부의 문장들 수행
  • 메서드 호출 시, 인자와 매개변수
    - 인자의 개수와 순서는 호출된 메서드의 매개변수와 일치해야 함
    - 인자의 타입은 매개변수의 타입과 일치하거나 자동 형변환이 가능한 형태
int add(int a, int b) {
		int result = a + b;
		return result;
}

int result = add(1,2,3) // ERROR: 선언된 매개변수와 갯수 다름
int result = add(1.0, 2.0) // ERROR: 선언된 매개변수와 타입이 다름, 자동 형변환도 X
  • 메서드 호출 방법

  • 메서드 실행흐름
    1) 메서드 호출시 지정한 인자를 호출된 메서드의 매개변수에 각각 복사(대입)
    2) 메서드의 구현부의 문장들을 순서대로 수행
    3) 메서드의 모든 문장이 실행되거나 return문 만나면, 호출한 메서드로 되돌아와서 이후의 문장들 실행

3.4 return문

  • 개념
    - 현재 실행중인 메서드를 종료하고, 호출한 메서드로 돌아가 반환값 전달
    - 리턴타입이 void → return; 또는 return 생략 O (컴파일러가 자동으로 return; 추가)
      리턴타입이 void X → return 반환값
    - 리턴타입과 반환값의 타입이 일치하거나, 자동 형변환이 가능한 것이어야 함
    - 반환값이 있는 메서드 → 모든 경우에 return문 존재해야 함

  • 반환값
    - 변수, 수식(수식 계산값이 반환), 메서드(메서드의 결과값 반환), 조건연산자 등 사용가능
  • 메서드 정삭적으로 종료되는 경우
       - 메서드의 블록{} 끝에 도달
       - 메서드의 블록{}을 수행 도중 return문을 만났을 때
  • 매개변수의 유효성 검사 → 값 보정 또는 보정 불가시 return을 통해 종료시킴

3.5 JVM의 메모리 구조

  • 메서드 영역(Method Area)
    - 클래스 정보와 클래스 변수 저장
  • 호출스택(Call Strack)
    - 메서드의 작업공간
    - 메서드 호출시, 메서드 수행에 필요한 메모리공간을 할당받고, 종료되면 사용한 메모리 자동 반환
    - 제일 위에 있는 메서드가 현재 실행중인 메서드
      아래에 있는 메서드가 바로 위의 메서드를 호출한 메서드
    - 메서드에서 선언된 지역변수가 호출스택에 생성

  • 힙(Heap)
    - 인스턴스가 생성되는 공간
    - new연산자에 의해 생성되는 배열과 객체가 힙에 생성 (인스턴스변수 생성)

3.6 인자 전달 방식

  • 1) 기본 타입의 값 전달
    - 값이 복사되어 전달
    - 메소드의 매개변수가 변경되어도 호출한 실인자 값은 변경 X (변수의 값 읽기만 가능)

  • 2) 참조형 타입의 주소값 전달
    - 객체나 배열의 레퍼런스 전달
       - 객체 혹은 배열이 통째로 복사되어 전달되는 것 X
    - 메소드의 매개변수와 호출한 실인자 객체나 배열 공유(변수의 값 읽고 변경 가능)

3.7 재귀호출(recursive call)

  • 개념
    - 메서드 내에서 자기자신을 반복적으로 호출
    - 반복문보다 성능이 나쁨
    - 간결한 코드 작성 가능
long factorial(int n) {
	long result = 0;
	if(n==1) {
		result = 1;
	} else {
		result = n * factorial(n-1);
	}
	return result;
}

3.8 클래스메서드(static 메서드)와 인스턴스메서드

  • 클래스 멤버(static 멤버) vs 인스턴스 멤버(non-static 멤버)

  • static 멤버 접근
    - 객체의 멤버로 접근
       - 객체 래퍼런스 변수.static 멤버
    - 클래스 이름으로 접근
       - 클래스 이름.static 멤버

 

  • non-static 멤버 접근
    - 인스턴스 생성 후, '참조변수.메서드이름()'으로 호출

class MyMath2 {
	long a, b;
	
	long add() {	// 인스턴스메서드
		return a + b;
	}

	static long add(long a, long b) { // 클래스메서드(static메서드)
		return a + b;
	}
}

class MyMathTest2 {
	public static void main(String args[]) {
		System.out.println(MyMath2.add(200L,100L); // 클래스메서드 호출
		MyMath2 mm = new MyMath2(); // 인스턴스 생성
		mm.a = 200L;
		mm.b = 100L;
		System.out.println(mm.add()); // 인스턴스메서드 호출
	}
}

 

  • static 멤버 활용
    1) 전역 변수와 전역 함수를 만들 때 활용
       - 전역 변수나 전역 함수는 static으로 클래스에 작성
       - ex) Math 클래스: java.lang.Math  // 모든 필드와 메소드가 public static으로 선언
                                                    // 다른 모든 클래스에서 사용 가능
    2) 공유 멤버를 작성
       - static 필드나 메소드는 하나만 생성, 클래스의 객체들 공유

  • static 메소드의 제약 조건 (1)
    - static 메소드는 non-static 멤버 접근 X
       - 객체가 생성되지 않은 상황에서 static 메소드는 실행될 수 있기 때문에 non-static 메소드와 필드 사용 불가
    - non-static 메소드는 static 멤버 사용 O

  • static 메소드의 제약조건 (2)
    - static 메소드는 this 사용 불가
       - 현재 객체를 가리키는 this 레퍼런스는 객체가 생성되지 않은 상황에서도 호출이 가능한 static 메소드에서는 사용불가

3.9 클래스 멤버와 인스턴스 멤버간의 참조와 호출

  • static멤버는 인스턴스멤버 호출 가능 X
  • 인스턴스멤버는 클래스멤버와 인스턴스멤버 모두 호출 가능 O 


4. 메서드 오버로딩(method overloading)

  • 정의
    - 하나의 클래스에 같은 이름의 메서드를 여러 개 정의
  • 조건
    -
    메서드의 이름이 같아야 함
    -
    매개변수의 개수나 타입이 달라야 함
    - 리턴 타입은 오버로딩과 관련 X


5. 생성자

  • 정의
    - 객체가 생성될 때 초기화를 위해 실행되는 메소드
  • 특징
    - 생성자는 메소드
    - 생성자 이름은 클래스 이름과 반드시 동일
    - 여러 개 작성 가능(오버 로딩)
    - new를 통해 객체를 생성할 때, 객체당 한 번 호출
    - 리턴 타입 지정 X
    - 목적: 객체 초기화
    - 객체가 생성될 때 반드시 호출됨
       - 생성자 미선언시, 자동으로 기본 생성자 삽입

5.1 기본 생성자(default constructor)

  • 정의
    - 매개 변수가 없는 생성자
    - 디폴트 생성자라고도 부름
  • 특징
    - 클래스에서 생성자가 하나도 선언되지 않은 경우, 컴파일러에 의해 기본 생성자 자동 삽입
    - 생성자가 하나라도 작성한 경우, 기본 생성자가 자동으로 삽입되지 X

5.2 매개변수가 있는 생성자


6. this 레퍼런스

  • 정의
    - 객체 자신에 대한 참조변수. 객체 주소가 저장
       - 컴파일러에 의해 자동 관리
  • 필요성
    - 객체의 멤버 변수와 메소드 변수의 이름이 같은 경우
    - 다른 메소드 호출 시 객체 자신의 레퍼런스를 전달할 때
    - 메소드가 객체 자신의 레퍼런스를 반환할 때

 

  • this()
    - 같은 클래스 내의 다른 생성자 호출
    - 생성자 내에서만 사용 가능
    - 반드시 생성자 코드의 첫 문장에서만 수행
public class Book2 {
	
	String title;
	String author;
	
	public Book2() { // 생성자
		this("", "");
	}
	
	public Book2(String title) { // 생성자
		this(title, "작자미상");
	}
	
	public Book2(String title, String author) { // 생성자
		this.title = title;
		this.author = author;
	}
	
	void show() {
		System.out.println(title + " " + author);
	}

	public static void main(String[] args) {

		Book2 littlePrice = new Book2("어린왕자", "생텍쥐페리");
		Book2 loveStory = new Book2("춘향전");
		Book2 emptyBook = new Book2();
		
		littlePrice.show();
		loveStory.show();
		emptyBook.show();
	}
}

// [ 출력 ]
// 어린왕자 생텍쥐페리
// 춘향전 작자미상
  • 생성자를 이용한 인스턴스 복사
    - 인스턴스 간의 차이는 인스턴스 변수의 값만 다름
    - 생성자에서 참조변수를 매개변수로 받아 인스턴스변수들의 값을 복사


7. 변수의 초기화

7.1 변수의 초기화 정의

  • 변수를 선언하고, 처음으로 값을 저장
  • 멤버변수(클래스 변수, 인스턴스 변수)와 배열은 각 타입의 기본값으로 자동초기화 → 초기화 생략 O
  • 지역변수는 사용전에 초기화 필수!!

7.2 멤버변수의 초기화

  • 명시적 초기화(explicit initialization)

  • 생성자

  • 초기화 블럭(initialization block)
    - 인스턴스 초기화 블럭 : {}
    - 클래스 초기화 블럭 : static {}

7.3 초기화 블럭(initialization block)

  • 클래스 초기화 블럭
    - 클래스 변수의 복잡한 초기화에 사용
    - 클래스가 로딩될 때 한 번만 실행(클래스 로딩 → 클래스 변수 생성 → 클래스 초기화)

  • 인스턴스 초기화 블럭
    - 생성자에서 공통적으로 수행되는 작업에 사용
    - 인스턴스가 생성될 때마다 실행 (생성자보다 먼저 실행)

7.4 멤버변수의 초기화 시기와 순서

  • 클래스변수 초기화 시점 : 클래스가 처음 로딩될 때 단 한번
  • 인스턴스 초기화 시점 : 인스턴스가 생성될 때 마다


[ 참조 ]

1. Java의 정석 3판 (지은이 : 남궁성)

2. 명품 JAVA Programming 개정 3판 (지은이 : 황기태, 김효수) 

댓글