Language/JAVA

[명품 JAVA programming] CHAPTER 4 클래스와 객체

위시리 2023. 3. 19. 15:51

4.2 클래스 만들기

클래스 구성

클래스의 구성 요소 : 멤버

멤버 = 필드(멤버 변수) + 메소드(멤버 함수)

 

예제 4-2

너비와 높이를 입력받아 사각형의 합을 출력하는 프로그램을 작성하라

public class Rectangle {
    int width;
    int heigth;
    public int Rectarea(){
        return width*heigth;
    }
}
import java.util.*;
public class example {
    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);
        Rectangle rect = new Rectangle(); // 객체 생성

        // 가로 세로 값 입력받기
        System.out.print("넓이는? : ");
        rect.width = scan.nextInt();
        System.out.print("높이는? : ");
        rect.heigth = scan.nextInt();
        System.out.print("사각형의 넓이는 " + rect.Rectarea());
        scan.close();
    }
}

 

4.3 생성자

생성자 선언 및 활용

생성자(constructor) : 객체가 생성될 때 객체의 초기화를 위해 실행되는 메소드

 

생성자는 객체가 생성되는 순간 자동으로 호출되는 메소드

→ 객체에 필요한 초기화를 실행하는 코드 필요

 

예제 4-3

2개의 생성자를 가진 Circle 클래스의 실행결과는?

public  class Circle {
    public int radius;
    public String name;

    public Circle() { // 매개 변수가 없는 생성자
        radius = 1; // 매개 변수로 필드 초기화
        name = ""; 
    }
    public Circle(int r, String n){
        radius = r;
        name = n;
    }
    public double getArea() {
        return 3.14 * radius * radius;
    }
}
//import java.util.*;
public class example {
    public static void main(String[] args) {
        Circle pizza = new Circle(10,"피자");
        double getPiArea = pizza.getArea();
        System.out.println(pizza.name + "의 면적은 : " + getPiArea);

        Circle dounut = new Circle(5, "도넛");
        double getDoArea = dounut.getArea();
        System.out.println(dounut.name + "의 면적은 : " + getDoArea);
    }
}

피자의 면적은 : 314.0
도넛의 면적은 : 78.5

 

  • 생성자의 이름은 클래스의 이름과 동일해야 한다.
  • 생성자는 여러 개 작성(오버로딩) 가능하다.
  • 생성자는 new 를 통해 객체를 생성할 때 객체 당 한번만 호출된다.
  • 생성자는 return 타입을 지정할 수 없다. >> public Circle { ... }
  • 생성자의 목적은 객체가 생성될 때, 필요한 초기 작업을 하기 위함이다.

생성자는 객체가 생성될 때,

1. 필드 초기화

2. 필요한 메모리 확보

3. 파일 열기

4. 네트워크 연결

등 객체가 활동하기 전에 필요한 초기 준비를 하는데 이용

 

기본 생성자

기본 생성자(default constructor) : 매개변수와 실행 코드가 없어 아무 일도 하지 않고 단순 리턴하는 생성자

= 디폴트 생성자

 

생성자가 없는 경우 컴파일러가 자동으로 기본 생성자 생성

생성자가 하나라도 클래스에 존재하면 컴파일러가 기본 생성자를 자동 생성해주지 않음

 

this 레퍼런스

this : 객체 자신을 가르키는 레퍼런스

현재 실행되고 있는 메소드가 속한 객체에 대한 레퍼런스

 

this의 필요성

클래스 내의 변수 이름과 객체 내 변수 이름이 중복되는 경우가 발생할 때 이를 구분하기 위해 필요

 

객체가 있어야 this 사용 가능

 

this( )로 다른 생성자 호출

this( )는 클래스 내에서 생성자가 다른 생성자를 호출할 때 사용하는 자바 코드

 

예제 4-5

public class Book {
    String title;
    String author;

    void show(){
        System.out.println(title + " " + author);
    }
    public Book(){
        this("",""); // 현재 정의하고 있는 Book 클래스의 갯수와 맞는 것 호출
        System.out.println("생성자 호출됨");
    }
    public Book(String title){
        this(title, "작자미상");
    }
    public Book(String title, String author){
        this.title = title;
        this.author = author;
    }

}
//import java.util.*;
public class example {
    public static void main(String[] args) {
        Book littlePrince = new Book("어린왕자", "생택쥐페리");
        Book loveStory = new Book("춘향전");
        Book empty = new Book();
        loveStory.show();
    }
}

 

this 사용시 주의할 점

  • this( )는 반드시 생성자 코드에서만 호출 가능
  • this( )는 반드시 같은 클래스 내 다른 생성자를 호출할 때 사용
  • this( )는 반드시 생성자의 첫 번째 문장이 되어야 함

객체 치환 시 주의할 점

= 연산자로 객체를 치환 시

객체의 치환은 객체를 복제하는 것이 아니라 레퍼런스를 복제하는 것

 

import javax.swing.*;

public  class Circle {
    public int radius;
    public Circle(int radius){
        this.radius = radius;
    }
    public void set(int radius){
        this.radius = radius;
    }
}
//import java.util.*;
public class example {
    public static void main(String[] args) {
        Circle ob1 = new Circle(1);
        Circle ob2 = new Circle(2);
        Circle s;

        s = ob2; // 레퍼런스 복사(주소 넘김)
        ob1 = ob2; // 객체 치환
        System.out.println("ob1.radius = " + ob1.radius);
        System.out.println("ob2.radius = " + ob2.radius);
    }
}

ob1, ob2, s : 주소를 기억할 만큼 주소를 할당받는 reference 변수 생성

 

4.4 객체 배열

객체 배열

객체를 원소로 하는 객체 배열도 생성 가능

객체 배열 : 객체에 대한 레퍼런스를 원소로 갖는 배열

 

Circle [] c = new Circle[5]; // 레퍼런스 배열 생성

for(int i=0 ; i<c.length ; i++){
    c[i] = new Circle(i); // 각 배열의 원소를 c[i]에 객체 하나 생성해서 넣음
}

for(int i=0 ; i<c.length ; i++){ // 배열에 있는 모든 Circle 객체의 면적 출력
    System.out.print((int)(c[i].getArea()) + " ");
}

 

배열 선언 및 생성

객체 배열을 만들기 위해서는 3단계 필요

1. 배열에 대한 레퍼런스 선언

Circle [] c

위에서는 레퍼런스 변수 c만 선언할 뿐, 배열을 생성해서는 안됨

 

2.  레퍼런스 배열 생성

5개의 레퍼런스를 원소로 하는 배열 생성

c = new Circle[5];

 

 

3. 객체 생성

Circle 객체를 하나씩 생성하여 배열 c[ ]의 각 레퍼런스에 대입

for(int i=0 ; i<c.length ; i++){
    c[i] = new Circle(i);
}

배열의 크기만큼 Circle 객체를 생성하여 레퍼런스 배열에 하나씩 대입

 

>> Circle 객체 배열 생성

 

배열의 원소 객체 접근

배열 c의 i번째 객체에 접근하기 위해서는 c[ i ]에 레퍼런스를 사용하면 됨

아래 코드는 배열 c에 들어있는 모든 Circle 객체의 면적 출력

for(int i=0 ; i<c.length ; i++){ 
    System.out.print((int)(c[i].getArea()) + " ");
}

 

예제 4-7

예제 4-4의 Book클래스를 활용하여 2개짜리 Book 객체 배열을 만들고, 사용자로부터 책의 제목과 저자를 입력받아 배열을 완성하라.

public class Book {
    String title;
    String author;

    void show(){
        System.out.println(title + ", " + author);
    }
    public Book(){
        this("","");
        System.out.println("생성자 호출됨");
    }
    public Book(String title){
        this(title, "작자미상");
    }
    public Book(String title, String author){
        this.title = title;
        this.author = author;
    }
}
import java.util.*;
public class example {
    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);
        Book [] book = new Book[2];

        for(int i=0 ; i<book.length ; i++){
            System.out.print("책 제목을 입력하세요 : ");
            String title = scan.next();
            System.out.print("책 저자를 입력하세요 : ");
            String author = scan.next();
            book[i] = new Book(title, author);
        }

        for(int i=0 ; i<book.length ; i++){
            System.out.print("(" + book[i].title + ", " + book[i].author + ")");
            System.out.println();
        }
        scan.close();
    }
}

 

4.5 메소드 활용

메소드 형식

메소드 : 클래스의 멤버 함수

메소드 앞 접근 지정자 선언

접근 지정자 4가지 : public, private, protected, 디폴트

→ 메소드가 다른 클래스에서 호출될 수 있는지 지정하기 위해 사용

 

인자 전달

자바의 메소드 호출 시 인자 전달 방식(argument passing)은 '값에 의한 호출'(call by value)

호출하는 실인자의 값이 복사되어 메소드의 매개 변수에 전달

 

 

  • 기본타입의 매개변수 전달

기본타입 : byte, char, short, int, long, float, double, boolean)

메소드의 매개변수가 기본타입으로 선언된 경우

→ 호출자(caller)가 건네는 값이 매개변수에 복사되어 전달

 

ex. 변수 n에 저장된 값 10을 increase( ) 메소드에 전달

int n = 10;
increase(n);

 

이때 increase( ) 메소드가 아래와 같이 구현되어 있으면

public void increase(int num){
    num += 1;
}

메소드 내에서 넘겨받은 n(num)값이 증가하여도 실제 n값은 변하지 않음

함수가 종료되면서 그 값이 소멸되기 때문

 

 

  • 객체가 전달되는 경우

메소드의 매개변수가 클래스 타입인 경우, 객체가 아니라 객체의 레퍼런스 값이 전달

 

public class example {

    public static void increase(Circle m){
        m.radius++;
    }

    public static void main(String[] args) {
        Circle pizza = new Circle(10);
        increase(pizza);
        System.out.println(pizza.radius);
    }
}

결과 : 11

 

이때는 pizza의 주소값을 넘겨줌

즉, 객체의 주소를 전달

 

 

  • 배열이 전달되는 경우

배열도 객체와 마찬가지로 배열을 통채로 전달하는 것이 아니라 배열에 대한 레퍼런스값만 복사되어 전달

 

예제 4-8

char[ ] 배열을 전달받아 출력하는 printCharArray( ) 메소드와 배열 속의 공백(' ') 문자를 ','로 대치하는 replaceSpace( ) 메소드를 작성하라