[Java] 객체지향 프로그래밍 1
6-01 객체지향 언어 장점
코드의 재사용성이 높고 유지보수가 용이하다.
재사용성, 유지보수, 중복된 코드의 제거 -> 3가지 관점에서 공부
6-02 클래스와 객체
클래스 정의 : 객체를 정의해 높은 것.
객체 정의 : 실제로 존재하는 것. 사물 또는 개념.
ex)
TV 설계도 - 클래스
TV라는 제품 - 객체
6-03 객체의 구성요소 - 속성과 기능
객체의 속성 - 멤버변수(variable)
객체의 기능 - 메서드(method)
class Tv {
String color; // 색깔
boolean power; // 전원상태
int channel; // 채널
void power() { power = !power; }
void channelUp() { channel++; }
void channelDown() { channel--; }
}
6-04 객체와 인스턴스
인스턴스 : 클래스로부터 만들어진 객체
ex)
책상은 객체다.
책상은 책상 클래스의 인스턴스다.
6-05 한 파일에 여러 클래스 작성하기
올바른 작성 예
// Hello2.java
public class Hello2 { }
class Hello3 { }
// Hello2.java
class Hello2 { }
class Hello3 { }
잘못된 작성 예
// Hello2.java
public class Hello2 { }
public class Hello3 { }
// Hello3.java
public class Hello2 { }
class Hello3 { }
// hello2.java
public class Hello2 { }
class Hello3 { }
6-06 객체의 생성과 사용
클래스명 변수명 = new 클래스명();
예제 6-1)
class Ex6_1 {
public static void main(String argsp[]) {
Tv t; // Tv 인스턴스를 참조하기 위한 변수 t 선언
t = new Tv(); // Tv 인스턴스를 생성한다.
t.channel = 7; // Tv 인스턴스의 멤버변수 channel
System.out.println("현재 채널은 " + t.channel + " 입니다.");
t.channelDown(); // Tv 인스턴스의 메서드 channelDown
System.out.println("채널 다운");
System.out.println("현재 채널은 " + t.channel + " 입니다.");
}
}
class Tv {
// Tv 속성 (멤버변수)
String color;
boolean power;
int channel;
// Tv 기능 (메서드)
void power() { power = !power; }
void channelUp() { ++channel; }
void channelDown() { --channel; }
}
6-07 객체의 생성과 사용 예제
예제 6-2)
class Ex6_2 {
public static void main(String[] args) {
Tv t1 = new Tv();
Tv t2 = new Tv();
System.out.println("t1 채널값은 " + t1.channel);
System.out.println("t2 채널값은 " + t2.channel);
t1.channel = 7;
System.out.println("t1 채널값을 7로 변경하였습니다.");
}
}
6-08 객체배열
Tv[] tvArr = new Tv[3]; // 참조변수 객체배열을 생성
// 객체를 생성해서 배열의 각 요소에 저장
tvArr[0] = new Tv();
tvArr[1] = new Tv();
tvArr[2] = new Tv();
6-09 클래스의 정의(1) - 데이터와 함수의 결합
변수 -> 배열 -> 구조체 -> 클래스
변수 : 하나의 데이터를 저장할 수 있는 공간
배열 : 같은 종류의 여러 데이터를 하나의 집합으로 저장할 수 있는 공간
구조체 : 서로 관련된 여러 데이터를 종류에 관계없이 하나의 집합으로 저장할 수 있는 공간
클래스 : 데이터와 함수의 결합(구조체 + 함수)
6-10 클래스의 정의(2) - 사용자 정의 타입
비객체지향적 코드
int hour1, hour2, hour3;
int minute1, minute2, minute3;
float second1, second2, second3;
int[] hour = new int[3];
int[] minute = new int[3];
float[] second = new float[3];
객체지향적 코드
Time t1 = new Time();
Time t2 = new Time();
Time t3 = new Time();
Time[] t = new Time[3];
t[0] = new Time();
t[1] = new Time();
t[2] = new Time();
6-11 선언위치에 따른 변수의 종류
class Variables { // 클래스 영역
int iv; // 인스턴스 변수
static int cv; // 클래스 변수(static변수, 공유변수)
void method() { // 메서드 영역
int lv = 0; // 지역변수
}
}
6-12 클래스 변수와 인스턴스 변수
class Card {
String kind; // 인스턴스 변수(개별 속성)
int number; // 인스턴스 변수(개별 속성)
static int width = 100; // 클래스 변수(공통 속성)
static int height = 250; // 클래스 변수(공통 속성)
}
6-13 클래스 변수와 인스턴스 변수 예제
class Ex6_3 {
public static void main(String args[]) { // 클래스 변수(static 변수)는 객체생성 없이 '클래스이름.클래스 변수'로 직접 사용 가능하다.
System.out.println("Card.width = " + Card.width);
System.out.println("Card.height = " + Card.height);
Card c1 = new Card();
c1.kind = "Heart";
c1.number = 7;
Card c2 = new Card();
c2.kind = "Spade";
c2.number = 4;
System.out.println("c1은 " + c1.kind + ", " + c1.number + "이며, 크기는 (" + c1.width + ", " + c1.height + ")");
System.out.println("c2는 " + c2.kind + ", " + c2.number + "이며, 크기는 (" + c2.width + ", " + c2.height + ")");
System.out.println("c1의 width와 height를 각각 50, 80으로 변경합니다.");
c1.width = 50;
c1.height = 80;
System.out.println("c1은 " + c1.kind + ", " + c1.number + "이며, 크기는 (" + c1.width + ", " + c1.height + ")");
System.out.println("c2는 " + c2.kind + ", " + c2.number + "이며, 크기는 (" + c2.width + ", " + c2.height + ")");
}
}
class Card {
String kind;
int number;
static int width = 100;
static int height = 250;
}
6-14 메서드란?
특정 작업을 수행하는 일련의 문장들을 하나로 묶은 것
6-15 메서드의 선언부
int add(int x, int y) {
int result = x + y;
return result;
}
반환값이 없는 경우 ‘void’
6-16 메서드의 구현부
지역변수(local variable)는 서로 다른 메서드에서 같은 이름으로 선언해도 된다.
int add(int x, int y) {
int result = x + y;
return result;
}
int multiply(int x, int y) {
int result = x * y;
return result;
}
6-17 메서드의 호출
public static void main(String[] args) {
int result = add(3, 5); // 메서드를 호출
}
6-18 메서드의 실행 흐름
MyMath mm = new MyMath(); // 먼저 인스턴스를 생성한다.
long value = mm.add(1, 2); // 메서드를 호출한다.
// 메서드 add의 괄호{}안에 있는 문장들이 순서대로 수행
// return문을 만나면, main 메서드로 되돌아와서 이후의 문장들을 실행한다.
6-19 메서드의 실행 흐름 예제
class Ex6_4 {
public static void main(String args[]) {
MyMath mm = new MyMath();
long result1 = mm.add(5L, 3L);
long result2 = mm.subtract(5L, 3L);
long result3 = mm.multiply(5L, 3L);
double result4 = mm.divide(5L, 3L);
System.out.println("add(5L, 3L) = " + result1);
System.out.println("subtract(5L, 3L) = " + result2);
System.out.println("multiply(5L, 3L) = " + result3);
System.out.println("divide(5L, 3L) = " + result4);
}
}
class MyMath {
long add(long a, long b) {
long result = a + b;
return result;
}
long subtract(long a, long b) { return a - b; }
long multiply(long a, long b) { return a * b; }
double divide(double a, double b) {
return a / b;
}
}
6-20 return문
void -> return 생략가능. 컴파일러가 자동추가.
int -> return 생략불가.
6-21 반환값
int add(int x, int y) {
int result = x + y;
return result;
}
int add(int x, int y) {
return x + y;
}
6-22 호출스택(call stack)
- 메서드가 호출되면 수행에 필요한 만큼의 메모리를 스택에 할당받는다.
- 메서드가 수행을 마치고 나면 사용했던 메모리를 반환하고 스택에서 제거된다.
- 호출스택의 제일 위에 있는 메서드가 현재 실행 중인 메서드이다.
- 아래에 있는 메서드가 바로 위의 메서드를 호출한 메서드이다.
6-23 기본형 매개변수
- 기본형 매개변수 : 변수의 값을 읽기만 할 수 있다.
- 참조형 매개변수 : 변수의 값을 읽고 변경할 수 있다.
class Data { int x; }
class Ex6_6 {
public static void main(String[] args) {
Data d = new Data();
d.x = 10;
System.out.println("main() : x = " + d.x);
change(d.x);
System.out.println("After change(d.x)");
System.out.println("main() : x = " + d.x);
}
static void change(int x) { // 기본형 매개변수
x = 1000;
System.out.println("change() : x = " + x);
}
}
6-24 참조형 매개변수
class Data2 { int x; }
class Ex6_7 {
public static void main(String[] args) {
Data2 d = new Data2();
d.x = 10;
System.out.println("main() : x = " + d.x);
change(d);
System.out.println("After change(d)");
System.out.println("main() : x = " + d.x);
}
static void change(Data2 d) { // 참조형 매개변수
d.x = 1000;
System.out.println("change() : x = " + d.x);
}
}
6-25 참조형 반환타입
class Data3 { int x; }
class Ex6_8 {
public static void main(String[] args) {
Data3 d = new Data3();
d.x = 10;
Data3 d2 = copy(d);
System.out.println("d.x ="+d.x);
System.out.println("d2.x="+d2.x);
}
static Data3 copy(Data3 d) {
Data3 tmp = new Data3(); // 새로운 객체 tmp를 생성한다.
tmp.x = d.x; // d.x의 값을 tmp.x에 복사한다.
return tmp; // 복사한 객체의 주소를 반환한다.
}
}
6-26 static 메서드와 인스턴스 메서드
메서드 중에서 인스턴스와 관계없는(인스턴스 변수나 인스턴스 메서드를 사용하지 않는) 메서드를 클래스 메서드(static 메서드)로 정의한다.
6-27 static 메서드와 인스턴스 메서드 예제
class MyMath2 {
long a, b;
// 인스턴스 변수 a, b만을 이용해서 작업하므로 매개변수가 필요없다.
long add() { return a + b; } // a, b는 인스턴스 변수
long subtract() { return a - b; }
long multiply() { return a * b; }
double divide() { return a / b; }
// 인스턴스 변수와 관계없이 매개변수만으로 작업이 가능하다.
static long add(long a, long b) { return a + b; } // a, b는 지역변수
static long subtract(long a, long b) { return a - b; }
static long multiply(long a, long b) { return a * b; }
static double divide(long a, long b) { return a / (double)b; }
}
class Ex6_9 {
public static void main(String args[]) {
// 클래스 메서드 호출. 인스턴스 생성없이 호출가능.
System.out.println(MyMath2.add(200L, 100L));
System.out.println(MyMath2.subtract(200L, 100L));
System.out.println(MyMath2.multiply(200L, 100L));
System.out.println(MyMath2.divide(200L, 100L));
MyMath2 mm = new MyMath2(); // 인스턴스를 생성.
mm.a = 200L;
mm.b = 100L;
// 인스턴스 메서드는 객체생성 후에만 호출이 가능함.
System.out.println(mm.add());
System.out.println(mm.subtract());
System.out.println(mm.multiply());
System.out.println(mm.divide());
}
}
6-28 static을 언제 붙여야 할까?
- 클래스를 설계할 때, 멤버변수 중 모든 인스턴스에 공통으로 사용하는 것에 static을 붙인다.
- 클래스 변수(static 변수)는 인스턴스를 생성하지 않아도 사용할 수 있다.
- 클래스 메서드(static 메서드)는 인스턴스 변수를 사용할 수 없다.
- 메서드 내에서 인스턴스 변수를 사용하지 않는다면, static을 붙이는 것을 고려한다.
6-29 메서드 간의 호출과 참조
- 같은 클래스에 속한 멤버들 간에는 별도의 인스턴스를 생성하지 않고도 서로 참조 또는 호출이 가능하다.
- 단, 클래스멤버가 인스턴스 멤버를 참조 또는 호출하고자 하는 경우에는 인스턴스를 생성해야 한다.
6-30 오버로딩(overloading)
- 한 클래스 내에 같은 이름의 메서드를 여러 개 정의하는 것
- 메서드 이름이 같아야 한다.
- 매개변수의 개수 또는 타입이 달라야 한다.
- 반환 타입은 관계없다.
6-31 오버로딩(overloading) 예제
class Ex6_10 {
public static void main(String args[]) {
MyMath3 mm = new MyMath3();
System.out.println("mm.add(3, 3) 결과:" + mm.add(3,3));
System.out.println("mm.add(3L, 3) 결과: " + mm.add(3L,3));
System.out.println("mm.add(3, 3L) 결과: " + mm.add(3,3L));
System.out.println("mm.add(3L, 3L) 결과: " + mm.add(3L,3L));
int[] a = {100, 200, 300};
System.out.println("mm.add(a) 결과: " + mm.add(a));
}
}
class MyMath3 {
int add(int a, int b) {
System.out.print("int add(int a, int b) - ");
return a+b;
}
long add(int a, long b) {
System.out.print("long add(int a, long b) - ");
return a+b;
}
long add(long a, int b) {
System.out.print("long add(long a, int b) - ");
return a+b;
}
long add(long a, long b) {
System.out.print("long add(long a, long b) - ");
return a+b;
}
int add(int[] a) { // 배열의 모든 요소의 합을 결과로 돌려준다.
System.out.print("int add(int[] a) - ");
int result = 0;
for(int i=0; i < a.length;i++)
result += a[i];
return result;
}
}
6-32 생성자(constructor)
- 인스턴스가 생성될 때 호출되는 ‘인스턴스 초기화 메서드’이다.
- 생성자의 이름은 클래스의 이름과 같아야 한다.
- 생성자는 리턴 값이 없다.
class Point {
Point() { // 매개변수가 없는 생성자.
}
Point(int x, int y) { // 매개변수가 있는 생성자.
}
}
6-33 기본 생성자(default constructor)
- 기본 생성자가 컴파일러에 의해서 추가되는 경우는 클래스에 정의된 생성자가 하나도 없을 때 뿐이다.
6-34 매개변수가 있는 생성자
class Car {
String color;
String gearType;
int door;
Car() {} // 기본 생성자
Car(String c, String g, int d) { // 생성자
color = c;
gearType = g;
door = d;
}
}
// 생성자 Car() 사용한다면
Car c = new Car();
c.color = "white";
c.gearType = "auto";
c.door = 4;
// 생성자 Car(String color, String gearType, int door) 사용한다면
Car c = new Car("white", "auto", 4);
6-35 매개변수가 있는 생성자 예제
- 인스턴스를 생성할 때는 다음의 2가지 사항을 결정해야 한다.
- 클래스 - 어떤 클래스의 인스턴스를 생성할 것인가?
- 생성자 - 선택한 클래스의 어떤 생성자로 인스턴스를 생성할 것인가?
class Car {
String color;
String gearType;
int door;
Car() {}
Car(String c, String g, int d) {
color = c;
gearType = g;
door = d;
}
}
class Ex6_12 {
public static void main(String[] args) {
Car c1 = new Car();
c1.color = "white";
c1.gearType = "auto";
c1.door = 4;
Car c2 = new Car("white", "auto", 4);
System.out.println("c1의 color=" + c1.color + ", gearType=" + c1.gearType+ ", door="+c1.door);
System.out.println("c2의 color=" + c2.color + ", gearType=" + c2.gearType+ ", door="+c2.door);
}
}
6-36 생성자에서 다른 생성자 호출하기 - this()
- 생성자의 이름으로 클래스이름 대신 this를 사용한다.
- 한 생성자에서 다른 생성자를 호출할 때는 반드시 첫 줄에서만 호출이 가능하다.
class Car2 {
String color;
String gearType;
int door;
Car2() {
this("white", "auto", 4);
}
Car2(String color) {
this(color, "auto", 4);
}
Car2(String color, String gearType, int door) {
this.color = color;
this.gearType = gearType;
this.door = door;
}
}
class Ex6_13 {
public static void main(String[] args) {
Car2 c1 = new Car2();
Car2 c2 = new Car2("blue");
System.out.println("c1의 color=" + c1.color + ", gearType=" + c1.gearType+ ", door="+c1.door);
System.out.println("c2의 color=" + c2.color + ", gearType=" + c2.gearType+ ", door="+c2.door);
}
}
6-37 객체 자신을 가리키는 참조변수 - this
- this : 인스턴스 자신을 가리키는 참조변수
- this(), this(매개변수) : 생성자, 같은 클래스의 다른 생성자를 호출할 때 사용한다.
- this는 ‘참조변수’이고, this()는 ‘생성자’이다.
6-38 변수의 초기화
- 멤버변수(클래스 변수와 인스턴스 변수)와 배열의 초기화는 선택이지만, 지역변수의 초기화는 필수이다.
class Test {
int x; // 인스턴스 변수
int y = x; // 인스턴스 변수
void method1() {
int i; // 지역변수
int j = i; // 에러. 지역변수를 초기화하지 않고 사용
}
}
6-39 멤버변수의 초기화
- 명시적 초기화
- 초기화
Leave a comment