p. 155
생성자는 메서드가 아니다.
- 복합연산대입자는 형변환을 자동으로 해줌
- 자바 웹 컴파일 사이트 Hashcode
메소드 오버로딩 : 클래스 내부에 이름이 같은 메서드가 복수 개 존재하는 현상.
대표 예시) println()
목적 : 만들어진 코드가 불러쓰기 편하도록 하기 위함 (쓰는 사람 입장)
코딩은 협업 + 객체지향언어 특징=재사용성 => 같이 쓰고 다시 쓰기 편하게 만들자!
- 컴파일 가능 코드
/* 메서드 구분 기준 1. 이름 2. parameter 정보(개수, type, 순서) (return 정보, 접근제한자는 구분 기준이 아님) */ class Some { void doit(){ } void todo(){ } void todo(int n){ } void todo(String s){ } void todo(int n, String s){ } void todo(String s, int n){ } } class Ex1 { public static void main(String[] args) { System.out.println(1); // 자료형 int, boolean, String, char 모두 OK System.out.println(false); System.out.println("abc"); System.out.println('h'); } }
- 에러 코드
class Some { void todo(){ } void todo(){ return 1; } public void todo(String s){ } private void todo(String s){ } void todo(String t){ } } class Ex1 { public static void main(String[] args) { } }
- 왜 메소드를 이름으로만 구분하지 않을까?
예를 들어 int 2개 합은 sum, double 2개 합은 plus, char와 int 합은 result ...라면
비슷한 기능을 하는 메소드를 전부 다른 이름으로 정의한다면, 필요할 때 불러와서 쓰기 어렵다.
(이름으로 기능은 알 수 있어도, 기능을 고려해서 이름 불러오기는 어렵다는 것)
Some s1 = new Some();
// 객체 생성 -> 'type + 변수 = new + 생성자 호출'
지금까지는 객체 생성 후 직접 멤버 변수를 설정하고(=초기화하고) 시작함
생성자란 객체를 사용하기 위해 필요한 사전 작업(=초기화)를 진행하는 (공간?)
return값 절대 없음 자료형 표시x, 클래스와 같은 이름 + () 해주면 됨
class Car {
int price;
String color;
String model;
}
class UseCar(){
public static void main(String[] args){
Car c = new Car();
c.price = 40000000;
c.color = "black";
c.model = "sonata";
}
}
생성자를 이용하면 아래와 같이 간단히 쓸 수 있다.
class Car {
int price;
String color;
String model;
Car(String newModel, String newColor, int newPrice){
model = newModel;
color = newColor;
price = newPrice;
}
public String toString(){
return model + "(" + color + ", " + price + ")";
}
}
class UseCar(){
public static void main(String[] args){
Car c1 = new Car("sonata", "black", 40000000);
Car c2 = new Car("s600", "white", 230000000);
System.out.println(c1);
System.out.println(c2);
}
}
Car(){
} // 기본 생성자
new로 객체 생성
생성자로 값 넣어줌 (쓸 수 있는 값으로 변경해줌)
즉 new Car()는 만들고 나서 사용자에게 전달되기 전 과정이라고 생각하는 게 맞음
new + 생성자() 실행하자마자 초기화는 끝!!! 엄밀히 말하면 생성자가 초기화하는 게 아님!
/*
생성자와 메서드의 차이점
1. 호출시기: 생성자는 객체 생성할 때만(new 뒤에서만) 가능
2. 생성자는 리턴이 없다. (void의 의미가 아님, 아예 리턴 기능이 없음!)
생성자 수 : 객체를 만들 수 있는 경우의 수
생성자 수 + 파라미터를 통해 (사용자=다른 개발자한테) 제공해야 하는 정보를 강제할 수 있다.
*/
class Human {
String name;
int age;
Human(String newName, int newAge){
setName(newName);
age = newAge;
}
Human(String newName){
setName(newName);
}
void setName(String newName){
name = newName;
}
}
class UseHuman {
public static void main(String[] args) {
Human h = new Human("아이유", 29);
}
}
변수는 type과 scope로 구분 가능
scope에 따라 멤버변수('객체'), 지역변수('메소드')
속해있는 scope가 다르면 같은 이름의 변수 선언도 가능하다!
(왜? 구분할 수 있으니까)
멤버변수와 지역변수는 'this'로 구분할 수 있다.
????
외부에서 지역변수 접근 못함
객체명 d는 멤버변수만 접근 가능
this로 멤버변수, 메소드 접근 가능
this는 메소드 안에서만 쓸 수 있다
Human(String name, int age){
this(name);
this.age = age;
}
- this()는 사실 잘 쓰지 않는다. 생성자의 첫 연산이어야 하는 것이 또 있는데, this()는 다르게 해결할 수 있는 반면 그건 대체 불가능하기 때문
- 생성자를 호출한 횟수와 생성된 객체의 개수는 같지 않다.
생성자가 n번 호출된 것으로 알 수 있는 것은 -> 어쨌든 객체 1개는 만들어졌다는 것뿐!
/*
this
- 객체 자신의 주소값을 나타내는 키워드.
this(...)
- 자신의 다른 생성자
*/
class Human {
String name;
int age;
Human(String name) {
this.name = name;
}
/*
this()
1. 생성자 내부에서만 사용가능
2. 생성자의 첫 연산이어야 한다.
*/
Human(String name, int age) {
this(name);
this.age = age;
}
public String toString() {
return name + " : " + age;
}
void printHumanInfo() {
System.out.println(this);
}
}
class UseHuman {
public static void main(String[] args) {
Human h = new Human("아이유", 29);
//h.setName("에일리");
System.out.println(h);
h.printHumanInfo();
}
}