생성자
- 인스턴스를 생성할 때 사용한다
- 어떤 값을 가지고 인스턴스가 만들어지게 하고 싶다면 생성자를 사용한다.
- 클래스 작성시 생성자를 하나도 만들지 않았다면 자동으로 기본 생성자가 생성된다.
- 기본 생성자는 매개변수를 하나도 받지 않는 생성자를 말한다.
public Car(){
System.out.println("자동차가 한 대 생성됩니다");
}
생성자는 메소드와 비슷하다
return type이 없다. 클래스 이름과 같아야 한다.
접근 제한자 다음에 바로 클래스명이 나온다.
매개변수가 0개인 생성자를 기본 생성자라고 한다.
생성자가 하나도 없으면 아무일도 안하는 기본 생성자가 자동으로 컴파일타임에 만들어진다.
이름을 가진 인스턴스가 만들어지고, 이름을 출력하고 싶으면 다음과 같이!
private String name; // 필드에 선언되어있어야 한다. 왜냐면 필드는 가지는 것.
public Car(String name){
this.name = name;
}
public void printName(){
System.out.println("자동차이름 : "+name);
}
Car class
public class Car {
private String name;
public Car(){
System.out.println("자동차 한대 생성!");
}
public Car(String name){
this.name=name;
}
public void printName(){
System.out.println("자동차이름 : "+name);
}
public void run(){
System.out.println("전륜구동으로 달리다");
}
@Override
public String toString() {
return "자동차";
}
}
CarExam
public class CarExam2 {
public static void main(String[] args){
Car c1 = new Car();
System.out.println(c1); //println(Object x)
c1.printName();
Car c2 = new Car("BMW");
System.out.println(c1);
c2.printName();
}
}
결과
자동차 한대 생성!
자동차
자동차이름 : null
자동차
자동차이름 : BMW
(alt + insert = 생성자 만들기-> 인스턴스를 생성할 때 입력할 필드를 선택)
불변객체 : 태어날 때 이런 값을 가지고 태어나고, 외부에 전달할 때 사용 ex) String
생성자 오버로딩
public class User {
private String email;
private String password;
private String name;
//생성자를 하나라도 만들게 되면 기본 생성자가 자동으로 안 만들어진다.
public User(String name,String email) {
this.email = email;
this.name = name;
}
//생성자 오버로딩.
public User(String name,String email, String password) {
this.email = email;
this.password = password;
this.name = name;
}
// setter없이 getter만 있다 : 불변객체
public String getEmail() {
return email;
}
public String getPassword() {
return password;
}
public String getName() {
return name;
}
}
생성자를 오버로딩할 때는 파라미터 순서를 맞춰준다.
private 변수에 접근하기 위해 getter 메소드를 생성했다.
public class UserExam {
public static void main(String[] args) {
User user = new User("김성박", "hello@com");
System.out.println(user.getName());
System.out.println(user.getEmail());
User user2 = new User("홍길동", "merong@com", "1234");
System.out.println(user2.getName());
System.out.println(user2.getEmail());
System.out.println(user2.getPassword());
}
}
결과
김성박
hello@com
홍길동
merong@com
1234
toString() 메소드를 오버라이딩 해서 번거롭게 getter 쓰지 않기
public class User {
private String email;
private String password;
private String name;
//생성자를 하나라도 만들게 되면 기본 생성자가 자동을 안 만들어진다.
public User(String name,String email) {
this.email = email;
this.name = name;
}
//생성자 오버로딩.
public User(String name,String email, String password) {
this.email = email;
this.password = password;
this.name = name;
}
//객체의 변수명을 println하면 나오는 값들 override 함 -> getter을 귀찮게 안 써도 됨
@Override
public String toString() {
return "User{" +
"email='" + email + '\'' +
", name='" + name + '\'' +
'}';
}
}
public class UserExam {
public static void main(String[] args) {
User user = new User("김성박", "hello@com");
System.out.println(user);
User user2 = new User("홍길동", "merong@com","1234");
System.out.println(user2);
}
}
결과
User{email='hello@com', name='김성박'}
User{email='merong@com', name='홍길동'}
생성자를 오버로딩할 때 중복을 피하는 방법
public User(String name,String email) {
this.email = email;
this.name = name;
}
//생성자 오버로딩.
public User(String name,String email, String password) {
this.email = email;
this.password = password;
this.name = name;
}
위의 코드에서 중복되는 부분이 길어지게 된다면 불 필요한 낭비가 생긴다. 따라서 아래와 같이 바꾼다.
// 자신의 생성자 참조
public User(String name,String email) {
this(name, email, null);
}
public User(String name,String email, String password) {
this.email = email;
this.password = password;
this.name = name;
}
많이 받아들이는 쪽을 this 생성자로 로 호출해주는 게 좋다. 즉, 참조할 생성자에 정보가 많을 수록 좋다 ㅇㅇ.
this 생성자는 슈퍼생성자를 제외하고 첫번째 줄에 나와야 한다.
생성자 오버로딩
생성자는 매개변수의 개수가 다르거나, 타입이 다르다면 여러개를 가질 수 있다.
자신의 생성자를 호출할 때 this()를 사용한다
- this는 인스턴스 자기 자신을 참조할 때 사용하는 키워드
- this() 생성자는 자기 자신의 생성자를 말한다
- this() 생성자는 생성자 안에서만 사용가능하다
- this() 생성자는 생성자 안에서 super() 생성자(부모생성자)를 호출하는 코드 다음이나, 첫번째 줄에 위치해야 한다
부모의 생성자를 호출할 때는 super()을 사용한다
- super은 인스턴스 부모를 참조할 때 사용하는 키워드
- super() 생성자는 부모 생성자를 의미한다.
- super() 생성자는 생성자 안에서만 사용가능하다.
- super() 생성자는 생성자 안에서 무조건 첫번째 줄에만 올 수 있다.
- 생성자는 무조건 super() 생성자를 호출해야 한다. 사용자가 super() 생성자를 호출하는 코드를 작성하지 않았다면 자동으로 부모의 기본 생성자가 호출된다. (부모가 기본생성자를 가지지 않을 때 오류발생)
- 부모클래스가 기본 생성자를 가지고 있지 않다면, 사용자는 반드시 직접 super() 생성자를 호출하는 코드를 작성해야 한다.
super() 이해하기
public class Car2 {
public Car2(){
super(); // 자동으로 들어간다
System.out.println("Car2() 생성자 호출");
}
}
Car2를 상속받는 Bus2 클래스 생성
public class Bus2 extends Car2{
}
public class Car2Exam {
public static void main(String[] args){
Car2 c1 = new Car2();
Bus2 b1 = new Bus2();
}
}
결과
Car2() 생성자 호출
Car2() 생성자 호출
Car2를 상속받는 Bus2의 객체를 만들었더니 부모의 (기본)생성자가 호출되었다.
why?
자식이 Bus2 클래스에 생성자를 호출하지 않으면 컴파일 시 자동으로 부모의 (기본)생성자가 호출된다. 즉
public class Bus2 extends Car2{
public Bus2(){
super(); // 자동으로 들어간 부모의 (기본)생성자
}
}
물론
public class Bus2 extends Car2{
public Bus2(){
System.out.println("Bus2 기본 생성자");
}
}
이렇게 자식 클래스에 생성자를 넣어주어도 부모의 (기본)생성자는 호출된다.
다음과 같이 삽입 되는 것.
public class Bus2 extends Car2{
public Bus2(){
super(); // 자동 삽입
System.out.println("Bus2 기본 생성자");
}
}
결과
Car2() 생성자 호출
Car2() 생성자 호출
Bus2 기본 생성자
원래 생성자를 하나라도 만들어주면 기본 생성자는 안만들어진다
따라서 자식의 객체가 만들어질 때 호출할 부모의 기본생성자가 없으니 반드시 자식의 클래스에 부모의 생성자 값을 넣어줘야 한다. 다음과 같다.
public class Bus2 extends Car2{
public Bus2(){
super("Bus!!");
// 부모가 기본생성자를 생성하지 않았을 때 반드시 부모생성자에 파라미터 값을 넣어서 적어줘야 한다.
System.out.println("Bus2 기본 생성자");
}
}
'프로그래밍 > java' 카테고리의 다른 글
12. final 클래스, 불변객체 String (0) | 2023.09.06 |
---|---|
11. java 템플릿 메소드 패턴 (0) | 2023.05.23 |
8. java 상속, 오버라이딩, getter&setter (0) | 2023.04.10 |
7. java 패키지 (0) | 2023.04.10 |
6. java 클래스 잘 만들기 (0) | 2023.04.10 |
댓글