[명품 JAVA programming] CHAPTER 4 클래스와 객체
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( ) 메소드를 작성하라