9. 클래스의 기능
9-1. 멤버에 대한 접근 제한
자동차 연료가 음수가 될 수 있나? NO!
사물에 대한 부자연스러운 조작을 막을 필요가 있다!
Private 멤버 만들기
실수 방지 위해, 클래스 외부에서 마음대로 접근할 수 없는 멤버를 만들 수 있음!
이것이 바로 private 멤버
class Car
{
private int num;
private double gas;
}
//----------------------------
class Sample1
{
public static void main(String[] args)
{
//...
// 아래와 같이 불가능! ( 클래스 "외부에서 접근 불가" )
//car1.num=1234;
//car1.gas=30.5;
}
}
Public 멤버 만들기
이에 접근하기 위해선, public 멤버가 필요하다.
-
필드는 private 멤버로,
-
메소드는 public 멤버로!
반드시 public 멤버인 메소드를 호출하여, 값을 저장해야한다!
class Car
{
// private 멤버
private int num;
private double gas;
// public 멤버
public void setNumGas(int n, double g)
{
if(g>0 && g<1000){
num=n;
gas=g;
System.out.println("차량번호 변경 to "+num+", 연료 변경 to"+gas);
}
else{
System.out.println("잘못 설정된 값");
}
}
public void show()
{
System.out.println("차량 변호"+num);
System.out.println("차량 변호"+gas);
}
}
class Sample2
{
public static void main(String[] args)
{
Car car1=new Car();
// car1.num=1234;
// car1.gas=20.5;
car1.setNumGas(1234,20.5); // 20.5 대신 음수이면, 에러 뜰 것!
car1.show();
}
}
요약 : public 멤버는, class 외부에서 접근할 수 있다!
캡슐화의 원리
캡슐화 =
-
클래스에 데이터(필드)와 기능(메소드)를 한 곳에 모은 뒤,
-
보호하고 싶은 멤버에 “private을 붙여” 접근을 제한하는 방법
일반적으로…
- 필드 : private 멤버
- 메소드 : public 멤버
private, public 생략 시?
- 제한자 (private, public)를 생략할 경우, 같은 폴더 안의 클래스는 마음 껏 접근 가능!
9-2. 메소드의 오버로딩
메소드 오버로딩 (Method Overloading)
-
클래스는 “같은 이름의 메소드 2개 이상”을 정의할 수 있게 함!
-
example
class Car
{
public void setCar(int n){
...
}
public void setCar(double g){
...
}
public void setCar(int n, double g){
...
}
}
기타/주의
- 메소드를 오버로딩할 때에는, “메소드의 인수의 형(type)과 개수를 반드시 다르게”해야한다!
- 다형성(polymorphism) : 하나의 이름이, 상황에 맞게 다른 기능을 가지는 것!
9-3. 생성자의 기본
클래스 안에는, “필드”와 “메소드”이외에도..
“생성자 (constructor)”라는 것을 작성할 수 있음!
- example )
class Car
{
private int num;
private double gas;
// 생성자 정의하기
public Car()
{
num=0;
gas=0.0;
System.out.println("초기값 설정");
}
public void show()
{
System.out.println("차량 변호는"+num);
System.out.println("연료량은"+gas);
}
}
class Sample4
{
public static void main(String[] args)
{
Car car1=new Car();
car1.show();
}
}
생성자의 역할 이해하기
- 클래스의 객체가 생성될 때, “생성자 안의 코드가 자동으로 실행”
-
메소드와 달리, “자유로이 호출 X”
- 객체의 멤버에 “자동으로 초기값을 설정”할 때!
즉, 생성자란, “프로그램 부품의 초기 설정을 자동으로 하기 위한 장치”
9-4. 생성자 오버로링
메소드 뿐만 아니라, 생성자도 여러 개 중복해서 정의 가능
class Car
{
private int num;
private double gas;
// 생성자 정의하기
public Car()
{
num=0;
gas=0.0;
System.out.println("(초기값) 자동차 생성 완료!");
}
public Car(int n, double g)
{
num=n;
gas=g;
System.out.println("자동차 생성 완료!");
}
public void show()
{
System.out.println("차량 변호는"+num);
System.out.println("연료량은"+gas);
}
}
class Sample5
{
public static void main(String[] args)
{
// 생성자 유형 1
Car car1=new Car();
car1.show();
// 생성자 유형 2
Car car2=new Car(1234,20.5);
car2.show();
}
}
다른 생성자를 호출하기
- 생성자 안에서만 사용할 수 있는 편리한 코드 작성법!
class Car
{
private int num;
private double gas;
// 생성자 정의하기
public Car()
{
num=0;
gas=0.0;
System.out.println("(초기값) 자동차 생성 완료!");
}
public Car(int n, double g)
{
this(); // 인자 없는 생성자(위의 Car())이 호출
num=n;
gas=g;
System.out.println("자동차 생성 완료!");
}
public void show()
{
System.out.println("차량 변호는"+num);
System.out.println("연료량은"+gas);
}
}
- 만약, 인수가 2개인 생성자를, 다른 생성자에서 호출하고 싶다면, 인수를 this() 안에 argument로써 전달하면 호출된다!
생성자를 생략한다면?
-
인수 없는 생성자 가 호출됨!
( 인수 없는 생성자 = 기본 생성자 )
생성자에 접근 제한자를 붙이기
- 메소드에 public / private 붙였던 것 처럼, 생성자에도 가능!
class Car
{
private int num;
private double gas;
// private한 생성자
private Car()
{
num=0;
gas=0.0;
System.out.println("(초기값) 자동차 생성 완료!");
}
// public한 생성자
public Car(int n, double g)
{
num=n;
gas=g;
System.out.println("자동차 생성 완료!");
}
public void show()
{
System.out.println("차량 변호는"+num);
System.out.println("연료량은"+gas);
}
}
class Sample
{
public static void main(String[] args)
{
// 아래와 같이 private한 생성자로는 불가능!
// Car car1=new Car();
// car1.show();
Car car2=new Car(1234,20.5);
car2.show();
}
}
9-5. 클래스 변수, 클래스 메소드
인스턴스 메소드 & 인스턴스 변수 작성하기
class Car
{
// ---- 인스턴스 변수 ------ //
private int num;
private double gas;
// ----------------------- //
public Car()
{
num=0;
gas=0.0;
System.out.println("(초기값) 자동차 생성 완료!");
}
public Car(int n, double g)
{
num=n;
gas=g;
System.out.println("자동차 생성 완료!");
}
// ---- 인스턴스 메소드 ------ //
public void setCar(int n, double g)
{
num=n; gas=g;
System.out.println("차량변호 변경 to"+num+"연료량 변경 to"+gas);
}
public void show()
{
System.out.println("차량 변호는"+num);
System.out.println("연료량은"+gas);
}
// -------------------------- //
}
class Sample
{
public static void main(String[] args)
{
Car car1=new Car();
car1.setCar(1234,20.5);
car1.show();
Car car2=new Car();
car2.setCar(4567,30.5);
car2.show();
}
}
- num과 gas는 “클래스 Car에 연결”되어 있다.
- 각 객체와 연결된 필드를 “인스턴스 변수 & 메소드”라고 한다
클래스 변수와 클래스 메소드
-
“객체에 연결되지 않은”“ 멤버
( = 클래스 “전체”에 연결되어 있다 )
-
클래스 변수/메소드 정의 위해선, 앞에
static
이라는 제한자를 붙여야! -
클래스 메소드는, 객체를 생성하지 않더라도 호출 가능!
( 클래스 이름을 붙여서 호출 함 )
class Car
{
public static int sum=0; // "클래스" 변수
private int num; // "인스턴스" 변수
private double gas; // "인스턴스" 변수
public Car()
{
num=0;
gas=0.0;
sum++; // 클래스 변수 sum +1
System.out.println("(초기값) 자동차 생성 완료!");
}
public Car(int n, double g)
{
num=n;
gas=g;
System.out.println("자동차 생성 완료!");
}
public void setCar(int n, double g)
{
num=n; gas=g;
System.out.println("차량변호 변경 to"+num+"연료량 변경 to"+gas);
}
// 클래스 메소드
public static void showSum()
{
System.out.println("자동차는 총 "+sum+"대 있습니다");
}
public void show()
{
System.out.println("차량 변호는"+num);
System.out.println("연료량은"+gas);
}
// -------------------------- //
}
class Sample
{
public static void main(String[] args)
{
//-------------------//
Car.showSum();
//-------------------//
Car car1=new Car();
car1.setCar(1234,20.5);
//-------------------//
Car.showSum();
//-------------------//
Car car2=new Car();
car2.setCar(4567,30.5);
//-------------------//
Car.showSum();
//-------------------//
}
}
주의 사항
- 1) 클래스 메소드 안에서는 “this.”를 사용할 수 없음
- 2) 클래스 메소드 안에서는 “인스턴스 변수”에 접근할 수 없음