CS/객체지향프로그래밍

[객체지향프로그래밍] #4 클래스와 객체

taeyeoxn 2024. 4. 21. 16:09

<생성자>

 

생성자는 객체가 생성될 때 객체의 초기화를 위해 실행되는 메소드이다.

 

• 생성자의 특징

  • 생성자의 이름은 클래스 이름과 동일하다.
public class Circle {
   public Circle(int r, String n) { ... } // 생성자
}
  • 생성자는 여러개 작성(오버로딩)할 수 있다.
public class Circle {
    public Circle() {...} // 매개 변수가 없는 생성자
    public Circle(int r, String n) {...} // 2개의 매개 변수를 가진 생성자
}
  • 생성자는 new를 통해 객체를 생성할 때 한번만 호출된다.
Circle pizza = new Circle(10, "자바피자"); // 생성자 Circle(int r, String n)
Circle donunt = new Circle(); // 생성자 Circle() 호출
  • 생성자에 리턴 타입을 지정할 수 없다.
public Circle() {...} // 리턴 타입 선언하지 않음
public void Circle() {...} // 오류. void를 리턴 타입으로 사용할 수 없음
  • 생성자의 목적은 객체가 생성될 때, 필요한 초기화 작업을 하기 위함이다.
Circle pizza = new Circle(10, "자바피자"); // 생성자 Circle(int r, String n) 호출

 

기본 생성자(디폴트 생성자)

매개변수와 실행 코드가 없어 아무 일도 하지 않고 단순 리턴하는 생성자이다.

class Circle {
   public Circle() { } // 기본 생성자. 매개변수 없고 아무 일 없이 단순 리턴
}

 

객체가 생성될 때 반드시 생성자가 실행되기 때문에 생성자가 없는 클래스는 있을 수 없다.

따라서 생성자가 하나도 없는 경우, 컴파일러는 기본 생성자를 자동으로 생성한다.

 

기본 생성자가 자동 생성되지 않는 경우

개발자가 클래스에 생성자를 하나라도 작성한 경우에는 기본 생성자가 자동 삽입되지 않는다.

 

this 래퍼런스

this는 현재 객체 자신에 대한 레퍼런스이다.

컴파일러에 의해 자동 관리되므로 개발자는 사용하기만 하면 된다.

public clas Circle {
   int radius;
   public Circle(int r) { this.radius = r; } // 현재 객체의 멤버 radius를 접근한다.
   public int getRadius() { return radius; }

 

이 코드에서 메소드 getRadius()는 this를 사용하지 않았다.

클래스 내에서 멤버 radius를 접근할 때 굳이 this.radius로 할 필요가 없다.

 

그렇다면 this는 언제 필요할까?

 

this가 필요한 경우

  • 객체의 멤버 변수와 메소드 변수의 이름이 같은 경우
  • 다른 메소드 호출 시 객체 자신의 레퍼런스를 전달할 때
  • 메소드가 객체 자신의 레퍼런스를 반환할 때

객체 속에서의 this

 

이 코드에서 main()은 3개의 Circle 객체를 생성한다. 

ob1, ob2, ob3 객체에서 this는 각각 자기가 속한 객체에 대한 레퍼런스이다.

예를 들어, ob1.set()이 실행될 때 this는 ob1 객체에 대한 레퍼런스인 것이다.

 

< 메소드>

 

메소드

메소드는 클래스의 멤버 함수로서 메소드 앞에 접근 지정자를 선언한다는 점만 제외하면 C/C++의 함수 작성법과 동일하다.

자바의 모든 메소드는 반드시 클래스 안에 있어야 한다.(캡슐화 원칙)

 

메소드 구성 형식

- 접근 지정자

public, private, protected, 디폴트(접근 지정자가 생략된 경우)

- 리턴 타입

메소드가 반환하는 값의 데이터 타입

 

인자 전달
자바에서는 메서드나 생성자에 매개변수(파라미터)를 사용하여 인자를 전달한다.


경우 1. 기본 타입의 값 전달
값이 복사되어 전달된다.
메소드의 매개변수가 변경되어도 호출한 실인자 값은 변경되지 않는다.

 

코드의 실행 과정을 알아보자.

우선 변수 n에 저장된 값 10을 increase() 메소드에 전달한다.

int n = 10;
increase(n);

 

 

increase(int m) 메소드가 호출되면, 매개변수 m이 생성되고 10으로 초기화된다.

그러고 나서 m 값을 1 증가시킨다.

increae()에서 리턴하여 main() 메소드로 돌아오면 변수 n 값은 여전히 10으로 남아 있다.

 

경우 2. 객체 혹은 배열 전달

객체나 배열의 레퍼런스만 전달한다.

메소드의 매개변수와 호출한 실인자 객체나 배열을 공유한다.

객체만 전달되는 경우
배열만 전달되는 경우

 

주의할 점은 자바에서 메소드의 매개변수로 객체나 배열을 전달할 때 레퍼런스만 전달하기 때문에 객체나 배열이 통째로 넘어가지 않는다는 것이다.

 

메소드 오버로딩

한 클래스 내에 이름이 같지만 매개변수의 타입이나 개수가 서로 다른 여러 개의 메소드를 중복 작성할 수 있는데, 이를 메소드 오버로딩이라고 한다. 

 

조건

  • 메소드 이름이 동일해야 한다.
  • 매개변수의 개수나 타입이 서로 달라야 한다.

 

<가비지 컬렉션> 

 

• 가비지

가비지란 자바 응용프로그램에서 더 이상 사용하지 않게 된 객체나 배열 메모리이다.

 

• 가비지의 발생

 

• 가비지 컬렉션

가비지가 많아지면 자바 플랫폼이 응용프로그램에게 할당해줄 수 있는 가용 메모리 양이 줄어들게 되기 때문에 가비지를 회수하여 가용 메모리를 늘려야 한다.

System.gc(); // 가비지 컬렉션 강제 요청

 

 

<접근 지정자>

 

자바에는 4가지 접근 지정자가 있다.
: private, protected, public, 디폴트(접근지정자 생략)

 

접근 지정자의 목적

클래스나 일부 멤버를 공개하여 다른 클래스에서 접근하도록 허용한다.

객체 지향 언어의 캡슐화 정책은 멤버를 보호하는 것인데, 접근 지정은 캡슐화에 묶인 보호를 일부 해제할 목적이다.

 

접근 지정자에 따른 클래스나 멤버의 공개 범위 

 

클래스 접근 지정

다른 클래스에서 이 클래스를 활용할 수 있는지 허용 여부를 지정하는 것이다.

 

• public 클래스

패키지에 상관없이 다른 어떤 클래스에게도 사용이 허용된다.

public class World { // public 클래스
   ···········
}

 

다른 클래스에서 world 클래스의 객체를 생성하는 등 활용할 수 있다. 

 

• 디폴트 클래스(접근 지정자 생략)

접근 지정자 없이 클래스를 선언한 경우, 디폴트 접근 지정으로 선언되었다고 한다.

class Local { // 디폴트 클래스
  ············
}

 

클래스 Local을 디폴트 클래스로 선언한 것이다.

디폴트 클래스는 같은 패키지 내의 클래스들에게만 사용이 허용된다.

 

멤버 접근 지정

클래스 멤버에 대한 접근 지정을 알아보도록 하자.

 

• public 멤버

모든 클래스들의 접근이 허용된다.

 

• private 멤버 

비공개를 지시하는 것으로 클래스 내의 멤버들에게만 접근이 허용된다.

 

• protected 멤버

보호된 공개를 지시하는 것으로 같은 패키지의 모든 클래스와 지식 클래스의 접근이 허용된다.

 

• 디폴트 멤버

동일한 패키지 내에 있는 클래스들만 접근이 허용된다.