클래스와 객체 (1)
1. 객체지향과 자바
1) 세상 모든 것이 객체다
실 세계 객체의 특징
- 객체마다 고유한 특성(state)와 행동(behavior)를 가짐
- 다른 객체들과 정보를 주고 받는 등, 상호작용하면서 살아감
컴퓨터 프로그램에서 객체 사례
- 테트리스 게임의 각 블록들
- 한글 프로그램의 메뉴나 버튼들
2) 자바의 객체 지향 특성 : 캡슐화
캡슐화 : 객체를 캡슐로 싸서 내부를 볼 수 없게 하는 것
- 객체의 가장 본질적인 특징
- 외부의 접근으로부터 객체 보호
자바의 캡슐화
- 클래스(class): 객체 모양을 선언한 틀(캡슐화하는 틀)
- 객체: 생성된 실체(instance)
- 클래스 내에 메소드와 필드 구현
3) 자바의 객체 지향 특성 : 상속
- 상위 개체의 속성이 하위 개체에 물려짐
- 하위 개체가 상위 개체의 속성을 모두 가지는 관계
실 세계의 상속 사례
graph BT
A[어류] --> B[동물];
C[사람] -->B;
D[나무] --> E[식물];
F[풀] -->E;
B-->G[생몰];
E-->G;
나무는 식물의 속성과 생물의 속성을 모두 가짐
사람은 생물의 속성은 가지지만 식물의 속성은 가지고 있지 않음
- 상위 클래스의 멤버를 하위 클래스가 물려받음
- 상위 클래스 : 슈퍼 클래스
- 하위클래스 : 서브클래스, 슈퍼클래스코드의 재사용, 새로운 특성 추가가능
class Animal {
String name;
int age;
void eat {...};
void speak {...};
void love {...};
}
// 상속
class Human extends Animals {
String hobby;
String job;
void work {...};
void cry {...};
void laugh {...};
}
4) 자바의 객체 지향 특성 : 다형성
같은 이름의 메소드가 클래스 혹은 객체에 따라 다르게 구현되는 것
- 메소드 오버로딩 : 한 클래스 내에서 같은 이름이지만 다르게 작동하는 여러 메소드
- 메소드 오버라이딩 : 슈퍼 클래스의 메소드를 동일한 이름으로 서브 클래스마다 다르게 구현
5) 객체 지향 언어의 목적
소프트웨어의 생산성 향상
- 컴퓨터 산업 발전에 따라 소프트웨어의 생명 주기(life cycle) 단축: 소프트웨어를 빠른 속도로 생산할 필요성 증대
- 객체지향언어: 상속, 다형성, 객체, 캡슐화등 소프트웨어 재사용을 위한 여러 장치 내장, 소프트웨어 재사용과 부분 수정 빠름, 소프트웨 어를 다시 만드는 부담 대폭 줄임, 소프트웨어 생산성 향상
실 세계에 대한 쉬운 모델링
- 초기프로그래밍:수학계산/통계처리를하는등처리과정,계산 절차 중요
- 현대 프로그래밍 : 컴퓨터가 산업 전반에 활용, 실 세계에서 발생하는 일을 프로그래밍, 실 세계에서는 절차나 과정보다 물체(객체)들의 상호 작용으로 묘사하는 것이 용이
- 객체지향언어: 실세계의 일을 보다 쉽게 프로그래밍하기위한 객체 중심적 언어
6) 절차 지향 프로그래밍과 객체 지향 프로그래밍
절차 지향 프로그래밍
- 작업 순서를 표현하는 컴퓨터 명령 집합
- 함수들의 집합으로 프로그램 작성
객체 지향 프로그래밍
- 컴퓨터가 수행하는 작업을 객체들간의 상호 작용으로 표현
- 클래스 혹은 객체들의 집합으로 프로그램 작성
절차지향적 프로그래밍의 실행 절차
graph LR
A([시작]) --> B[동전입력]
B--> C{돈이 충분 한가?}
C--> |아니오| B
C--> |예| D[상품선택]
D-->E{상품 재고 있나요?}
E--> |아니오| D
E--> |예| F[상품인도]
객체지향적 프로그래밍의 객체들의 상호 관련성
graph BT
b[버튼1]
c[버튼2]
d[버튼3]
a[디스플레이]
b-->e[자판기 엔진]
c-->e
d-->e
e-->a
direction BT
e---->f[돈통통]
e---->g[커피통]
e---->h[물통]
e---->i[프림통]
e---->j[컵통]
7) 클래스와 객체
클래스
- 객체의 속성(state)과 행위(behavior) 선언
- 객체의설계도혹은틀
객체
- 클래스의 틀로 찍어낸 실체
- 프로그램 실행 중에 생성되는 실체
- 메모리 공간을 갖는 구체적인 실체
- 인스턴스(instance)라고도 부름
사례
클래스 | 객체 |
---|---|
소나타자동차 | 출고된 실제 소나타 100대 |
벽시계 | 우리집벽에걸린벽시계들 |
책상 | 우리가 사용중인 실제 책상들 |
붕어빵 틀은 클래스이며, 이 틀의 형태로 구워진 붕어빵은 바로 객체입니다.
붕어빵은 틀의 모양대로 만들어지지만 서로 조금씩 다릅니다.
- 치즈 붕어빵, 크림 붕어빵, 앙꼬 붕어빵 등이 있습니다. 그래도 이들은 모두 붕어빵입니다.
객체들은 클래스에 선언된 동일한 속성을 가지지만 속성 값은 서로 다름
2. 자바 클래스, 생성자
1) 자바 클래스의 구성
- class 키워드로 선언
- 멤버 : 클래스 구성 요소
- 필드(멤버 변수)와 메소드(멤버 함수)
- 클래스에 대한 public 접근 지정 : 다른 모든 클래스에서 클래스 사용 허락
- 멤버에 대한 public 접근 지정 : 다른 모든 클래스에게 멤버 접근 허용
public class Circle {
// 변수
int radius;
String name;
public double getArray() { // 메소드
return 3.14 * radius * radius;
}
}
2) Circle 클래스의 객체 생성 및 활용
[예제 4-1]
public class Circle {
int radius; // 원의 반지름을 저장하는 멤버 변수
String name; // 원의 이름을 저장하는 멤버 변수
public double getArea() { // 멤버 메소드
return 3.14 * radius * radius;
}
public static void main(String[] args) {
Circle pizza;
pizza = new Circle();
pizza.radius = 10;
pizza.name = "자바피자";
double area = pizza.getArea();
System.out.println(pizza.name + "의 면적은 " + area);
Circle donut = new Circle();
donut.radius = 2;
donut.name = "자바도넛";
area = donut.getArea();
System.out.println(donut.name + "의 면적은 " + area);
}
}
자바피자의 면적은 314.0
자바도넛의 면적은 12.56
3) Rectangle 클래스 만들기 연습
[예제 4-2] 너비(width)와 높이(height) 필드, 그리고 면적 값을 제공하는 getArea() 메소드를 가진 Rectangle 클래스를 작성하라.
public class Rectangle {
int width;
int height;
int getArea() {
return width * height;
}
public static void main(String[] args) {
Rectangle rect = new Rectangle(); // 객체 생성
rect.width = 4;
rect.height = 5;
System.out.println("사각형의 면적은 " + rect.getArea());
}
}
사각형의 면적은 20
4) 생성자
- 객체가 생성될 때 초기화 목적으로 실행되는 메소드
- 객체가 생성되는 순간에 자동 호출
5) 두 개의 생성자를 가진 Circle 클래스
[예제 4-3]
public class Circle {
int radius;
String name;
public Circle() { // 매개 변수 없는 생성자
radius = 1;
name = ""; // radius의 초기값은 1
}
public Circle(int r, String n) { // 매개 변수를 가진 생성자
radius = r;
name = n;
}
public double getArea() {
return 3.14 * radius * radius;
}
public static void main(String[] args) {
Circle pizza = new Circle(10, "자바피자"); // Circle 객체 생성, 반지름 10
double area = pizza.getArea();
System.out.println(pizza.name + "의 면적은 " + area);
Circle donut = new Circle(); // Circle 객체 생성, 반지름 1
donut.name = "도넛피자";
area = donut.getArea();
System.out.println(donut.name + "의 면적은 " + area);
}
}
자바피자의 면적은 314.0 도넛피자의 면적은 3.14
6) 생성자의 특징
- 생성자 이름은 클래스 이름과 동일
- 생성자는 여러 개 작성 가능(생성자 중복)
-
생성자는 객체 생성시 한 번만 호출 : 자바에서 객체 생성은 반드시 new 연산자로 함
-
생성자의 목적은 객체 생성 시 초기화
- 생성자는 리턴 타입을 지정할 수 없음
7) 생성자 선언 및 호출 연습
[예제 4-4] title과 author 필드를 가진 Book 클래스를 선언하고,필드 값을 매개변수로 받아 초기화하는 2개의 생성자를 작성하라.
public class Book {
String title;
String author;
public Book(String t) { // 생성자
title = t;
author = "작자미상"; }
public Book(String t, String a) { // 생성자
title = t;
author = a;
}
public static void main(String [] args) {
Book javaBook = new Book("Java", "황기태"); // 2개의 매개변수 생성자 호출
Book bible = new Book("Bible"); // 1개의 매개변수 생성자 호출
}
}
8) 기본 생성자
- 매개 변수 없고, 아무 작업 없이 단순 리턴하는 생성자
- 디폴트 생성자라고도 불림
9) 기본 생성자가 자동 생성되는 경우
- 클래스에 생성자가 하나도 선언되어 있지 않을 때
- 컴파일러에 의해 기본 생성자 자동 생성
public class Circle {
int radius;
void set(int r) { ridius = r; }
double getArea() { return 3.14 * radius * radius; }
public static void main(String[] args) {
Circle pizza = new Circle(); // 호출 -> 컴파일러에 의해 자동 생성자 삽입 public Circle() {}
pizza.set(5);
System.out println(pizza.getArea());
}
}
10) 기본 생성자가 자동 생성되지 않는 경우
- 클래스에 생성자가 선언되어 있는 경우
- 컴파일러는 기본 생성자를 자동 생성해 주지 않는다.
public class Circle {
int radius;
void set(int r) { radius = r; }
double getArea() { return 3.14 * radius * radius; }
public Circle(int r) {
radius = r;
}
public static void main(string[] args) {
Circle pizza = new Circle(10);
System.out.println(pizza.getArea());
Circle donut = new Circle(); // 컴파일 오류 : 해당하는 생성자 없음
System.out.println(donut.getArea());
}
}
3. this 레퍼런스, 객체 배열
1) this 레퍼런스
- 객체 자신에 대한 레퍼런스
- 컴파일러에 의해 자동 관리, 개발자는 사용하기만 하면 됨
this.
멤버 형태로 멤버를 접근할 때 사용
public class Circle {
int radius;
public Circle() {
radius = 1;
}
public Circle(int r) {
radius = r;
}
double getArea() {
return 3.14 * radius * radius;
}
...
}
this를 사용하여 수정한 경우
public class Circle {
int radius;
public Circle() {
this.radius = 1;
}
public Circle(int radius) {
this.radius = radius;
}
double getArea() {
return 3.14 * this.radius * this.radius;
}
...
}
2) 객체 속에서의 this
생략
3) this()로 다른 생성자 호출
- 같은 클래스의 다른 생성자 호출
- 생성자 내에서만 사용 가능
- 생성자 코드의 제일 처음에 있어야 함
this() 사용 실패 사례
public Book() {
System.out.println("생성자 호출됨");
this("", "", 0); // 생성자의 첫 번째 문장이 아니기 때문에 컴파일 오류
}
[예제 4-5] this()로 다른 생성자 호출
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) 생성자 호출
}
public Book(String title, String author) {
this.title = title;
this.author = author;
}
public static void main(String [] args) {
Book javaBook = new Book("Java", "황기태");
Book bible = new Book("Bible");
Book emptyBook = new Book();
bible.show();
}
}
4) 객체 배열
객체에 대한 레퍼런스 배열임
자바의 객체 배열 만들기 3단계
- 배열레퍼런스 변수선언
- 레퍼런스 배열 생성
- 배열의 각 원소 객체생성
Circle [] c; // 1단계 : Circle 배열에 대한 레퍼런스 변수 c 선언
c = new Circle[5]; // 2단계 : 레퍼런스 배열 생성
for (int i = 0; i < c.length; i++)
c[i] = new Circle(i); // 3단계: 각 원소 객체 생성
for (int i = 0; i < c.length; i++) // 모든 객체의 면적 출력
System.out.pirnt((int)(c[i].getArea())+ " ")
5) 객체 배열 선언과 생성 과정
생략 (4 설명과 유사)
6) Circle 배열 만들기
[예제 4-6]
class Circle {
int radius;
public Circle(int radius) {
this.radius = radius;
}
public double getArea() {
return 3.14 * radius * radius;
}
}
public class CircleArray {
public static void main(String[] args) {
Circle [] c;
c = new Circle[5];
for(int i = 0; i < c.length; i++)
c[i] = new Circle(i);
for(int i = 0; i < c.length; i++)
System.out.print((int)(c[i].getArea()) + " ");
}
}
7) 객체 배열 만들기
[예제 4-7] 예제 4-4의 Book 클래스를 활용하여 2개 Book 객체 배열을 만들고, 사용자 로부터 책의 제목과 저자를 입력 받아 배열을 완성하라
import java.util.Scanner;
class Book {
String title, author;
public Book(String title, String author) {
this.title = title;
this.author = author;
}
}
public class BookArray {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
Book [] book = new Book[2]; // Book 배열 선언
for(int i=0; i<book.length; i++) {
System.out.print("제목>>");
String title = scanner.nextLine();
System.out.print("저자>>");
String author = scanner.nextLine();
book[i] = new Book(title, author); // 배열 원소 객체 생성
}
for(int i=0; i<book.length; i++)
System.out.print("(" + book[i].title + ", " + book[i].author + ")");
}
}