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) 클래스 메소드 안에서는 “인스턴스 변수”에 접근할 수 없음

Tags:

Categories:

Updated: