아침에 일어나 학교를 가는 과정을 예를 들어 보자.
절차 지향 프로그래밍
객체 지향 프로그래밍
객체를 정의 하고
각 객체마다 제공하는 기능들을 구현하고
각 객체가 제공하는 기능들 간의 소통(메세지 전달)을 통하여 객체간의 협력을 구현
객체 지향 프로그램에서 객체 간에는 협력이 이루어짐
협력을 위해서는 필요한 메세지를 전송하고 이를 처리하는 기능이 구현되어야 함
매개 변수로 객체가 전달되는 경우가 발생
생성된 인스턴스는 동적 메모리(heap memory)에 할당됨
C나 C++ 언어에서는 사용한 동적 메모리를 프로그래머가 해제 시켜야 함 (free() 혹은 delete 이용)
자바에서는 Gabage Collector가 주기적으로 사용하지 않는 메모리를 수거
하나의 클래스로부터 여러 개의 인스턴스가 생성되고 각각 다른 메모리 주소를 가지게 됨
배열은 같은 데이터 타입을 가진 연속된 메모리 공간으로 이루어진 자료구조이다.
같은 데이터 타입을 가진 여러개의 변수가 필요할 때 사용한다.
int[] array1 = new int[4];
array1[0] = 1;
array1[1] = 2;
array1[2] = 3;
array1[3] = 4;
int value = array1[2];
//array1 이 참조하는 배열의 2번 인덱스에 해당하는 값 3을 꺼내서 int형 변수 value에 담는다.
System.out.println(array1[1]);
//array1 이 참조하는 배열의 1번 인덱스에 해당하는 값 2가 콘솔에 출력된다.
int[] array2 = new int[]{1,2,3,4,5};
//int 값을 5개저장 할 수 있는 배열이며, 해당 배열에는 1,2,3,4,5가 순서대로 저장되게 된다.
array.length
기본 자료형 배열은 선언과 동시에 배열의 크기만큼의 메모리가 할당되지만,
객체 배열의 경우엔 요소가 되는 객체의 주소가 들어갈(4바이트, 8바이트) 메모리만 할당되고(null) 각 요소 객체는 생성하여 저장해야 함
System.arrayCopy(src, srcPos, dest, destPos, length) // 자바에서 제공되는 배열 복사 메서드
arrayCopy는 얕은 복사
깊은 복사는 각각의 객체를 생성하여 그 객체의 값을 복사하여 배열이 서로 다른 객체를 가리키도록 함
int[][] array4 = new int[3][4];
array4[0][0] = 10;
int[][] array5 = new int[3][];
//위와 같이 선언하면 array5는 3개짜리 배열을 참조한다. 3개짜리 배열은 아직 참조하는 배열이 없다는 것을 의미.
array5[0] = new int[1]; //정수를 하나 담을 수 있는 배열을 생성해서 array5 의 0 번째 인덱스가 참조한다.
array5[1] = new int[2]; //정수를 두개 담을 수 있는 배열을 생성해서 array5 의 1 번째 인덱스가 참조한다.
array5[2] = new int[3]; //정수를 세개 담을 수 있는 배열을 생성해서 array5 의 2 번째 인덱스가 참조한다.
int[][] array6 = {{1}, {2,3}, {4,5,6}};
//위와 같이 선언할 경우 array6[0][0] 는 1이다. array6[1][0]은 2이다.
int[] iarr = {10,20,30,40,50};
for(int value:iarr){
System.out.println(value);
}
자바는 객체를 만들기 위해 반드시 클래스를 먼저 만들어야 한다. 클래스는 객체를 만들기 위한 일종의 틀이다.
붕어빵이 객체라면, 붕어빵 틀은 클래스
자동차 클래스 생성
public class Car{
}
Car.java란 파일을 만든다.
저장을 하면 이클립스는 컴파일하여 디스크에 Car라는 클래스를 생성한다.
자동차 클래스가 생성되었다고 해서 자동차가 만들어 진것은 아니다.
클래스는 대문자로 시작하는것이 좋다
java 파일 하나에 클래스는 여러 개가 있을 수 있지만, public 클래스는 하나이고, public 클래스와 .java 파일의 이름은 동일하다
camel notation 방식으로 명명한다.
public class CarExam{
public static void main(String args[]){
Car c1 = new Car();
Car c2 = new Car();
}
}
new연산자는 new연산자 뒤에 나오는 생성자를 이용하여 메모리에 객체를 만들라는 명령이다.
메모리에 만들어진 객체를 인스턴스(instance)라고도 한다.
이렇게 만들어진 객체를 참조하는 변수가 c1 , c2 이다.
위의 코드가 실행되면 Car라는 객체가 2개가 만들어지고 각각의 객체를 참조하는 c1과 c2변수가 선언된다.
참조형 타입은 기본형 타입을 제외한 모든 타입이다.
String str = new String("hello");
자바에서 가장 많이 사용하는 클래스이며 문자열을 표현한다.
String str1 = "hello";
String str2 = "hello";
String str3 = new String("hello");
String str4 = new String("hello");
if(str1 == str2){ // 같은 인스턴스를 참조하므로 결과는 true
System.out.println("str1과 str2는 같은 레퍼런스입니다.");
}
if(str1 == str3){ // str1과 str3은 서로 다른 인스턴스를 참조하므로 결과는 false
System.out.println("str1과 str3는 같은 레퍼런스입니다.");
}
if(str3 == str4){ // str3과 str4는 서로 다른 인스턴스를 참조하므로 결과는 false
System.out.println("str3과 str4는 같은 레퍼런스입니다.");
}
String str5 = "hello world";
String str6 = str5.substring(3);
TODO: 밑의 코드를 스스로 실행해보자.
String testString = "Like a flower in the dawn";
// 밑의 새로운 substring 두 개는 서로 같은 인스턴스를 참조하는가?
String testSubstring1 = testString.substring(3);
String testSubstring2 = testString.substring(3);
결과: testSubstring1과 testSubstring2는 서로 다른 인스턴스를 참조한다.
public class StringExam {
public static void main(String[] args) {
String str1 = new String("Hello world");
String str2 = new String("Hello world");
if( str1.equals(str2) ){
System.out.println("str1과 str2는 같은 값을 가지고 있습니다.");
}
else{
System.out.println("str1과 str2는 다른 값을 가지고 있습니다.");
}
}
}
자동차는 자동차 이름, 자동차 번호를 가지고 있고, 자동차는 달리고 멈추는 기능이 있다. 여기에서 가지고 있는 것을 속성이라고 한다. 자바에서는 이러한 속성을 필드(Field)라는 용어로 사용한다. 그리고 객체의 속성은 클래스의 멤버 변수(member variable)로 선언한다.
public class Car{
String name;
int number;
}
Car c1 = new Car();
Car c2 = new Car();
//Car라는 인스턴스가 메모리에 2개 만들어 진다. 객체별로 name과 number라는 속성을 가진다.
//c1.name은 c1이 참조하는 객체의 name 을 의미.
c1.name = "소방차"; //c1이 참조하는 객체의 name을 소방차로 설정
c1.number = 1234; // c1.number = 1234란 c1이 참조하는 객체의 number를 1234 로 설정
c2.name = "구급차" //c2가 가리키는 객체의name을 구급차로 설정
c2.number = 1004; //c2가 가리키는 객체의 number를 1004로 설정
System.out.println(c1.name); //콘솔에 c1이 참조하는 객체의 name 을 출력합니다.
System.out.println(c1.number); //콘솔에 c1이 참조하는 객체의 number 를 출력합니다.
String name = c2.name; //c2가 참조하는 객체의 name 을 String 타입 변수 name 도 참조하게 합니다.
필드가 물체의 상태라면, 물체의 행동에 해당하는게 메소드다. car에 이름과 번호가 있기도 하지만, car는 앞으로 전진할수도 있고 후진하는 행동도 할 수 있다.
public class MyClass{
public void method(){
System.out.println("method1이 실행됩니다.");
}
public void method2(int x){
System.out.println(x + " 를 이용하는 method2입니다.");
}
public int method3(){
System.out.println("method3이 실행됩니다.");
return 10;
}
public void method4(int x, int y){
System.out.println(x + "," + y + " 를 이용하는 method4입니다.");
}
public int method5(int y){
System.out.println(y + " 를 이용하는 method5입니다.");
return 5;
}
}
메소드를 사용하기 위해서는 메소드가 정의된 클래스인 MyClass 가 생성되어야 한다.
객체를 생성할 때는 new 연산자를 이용한다.
메소드를 사용할때는 생성된 클래스를 참조하는 레퍼런스변수.메소드명() 으로 사용할 수 있다.
public class MyClassExam{
public static void main(String args[]){
MyClass my1 = new MyClass(); //메소드가 정의된 클래스 생성
my1.method1(); //MyClass에서 정의해 놓은 메소드 method1() 를 호출한다.
my1.method2(10);
int x = my1.method3();
System.out.println("method3 이 리턴한 " + x + " 입니다.");
my1.method4(10,100);
int x2 = my1.method5(50);
System.out.println("method5 가 리턴한 " + x2 + " 입니다.");
}
}
class ReferenceTypeExam {
public static void main(String []args) {
ReferenceTypeExam exam = new ReferenceTypeExam();
//기본형 변수value1을 addOne에 전달합니다.
int value = 10;
exam.addOne(value);
System.out.println("기본형 변수의 값을 다른 메소드에서 변경한 결과: " + value);
//참조형 변수arr을 addOne에 전달합니다.
int []arr = {10};
exam.addOne(arr);
System.out.println("참조형 변수의 값을 다른 메소드에서 변경한 결과: " + arr[0]);
}
public void addOne(int value) {
value++;
}
public void addOne(int[] arr) {
for(int i = 0; i < arr.length; i++){
arr[i] ++;
}
}
}
기본형 타입은 다른 메소드에 매개변수로 전달될 때, 10이라는 값이 그대로 전달된다. 따라서 addOne에서 1을 더하더라도 value라는 변수에는 아무 영향이 없다.
하지만 참조형 타입은 다른 메소드에 매개변수로 전달될 때, 변수의 주소가 전달된다. 예를들어 '몇번째 박스에 값이 있다'는 식으로 값이 들어있는 주소가 전달된다. 그럼 그걸 전달받은 메소드 addOne에서는 그 박스에 가서 들어있는 값에 1 더한다. addOne을 실행하고 나서 arr[0]을 확인해 볼 때도 같은 박스에 가서 값을 확인하기 때문에 값이 11로 변해 있다.
객체 : 객체 지향 프로그램의 대상, 생성된 인스턴스
클래스 : 객체를 프로그래밍 하기위해 코드로 정의해 놓은 상태
인스턴스 : new 키워드를 사용하여 클래스를 메모리에 생성한 상태
멤버 변수 : 클래스의 속성, 특성
메서드 : 멤버 변수를 이용하여 클래스의 기능을 구현한 함수
참조 변수 : 메모리에 생성된 인스턴스를 가리키는 변수
참조 값 : 생성된 인스턴스의 메모리 주소 값