객체가 생성될 때 가지고 있어야 할 기본 값 (객체 초기화값)이나 수행될 코드를 정의하는 method 일종
반환형이 없다.
Overload 지원(객체 생성을 다양하게 할 수 있다)
클래스명과 동일하게 만든다
개발자가 생성자를 하나도 정의하지 않으면 Compiler가 매개변수 없는 기본생성자(Default Constructor)를 생성해준다.
접근지정자는 class의 접근지정자를 따라간다.
객체 생성할때만 호출된다.
method 호출하듯이 직접 호출할 수 없다.
this를 사용하면 내 클래스의 다른 생성자를 호출할 수 있다.
접근지정자 생성자명(parameter...) {}// 생성자의 접근지정자public - 클래스 외부에서 객체 생성가능protected - 동일 패키지 다른 클래스에서만 객체생성가능 패키지가 다르다면 자식클래스만 객체생성가능private - 클래스안에서만 객체 생성가능(singleton pattern 적용)default - 동일 패키지 다른 클래스에서만 객체생성가능 패키지가 다르다면 객체생성불가능
public class Marker { ... public Marker() { color = "검은색"; cap = 1; body = 1; } public Marker(String color, int cap, int body) { this.color = color; this.cap = cap; this.body = body; } ...}
// 클래스명 객체명 = new 생성자();Marker m = new Marker(); // 기본생성자 - 검은색 마카펜m.setColor("빨간색"); // 검은색->빨간색 심교체..// 그냥 첨부터 빨간펜을 만들자!Marker r = new Marker("빨간색",1,1); // setter를 안불러도 되므로 코드가 짧아짐// => 생성자 오버로딩(다형성)
public class TestConstructor { public TestConstructor() { System.out.println("기본 생성자"); } public TestConstructor(int i) { System.out.println("인자있는 생성자 : "+i); } public void test() { System.out.println("test method"); temp(); // 생성자는 메소드 호출하듯 호출할 수 없다. // TestConstructor(); } public void temp() { System.out.println("----temp method"); } public static void main(String[] args) { // Overloading된 생성자를 사용하여 객체화를 다양하게 할 수 있음 TestConstructor tc = new TestConstructor(); // 기본 생성자 System.out.println(tc); TestConstructor tc1 = new TestConstructor(2); // 인자있는 생성자 System.out.println(tc1); tc.test(); }}
public class Test { public Test() { // 호출순서 2, 4 this(11); ... } public Test(int i) { // 호출순서 3 ... }}...// Test 객체를 사용하기위해 다른 클래스에서 객체 생성 시 호출Test t = new Test(); // 호출순서 1, 5
public class ThisConstructor { public ThisConstructor() { this(26); System.out.println("기본 생성자"); } public ThisConstructor(int i) { System.out.println("인자있는 생성자 i:"+i); // this는 생성자의 첫번째 줄에서만 사용가능 // this(); // error! } public static void main(String[] args) { // 객체를 저장해서 사용할 일이 없을 때 이렇게 사용 new ThisConstructor(); }}
public class Marker { ... public Marker() { // 인자 있는 생성자를 호출하여 값 설정(코드량 감소) this("검은색",1,1); // color = "검은색"; // body = 1; // cap = 1; } public Marker(String color, int cap, int body) { this.color = color; this.body = body; this.cap = cap; } ...
call by value
method의 매개변수를 기본형 데이터형으로 정의하면 값이 복사되어 넘어간다.
값 전달
public class Test { // swap 메소드 호출 시 i,j 값은 복사되어 들어간다 public void swap(int i, int j) { int temp = 0; temp = i; i = j; j = temp; } public static void main(String[] args) { int i=100, j=300; System.out.println(i+" "+j); // 100 300 Test t = new Test(); t.swap(i,j); System.out.println(i+" "+j); // 100 300 }}
call by reference
method의 매개변수를 참조형 데이터형으로 정의하면 하나의 주소가 그대로 전달된다.
주소 전달
public class Test2 { int i; int j; public void swap(Test2 t) { int temp = 0; temp = t.i; t.i = t.j; t.j = temp; } public static void main(String[] args) { Test2 t2 = new Test2(); t2.i = 100; t2.j = 300; System.out.println(t2.i+" "+t2.j); // 100 300 t2.swap(t2); System.out.println(t2.i+" "+t2.j); // 300 100 }}
this의 keyword 형식
생성된 객체의 주소를 저장한 keyword
static 영역안에서는 사용할 수 없다
this.변수명;this.method명();
public class ThisKeyword { int i; // 인스턴스변수와 파라미터 변수가 같기 때문에 객체를 넘겨받아 구분하는 것 public void useInstance(int i, ThisKeyword t) { // 파라미터 변수의 값을 인스턴스변수에 할당하겠습니다. // == stack의 값을 heap의 값으로 올리겠습니다. System.out.println("전달받은 객체 t:"+t); t.i = i; } // Call By Reference로 객체를 매번 넘기는 걸 안하기 위해서 this를 사용 public void useThis(int i) { // this는 메소드를 호출하는 객체의 주소로 바뀐다. // 매개변수로 객체를 받을 필요가 없다. this.i = i; System.out.println("메소드를 호출한 객체의 주소 : "+this); } public static void test() { // static method 안에서는 this 키워드를 사용할 수 없다. // this.i = 10; // error! System.out.println("static method"); } public static void main(String[] args) { ThisKeyword tk = new ThisKeyword(); System.out.println("생성된 객체 tk:"+tk); tk.useInstance(10, tk); System.out.println("전달한 객체의 인스턴스변수의 값 "+tk.i); System.out.println("==========================================="); tk.useThis(3300); System.out.println("this를 사용하여 변경한 인스턴스변수의 값 "+tk.i); ThisKeyword.test(); }}
문자열
문자열 != String
"로 묶여있는 여러 글자들
문자열은 "문자열 저장소"라는 literal에 생성
같은 문자열은 하나만 생성되고 그 주소를 사용하게된다.
문자열을 저장하고 사용하기 위한 class로 java.lang패키지에 String 제공
String class에서 제공하는 모든 method를 사용가능
String
참조형 데이터형
문자열 저장소의 주소를 저장할 수 있는 데이터형
기본형 형식, 참조형 형식 두가지로 사용가능
객체에 == 을 사용하면 주소가 같은지 비교
기본형 형식으로 만들면 literal를 참조하여 같은 문자열인지 비교할 수 있다.
참조형 형식으로 만들면 heap을 참조하여 같은 문자열인지 비교할 수 없다.
equals method를 사용하면 객체 내 주소를 비교하는 기능을 수행
기본형이나 참조형 형식 모두 같은지에 대한 비교를 할 수 있다.
// 기본형 형식 (new를 사용하지 않음)String name = "young";// 참조형 형식 (new를 사용)String name = new String("young");
public class TestString { public static void main(String[] args) { // 기본형 형식의 사용 String str1 = "ABC"; // 기본형 형식으로 선언한 문자열은 문자열 저장소의 주소를 저장하기 // 때문에 == 비교로 같은지 비교수행할 수 있다. if (str1 == "ABC") { System.out.println("기본형 == 같음"); } else { System.out.println("기본형 == 다름"); } // 참조형 형식의 사용 String str2 = new String("ABC"); // 참조형 형식으로 사용하면 변수는 heap주소를 저장하고 // heap에 만들어진 객체가 문자열 저장소의 주소를 저장한다. if (str2 == "ABC") { System.out.println("참조형 == 같음"); } else { System.out.println("참조형 == 다름"); } System.out.println("----------------------"); if (str1.equals("ABC")) { System.out.println("기본형 equals 비교 같음."); } else { System.out.println("기본형 equals 비교 다름."); } if (str2.equals("ABC")) { System.out.println("참조형 equals 비교 같음."); } else { System.out.println("참조형 equals 비교 다름."); } }}
숙제풀이
지난 시간에 만든 라면 클래스에 기본 생성자와 인자있는 생성자를 정의한 후 해당 생성자를 사용하여 객체를 생성하고 사용해보세요.