자바의정석-객체지향 프로그래밍

자바의정석-객체지향 프로그래밍

chapter6 객체지향 프로그래밍 1

- TV설계도(클래스)는 TV라는 제품(객체)를 정의한 것이며, TV(객체)를 만드는데 사용된다.

- 객체를 사용하려면, 클래스로부터 객체를 생성하는 과정이 선행되어야 한다.

클래스 객체 제품 설계도 제품 TV 설계도 TV 붕어빵 기계 붕어빵

- 클래스로부터 객체를 만드는 과정을 클래스의 인스턴스화(instantiate) 라고 한다.

- 어떤 클래스로부터 만들어진 객체를 그 클래스의 인스턴스(instance)라고 한다.

3. 클래스의 또 다른 정의

1) 클래스 – 데이터와 함수의 결합

- 자바와 같은 객체지향언어에서는 변수(데이터)와 함수를 하나의 클래스에 정의하여 서로 관계가 깊은 변수와 함수들을 함께 다룰 수 있게 했다.

- 서로 관련된 변수들을 정의하고 이들에 대한 작업을 수행하는 함수들을 함께 정의한 것이 바로 클래스이다.

- 자바에서는 문자열을 문자의 배열로 다루지않고, String이라는 클래스로 문자열을 다룬다.

문자열을 클래스로 다룬 이유는, 문자열과 문자열을 다루는데 필요한 함수들을 함께 묶기 위해서다.

2) 클래스 – 사용자 정의 타입(user-defined type)

- 예를 들어 시간을 표현하기 위해서는 시/분/초 변수를 생성하는데

하나의 시간을 구성하는 시/분/초 변수가 분리되지 않도록 하나로 묶어 사용자 정의 타입 즉, 클래스를 정의해서 사용한다.

- 시간을 구성하는 시/분/초라는 변수에 제약 조건이 있을 때 제어자를 통해 변수의 값을 직접 변경하지 못하도록 하고 대신 메서드를 통해서 값을 변경하도록 작성 할 수 있다.

- 값을 변경할 때 지정된 값의 유효성을 조건문으로 저검한 다음에 유효한 값일 경우에만 변경할 수도 있다.

코드의 setHour메서드 참고

public class Time { private int hour; private int minute; private float second; public int getHour() { return hour; } public int getMinute() { return minute; } public float getSecond() { return second; } public void setHour(int hour) { if(hour<0 || hour>23) return; this.hour = hour; } public void setMinute(int minute) { this.minute = minute; } public void setSecond(float second) { this.second = second; } }

변수의 종류 선언위치 생성시기 멤버변수 클래스 변수 클래스 영역 클래스가 메모리에 올라갈 때 인스턴스 변수 클래스 영역 인스턴스가 생성되었을 때 멤버변수 특징 : 자동으로 초기화가 된다 . 지역변수 메서드 , 생성자 , 초기화 블록 내부 ( 클래스 이외 영역 ) 변수 선언문이 수행되었을 때 지역변수 특징 : 자동으로 초기화되지 않는다 . 초기화 되지 않은 상태에서 다른 변수를 초기화 하는데 사용될 수 없다 .

class InitTest{ int x; int y = x; void method(){ int i; int j = i; //에러. 지역변수를 초기화하지 않고 사용 } }

- 클래스 변수 : 인스턴스를 생성하지 않고도 언제라도 바로 사용할 수 있다.

- main메서드와 같은 클래스에 있을 때 클래스이름을 생략하는 것이 가능하다.

- 클래스를 작성할 때 속성과 기능을 알아 내야 한다.

- 또한 속성중에 어떤 속성을 클래스 변수로 선언할 것이며, 어떤 속성들을 인스턴스 변수로 선언할 것인지 생각해보자.

class Card { String kind ; // 카드의 무늬 - 인스턴스 변수 int number; // 카드의 숫자 - 인스턴스 변수 static int width = 100; // 카드의 폭 - 클래스 변수 static int height = 250; // 카드의 높이 - 클래스 변수 }

- 클래스 정의할 때 어느 경우에 static을 사용해서 클래스 메서드나 클래스 변수로 정의해야 할까?

- 클래스의 멤버변수 중 모든 인스턴스에 공통된 값을 유지해야 하는 것 이 있는지 살펴보고 있으면 static을 붙여준다.

- 작성한 메서드 중에서 인스턴스 변수나 인스턴스 메서드를 사용하지 안는 메서드에 static을 붙일 것을 고려 한다.

- argument(인자)와 parameter(매개변수)

public static void main(String[] args) { int result = add(3,5); //메서드 호출, argument(인자), 원본 int add(int a,int b) { //parameter(매개변수), 복사본 return a+b; } }

6. 매개변수의 유효성 검사

- 매개변수의 유효성 검사하는 코드를 반드시 넣기를 바란다.

- 메서드를 작성하는 사람은 호출하는 쪽에서 알아서 적절한 값을 넘겨주겠지 라는 생각을 절대로 가져서는 안된다.

- 타입만 맞으면 어떤 값도 매개변수를 통해 넘어 올 수 있기 때문에

가능한 모든 경우의 수에 대해 고민하고 그에 대비한 코드를 작성해야 한다.

7. JVM 의 메모리 구조

- JVM은 시스템으로부터 메모리를 할당받고, 메모리를 용도에 따라 여러 영역으로 나누어 관리한다.

- Method Area : 프로그램 실행 중 어떤 클래스가 사용되면 .class 파일을 읽어서 분석하여 클래스에 대한 정보를 이곳에 저장한다.

- Heap : 인스턴스가 생성되는 공간

- Call Stack : 메서드가 호출되면 호출스택에 메서드를 위한 메모리가 할당된다. 메서드가 작업을 마치면 할당되었던 메모리 공간은 반환된다.

Method Area

Call Stack

Heap

- 한 클래스 내에 같은 이름의 메서드를 여러 개 정의하는 것을

메서드 오버로딩, 오버로딩이라고 한다.

- 오버로딩 성립조건

① 메서드 이름이 같아야 한다.

② 매개변수의 개수 또는 타입이 달라야 한다.

- 가변인자

예) String… args, Object… objs

인자가 없어도 되고, 배열도 인자가 될 수 있다.

class VarArgsEx { public static void main(String[] args) { String[] strArr = { "100", "200", "300" }; System.out.println(concatenate("", "100", "200", "300")); System.out.println(concatenate("-", strArr)); System.out.println(concatenate(",", new String[] { "1", "2", "3" })); System.out.println("[" + concatenate(",", new String[0]) + "]"); System.out.println("[" + concatenate(",") + "]"); } static String concatenate(String delim, String... args) { String result = ""; for (String str : args) { result += str + delim; } return result; }

- 생성자에서 다른 생성자 호출하기

① 생성자의 이름으로 클래스이름 대신 this를 사용한다.

② 다른 생성자를 호출 할때는 반드시 첫줄에서만 호출 가능하다.

class Car { String color; // 색상 String gearType; // 변속기 종류 - auto(자동), manual(수동) int door; // 문의 개수 Car() { this("white", "auto", 4); } Car(Car c) { // 인스턴스의 복사를 위한 생성자. this(c.color, c.gearType, c.door); } Car(String color, String gearType, int door) { this.color = color; this.gearType = gearType; this.door = door; } }

- 클래스 초기화 블럭

- 인스턴스 초기화 블록

class BlockTest { //클래스 초기화 블럭: 클래스변수의 복잡한 초기화에 사용된다. static { System.out.println("static { }"); } //인스턴스 초기화 블럭 : 인스턴스 변수의 복잡한 초기화에 사용된다. //생성자마다 공통으로 수행되어야 하는 문장이 있을 때 사용하면 코드가 간결해진다. { System.out.println("{ }"); } public BlockTest() { System.out.println("생성자"); } public static void main(String args[]) { System.out.println("BlockTest bt = new BlockTest(); "); BlockTest bt = new BlockTest(); System.out.println("BlockTest bt2 = new BlockTest(); "); BlockTest bt2 = new BlockTest(); } }

- 아래 예제 실행결과 예측해보기

class Document { static int count = 0; String name; // 문서명(Document name) Document() { // 문서 생성 시 문서명을 지정하지 않았을 때 this("제목없음" + ++count); } Document(String name) { this.name = name; System.out.println("문서 " + this.name + "가 생성되었습니다."); } } class DocumentTest { public static void main(String args[]) { Document d1 = new Document(); Document d2 = new Document("자바.txt"); Document d3 = new Document(); Document d4 = new Document(); } }

- 실행결과

문서 제목없음1가 생성되었습니다. 문서 자바.txt가 생성되었습니다. 문서 제목없음2가 생성되었습니다. 문서 제목없음3가 생성되었습니다.

from http://devstep.tistory.com/12 by ccl(A) rewrite - 2021-10-30 13:01:17