10 minute read

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을 언제 붙여야 할까?

  1. 클래스를 설계할 때, 멤버변수 중 모든 인스턴스에 공통으로 사용하는 것에 static을 붙인다.
  2. 클래스 변수(static 변수)는 인스턴스를 생성하지 않아도 사용할 수 있다.
  3. 클래스 메서드(static 메서드)는 인스턴스 변수를 사용할 수 없다.
  4. 메서드 내에서 인스턴스 변수를 사용하지 않는다면, static을 붙이는 것을 고려한다.

6-29 메서드 간의 호출과 참조

  • 같은 클래스에 속한 멤버들 간에는 별도의 인스턴스를 생성하지 않고도 서로 참조 또는 호출이 가능하다.
  • 단, 클래스멤버가 인스턴스 멤버를 참조 또는 호출하고자 하는 경우에는 인스턴스를 생성해야 한다.

6-30 오버로딩(overloading)

  • 한 클래스 내에 같은 이름의 메서드를 여러 개 정의하는 것
    1. 메서드 이름이 같아야 한다.
    2. 매개변수의 개수 또는 타입이 달라야 한다.
    3. 반환 타입은 관계없다.

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)

  • 인스턴스가 생성될 때 호출되는 ‘인스턴스 초기화 메서드’이다.
    1. 생성자의 이름은 클래스의 이름과 같아야 한다.
    2. 생성자는 리턴 값이 없다.
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가지 사항을 결정해야 한다.
    1. 클래스 - 어떤 클래스의 인스턴스를 생성할 것인가?
    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 멤버변수의 초기화

  • 명시적 초기화
  • 초기화

Tags:

Categories:

Updated:

Leave a comment