목차
생성자와 접근제어
- 생성자
- 정적 변수
- 정적 메소드
- 접근제어
- this
- 클래스간의 관계
객체가 생성될 때 초기화를 담당하는 생성자에 대하여 알아보자.
생성자
- 생성자(contructor) : 객체가 생성될 때에 필드에게 초기값을 제공하고 필요한 초기화 절차를 실행하는 메소드
생성자의 예
class Car {
private String color; // 색상
private int speed; // 속도
private int gear; // 기어
// 첫 번째 생성자
public Car(String c, int s, int g) {
color = c;
speed = s;
gear = g;
}
// 두 번째 생성자
public Car() {
color = "red";
speed = 0;
gear = 1;
}
}
public class CarTest {
public static void main(String args[]) {
Car c1 = new Car("blue", 100, 0); // 첫번째 생성자 호출
Car c2 = new Car(); // 두번째 생성자 호출
- 위의 방식처럼 생성자는 객체를 만들 때 파라미터의 값으로 필드를 초기화를 하거나, 아무것도 입력되지 않으면 기본값으로 초기화 시킬 수도 있다.
디폴트 생성자
- 만약 클래스 작성 시 생성자를 하나도 만들지 않는 경우에는 자바 컴파일러가 자동적으로 메소드의 몸체 부분이 비어있는 생성자를 만들어준다.
→ 단, 생성자가 하나라도 정의가 되어 있으면 디폴트 생성자는 자동으로 만들어 지지 않는다.
- 만약 인수를 받는 생성자를 정의하면 인수가 비어져 있는 디폴트 생성자 ( )도 같이 정의를 해줘야한다.
생성자에서 메소드 호출
- this( ) 는 자기 자신의 생성자를 호출한다.
class Car {
private String color; // 색상
private int speed; // 속도
private int gear; // 기어
// 첫 번째 생성자
public Car(String c, int s, int g) {
color = c;
speed = s;
gear = g;
}
// 두 번째 생성자
public Car() {
this(c, 0, 1);
}
}
정적 변수와 인스턴스 변수
- 인스턴스 변수(instance variable) : 객체마다 하나씩 있는 변수 - 해당 클래스의 각 객체마다 따로 가지고 있다.
- 정적 변수(static variable) : 모든 객체를 통틀어서 하나만 있는 변수 - 해당 클래스의 모든 객체들이 서로 공유한다. 사용 예 : 객체를 만든 횟수, 시리얼 넘버 등
정적 변수의 예
public class Car {
private String color;
private int speed;
private int gear;
// 자동차의 시리얼 번호
private int id;
private static int numberOfCars = 0; // 정적 변수
public Car(String c, int s, int g) {
color = c; speed = s; gear = g;
id = ++numberOfCars;
}
}
class People {
private static int count;
public People() { ++count;// 호출 될 때 정적 변수 증가 }
protected void finalize() { // 객체가 소멸될 때 호출된다.
count--; // 객체 하나가 줄어 들 기 때문에 정적변수 count를 감소
}
}
정적 변수를 외부에서 사용할 때
- “클래스이름.정적변수명” 형식을 사용한다.
int n = Car.numberOfCars;
상수
- 상수는 공간을 절약하기 위하여 자동으로 정적 변수로 선언이 된다.
public class Car {
static final int MAX_SPEED = 350;
}
정적 메소드
- 정적 메소드(static method) : 객체를 생성하지 않고 사용할 수 있는 메소드
- (예) Math 클래스에 들어 있는 각종 수학 메소드 들
double value = Math.sqrt(9.0);
정적 메소드 예
public class Car {
private String color;
private int speed;
private int gear;
// 자동차의 시리얼 번호
private int id;
private static int numberOfCars = 0; // 정적 변수
public Car(String c, int s, int g) {
color = c; speed = s; gear = g;
id = ++numberOfCars;
}
public Car() { this(init, 0, 0); }
// 정적 메소드
public static int getNumberOfCars() { return numberOfCars; }
}
- 정적 메소드에서는 인스턴스 변수와 인스턴스 메소드에 접근할 수 없다.
→ 왜냐하면 정적 메소드는 해당 클래스 정의 부분을 만나면서 메모리 상에 올라 가는데 아직 객체를 만들지 않은 상태이기에 인스턴스 변수나 필드가 없다. 추 후 객체를 만들었다고 해서 어떠한 인스턴스 객체와도 연결되지 않기 때문에 접근 불가능
중간 점검
- 정적 변수는 어떤 경우에 사용하면 좋은가?
- PI(파이) 처럼 절대 바뀌지않는 경우, 시리얼넘버 같은 경우
- 정적 변수나 정적 메소드를 사용할 때, 클래스 이름을 통하여 접근하는 이유는?
- 어느 특정 인스턴스 객체에 속한게 아니기에.
- main( ) 안에서 인스턴스 메소드를 호출할 수 없는 이유는?
- main도 정적 메소드이기때문
접근 제어
- 접근 제어(access control) : 다른 클래스가 특정한 필드나 메소드에 접근하는 것을 제어하는 것
접근 제어의 종류
- 클래스 수준에서의 접근 제어
- 멤버 수준에서의 접근 제어
클래스 수준에서의 접근 제어
- public : 다른 모든 클래스가 사용할 수 있는 공용 클래스
- Package : 수식자가 없으면 : 같은 패키지 안에 있는 클래스들만이 사용
멤버 수준에서의 접근 제어
this 참조
- 자기 자신을 참조하는 키워드이다.
private int speed;
public void setSpeed(int speed) {
this.speed = speed;
}
- 필드의 이름과 매개변수의 이름이 같다. 이때 대입연산(=) 은 가장 가까운 곳에 대입 되는 경우가 있다. 그러므로 명시적으로 자기 자신(객체)의 speed 필드라고 명시한 것.
- 생성자를 호출할 때도 사용된다.
클래스와 클래스 간의 관계
- 사용(use): 하나의 클래스가 다른 클래스를 사용한다.
- 집합(has-a): 하나의 클래스가 다른 클래스를 포함한다.
- 상속(is-a): 하나의 클래스가 다른 클래스를 상속한다.
사용 관계
- 클래스 A의 메소드에서 클래스 B의 메소드들을 호출한다.
public class Complex { // 복소수를 표현하는 클래스
private double real;
private double imag;
public Complex(double r, double i) {
real = r;
imag = i;
}
...
double getReal() {
return real;
}
double getImag() {
return imag;
}
// 객체 참조 값을 매개변수로 받는다.
public Complex add(Complex c) {
double resultReal = real + c.getReal();
double resultImag = real + c.getImag();
return new Complex(resultReal, resultImag); // 객체가 생성되고 객체의 참조값이 반환된다.
}
}
집합 관계
class Time {
private int time;
private int minute;
private int second;
public Time(int t, int m, int s) {
time = t;
minute = m;
second = s;
}
}
public class AlarmClock {
private Time currentTime; // Time 객체가 포함된다
private Time alarmTime; // (has - a 관계)
public AlarmClock(Time a, Time c) {
alarmTime = a;
currentTime = c;
}
}
public class AlarmClockTest {
public static void main(String args[]) {
Time alarm = new Time(6, 0, 0);
Time current = new Time(12, 56, 34);
AlarmClock c = new AlarmClock(alarm, current);
System.out.println(c);
}
}
생성자와 접근제어
- 생성자
- 정적 변수
- 정적 메소드
- 접근제어
- this
- 클래스간의 관계
객체가 생성될 때 초기화를 담당하는 생성자에 대하여 알아보자.
생성자
- 생성자(contructor) : 객체가 생성될 때에 필드에게 초기값을 제공하고 필요한 초기화 절차를 실행하는 메소드
생성자의 예
class Car {
private String color; // 색상
private int speed; // 속도
private int gear; // 기어
// 첫 번째 생성자
public Car(String c, int s, int g) {
color = c;
speed = s;
gear = g;
}
// 두 번째 생성자
public Car() {
color = "red";
speed = 0;
gear = 1;
}
}
public class CarTest {
public static void main(String args[]) {
Car c1 = new Car("blue", 100, 0); // 첫번째 생성자 호출
Car c2 = new Car(); // 두번째 생성자 호출
- 위의 방식처럼 생성자는 객체를 만들 때 파라미터의 값으로 필드를 초기화를 하거나, 아무것도 입력되지 않으면 기본값으로 초기화 시킬 수도 있다.
디폴트 생성자
- 만약 클래스 작성 시 생성자를 하나도 만들지 않는 경우에는 자바 컴파일러가 자동적으로 메소드의 몸체 부분이 비어있는 생성자를 만들어준다.
→ 단, 생성자가 하나라도 정의가 되어 있으면 디폴트 생성자는 자동으로 만들어 지지 않는다.
- 만약 인수를 받는 생성자를 정의하면 인수가 비어져 있는 디폴트 생성자 ( )도 같이 정의를 해줘야한다.
생성자에서 메소드 호출
- this( ) 는 자기 자신의 생성자를 호출한다.
class Car {
private String color; // 색상
private int speed; // 속도
private int gear; // 기어
// 첫 번째 생성자
public Car(String c, int s, int g) {
color = c;
speed = s;
gear = g;
}
// 두 번째 생성자
public Car() {
this(c, 0, 1);
}
}
정적 변수와 인스턴스 변수
- 인스턴스 변수(instance variable) : 객체마다 하나씩 있는 변수 - 해당 클래스의 각 객체마다 따로 가지고 있다.
- 정적 변수(static variable) : 모든 객체를 통틀어서 하나만 있는 변수 - 해당 클래스의 모든 객체들이 서로 공유한다. 사용 예 : 객체를 만든 횟수, 시리얼 넘버 등
정적 변수의 예
public class Car {
private String color;
private int speed;
private int gear;
// 자동차의 시리얼 번호
private int id;
private static int numberOfCars = 0; // 정적 변수
public Car(String c, int s, int g) {
color = c; speed = s; gear = g;
id = ++numberOfCars;
}
}
class People {
private static int count;
public People() { ++count;// 호출 될 때 정적 변수 증가 }
protected void finalize() { // 객체가 소멸될 때 호출된다.
count--; // 객체 하나가 줄어 들 기 때문에 정적변수 count를 감소
}
}
정적 변수를 외부에서 사용할 때
- “클래스이름.정적변수명” 형식을 사용한다.
int n = Car.numberOfCars;
상수
- 상수는 공간을 절약하기 위하여 자동으로 정적 변수로 선언이 된다.
public class Car {
static final int MAX_SPEED = 350;
}
정적 메소드
- 정적 메소드(static method) : 객체를 생성하지 않고 사용할 수 있는 메소드
- (예) Math 클래스에 들어 있는 각종 수학 메소드 들
double value = Math.sqrt(9.0);
정적 메소드 예
public class Car {
private String color;
private int speed;
private int gear;
// 자동차의 시리얼 번호
private int id;
private static int numberOfCars = 0; // 정적 변수
public Car(String c, int s, int g) {
color = c; speed = s; gear = g;
id = ++numberOfCars;
}
public Car() { this(init, 0, 0); }
// 정적 메소드
public static int getNumberOfCars() { return numberOfCars; }
}
- 정적 메소드에서는 인스턴스 변수와 인스턴스 메소드에 접근할 수 없다.
→ 왜냐하면 정적 메소드는 해당 클래스 정의 부분을 만나면서 메모리 상에 올라 가는데 아직 객체를 만들지 않은 상태이기에 인스턴스 변수나 필드가 없다. 추 후 객체를 만들었다고 해서 어떠한 인스턴스 객체와도 연결되지 않기 때문에 접근 불가능
중간 점검
- 정적 변수는 어떤 경우에 사용하면 좋은가?
- PI(파이) 처럼 절대 바뀌지않는 경우, 시리얼넘버 같은 경우
- 정적 변수나 정적 메소드를 사용할 때, 클래스 이름을 통하여 접근하는 이유는?
- 어느 특정 인스턴스 객체에 속한게 아니기에.
- main( ) 안에서 인스턴스 메소드를 호출할 수 없는 이유는?
- main도 정적 메소드이기때문
접근 제어
- 접근 제어(access control) : 다른 클래스가 특정한 필드나 메소드에 접근하는 것을 제어하는 것
접근 제어의 종류
- 클래스 수준에서의 접근 제어
- 멤버 수준에서의 접근 제어
클래스 수준에서의 접근 제어
- public : 다른 모든 클래스가 사용할 수 있는 공용 클래스
- Package : 수식자가 없으면 : 같은 패키지 안에 있는 클래스들만이 사용
멤버 수준에서의 접근 제어
this 참조
- 자기 자신을 참조하는 키워드이다.
private int speed;
public void setSpeed(int speed) {
this.speed = speed;
}
- 필드의 이름과 매개변수의 이름이 같다. 이때 대입연산(=) 은 가장 가까운 곳에 대입 되는 경우가 있다. 그러므로 명시적으로 자기 자신(객체)의 speed 필드라고 명시한 것.
- 생성자를 호출할 때도 사용된다.
클래스와 클래스 간의 관계
- 사용(use): 하나의 클래스가 다른 클래스를 사용한다.
- 집합(has-a): 하나의 클래스가 다른 클래스를 포함한다.
- 상속(is-a): 하나의 클래스가 다른 클래스를 상속한다.
사용 관계
- 클래스 A의 메소드에서 클래스 B의 메소드들을 호출한다.
public class Complex { // 복소수를 표현하는 클래스
private double real;
private double imag;
public Complex(double r, double i) {
real = r;
imag = i;
}
...
double getReal() {
return real;
}
double getImag() {
return imag;
}
// 객체 참조 값을 매개변수로 받는다.
public Complex add(Complex c) {
double resultReal = real + c.getReal();
double resultImag = real + c.getImag();
return new Complex(resultReal, resultImag); // 객체가 생성되고 객체의 참조값이 반환된다.
}
}
집합 관계
class Time {
private int time;
private int minute;
private int second;
public Time(int t, int m, int s) {
time = t;
minute = m;
second = s;
}
}
public class AlarmClock {
private Time currentTime; // Time 객체가 포함된다
private Time alarmTime; // (has - a 관계)
public AlarmClock(Time a, Time c) {
alarmTime = a;
currentTime = c;
}
}
public class AlarmClockTest {
public static void main(String args[]) {
Time alarm = new Time(6, 0, 0);
Time current = new Time(12, 56, 34);
AlarmClock c = new AlarmClock(alarm, current);
System.out.println(c);
}
}