생성자
- 모든 클래스는 인스턴스화될 때 생성자를 사용
- 예: Car c1 = new Car( ); 에서 Car( )가 생성자
생성자의 특징
- 생성자는 리턴타입이 없음
- 생성자를 프로그래머가 만들지 않으면, 컴파일할 때 매개변수가 없는 생성자가 자동으로 만들어짐
- 컴파일 시에 만들기 때문에 코드로 나타나진 않음
- 매개변수가 없는 생성자를 기본생성자라고 함
- 생성자를 하나라도 프로그래머가 만들었다면 기본생성자는 자동으로 만들어지지 않음
생성자의 역할
- 생성자가 하는 일은 클래스가 객체가 될(인스턴스화) 때 필드를 초기화하는 역할을 수행
- Car가 객체가 될 때 반드시 이름을 가지도록 하려면, Car클래스에 다음과 같은 생성자를 만들어야 함
- 이름을 받아들일 수 있는 매개변수를 하나 받아서, 그때 받은 매개변수를 name필드에 넣어줌
- Car객체가 생성되면 name이 초기화될 것
public class Car{
String name;
int number;
public Car(String n){ //이름을 받아들일 수 있는 매개변수를 하나 받고
name = n; //그때 받은 매개변수를 name필드에 넣어줌
} //Car객체가 생성되면 name이 초기화될 것
}
- 위에서 매개변수 n로 정의한 생성자를 만들었기 때문에 Car클래스는 기본 생성자를 가지지 않음 >기본생성자로 Car 객체를 생성할 수 없음
- 매개변수 n로 정의한 생성자를 만들자마자, CarExam 클래스의 기본생성자에 오류 발생
- 위의 Car 클래스를 이용하여 Car 인스턴스를 생성하는 방법
- 정의한 생성자는 값을 받아와야 함 (생성자의 매개변수 데이터타입에 맞춰서)
- Car 객체를 생성할 때 필드 값이 생성자에 적은 값으로 초기화됨
public class CarExam2{
public static void main(String args[]){
Car c1 = new Car("소방차");
Car c2 = new Car("구급차");
*//Car c3 = new Car(); //컴파일 오류 발생*
System.out.println(c1.name); //Car 객체를 생성할 때 필드 값이 "소방차"로 초기화됨
System.out.println(c2.name); //Car 객체를 생성할 때 필드 값이 "구급차"로 초기화됨
}
}
실습
- Person클래스
class Person{
int age;
public Person(int a){
age = a;
}
}
- PersonExam클래스
//실행을 위한 코드입니다.
public class PersonExam {
public static void main(String[] args) {
//Person클래스에서 int형 변수를 매개변수로 받는 생성자를 호출합니다.
Person person = new Person(25);
}
}
this
객체 자신을 참조하는 키워드
this 의 사용
public class Car{
String name;
int number;
public Car(String n){
name = n;
}
}
- Car클래스의 생성자 매개변수의 이름이 n
- n 이라는 변수명은 무엇을 의미하는지 쉽게 알 수 없음
- n 보다는 name으로 사용하는 게 좋음
public Car(String name){
name = name; //필드 = 매개변수
}
- 'name=name' 이라고 코드를 바꾸면, 컴파일러는 가깝게 선언된 변수를 우선 사용
- 매개변수 name의 값을 매개변수 name에 대입하라는 의미로 변질됨
- 생성자에 인자를 넣었을 때 String클래스로 선언한 필드의 결과는 null이 되고, int 데이터타입으로 선언한 필드의 결과는 0이 됨
- 필드를 매개변수에 들어오는 인자로 바꾸려는 건데 위처럼 되면, 필드는 바뀌지 않음
- 매개변수 name의 값을 매개변수 name에 대입하라는 의미로 변질됨
- 이런 경우 필드라는 것을 컴파일러와 JVM에게 알려주기 위해 this키워드를 사용해야 함
public Car(String name){
this.name = name;
}
- 앞의 this.name은 필드 name을 말하고 =(이퀄) 뒤의 name은 매개변수를 의미
- 즉 매개변수의 값(인자)을 필드에 대입하라는 의미가 됨
클래스 안에서 this를 사용하는 경우
- 자기 자신이 갖고 있는 필드에 매개변수의 값을 대입할 때: this.필드명 = 매개변수명;
- 예: this.name = name;
- 자기 자신이 갖고 있는 메소드를 사용할 때: this.메소드명( )
- 자기 자신의 생성자를 호출할 때: this.생성자
- 예: this(”이름없음”, 0);
실습
- Person클래스
class Person {
String name;
int age;
public Person(String name, int age) {
// 매개변수로 받은 name과 age를 각각 name, age 필드에 저장하세요.
this.name = name;
this.age = age;
}
}
- PersonExam클래스
// 실행을 위한 코드입니다.
public class PersonExam {
public static void main(String[] args) {
// Person클래스에서 String과 int를 매개변수로 받는 생성자를 호출합니다.
Person person = new Person("사람", 25);
}
}
메소드 오버로딩
매개변수의 데이터타입이나 개수가 다른 경우, 같은 이름의 메소드를 여러 개 정의할 수 있게 하는 기술
메소드 오버로딩
- 이름은 같지만 매개변수가 다른 메소드
class MyClass2{
public int plus(int x, int y){
return x + y;
}
public int plus(int x, int y, int z){
return x + y + z;
}
public String plus(String x, String y){
return x + y;
}
}
- 메소드 오버로딩은 매개변수 부분이 반드시 달라야 함
public int plus(int i, int f){
return i+f; //오류
}
- 위처럼 변수명이 다르다고 해서 메소드 오버로딩을 사용할 순 없음 (메소드 오버로딩 조건을 충족하지 못함)
- 매개변수의 타입과 개수가 동일하기 때문에 동일한 메소드를 또 정의할 수 X
오버로딩된 메소드 이용하기
- 메소드의 인자에 어떤 값이 쓰이는지에 따라 각기 다른 메소드가 호출됨
public MethodOverloadExam{
public static void main(String args[]){
MyClass2 m = new MyClass2();
System.out.println(m.plus(5,10));
System.out.println(m.plus(5,10,15));
System.out.println(m.plus("hello" + " world"));
}
}
실습
- Car클래스
class Car {
void run() {
System.out.println("차가 달립니다.");
}
// 정수 하나를 매개변수로 받는 메소드, run을 추가해 보세요.
public void run(int x){
}
}
- CarExam클래스
// 실행을 위한 코드입니다.
public class CarExam {
public static void main(String[] args) {
// Person클래스에서 String과 int를 매개변수로 받는 생성자를 호출합니다.
Car car = new Car();
car.run();
// int형 매개변수를 받는 run을 호출합니다.
car.run(100);
}
}
메소드 오버로딩과 this
생성자 오버로딩
- 생성자의 매개변수의 유형과 개수가 다르게 해서 같은 이름의 생성자를 여러 개 가질 수 있음
- 생성자도 메소드와 마찬가지로 여러 개를 선언할 수 있음
- 매개변수의 수와 타입이 다르다면 여러개의 생성자를 선언할 수 있음
public class Car{
String name;
int number;
//기본생성자로 Car객체를 만들고 싶다면 Car클래스에 기본생성자를 정의해두면 됨
**public Car(){
}**
public Car(String name){
this.name = name;
}
public Car(String name, int number){
this.name = name;
this.number = number;
}
}
- 매개변수가 있는 생성자가 있을 경우, 기본생성자로 객체를 정의하면 오류 발생
- 클래스에 기본생성자를 정의해두면 오류가 해결됨
오버로딩된 생성자 이용하기
public class CarExam4{
public static void main(String args[]){
Car c1 = new Car();
Car c2 = new Car("소방차");
Car c3 = new Car("구급차", 1234);
}
}
자기 생성자 호출하는 this( )
- 기본생성자를 호출했을 때 name을 "이름없음" , 숫자를 0으로 초기화하기
public Car(){
this.name = "이름없음";
this.number = 0; //밑의 코드와 중복됨
}
public Car(String name, int number){
this.name = name;
this.number = number;
}
- 위처럼 작성했을 경우 기본생성자와 매개변수가 있는 생성자에서 코드 중복이 발생
- 자신이 가지고 있는 다른 생성자를 이용할 수 있음
public Car(){
//this.name = "이름없음";
//this.number = 0;
this("이름없음", 0); //이렇게 쓰면 중복을 피할 수 있음
}
- this( ): 자신의 생성자를 호출하는 것
- 자기 자신의 생성자를 호출함으로써 비슷한 코드가 중복돼서 나오는 것을 방지할 수 있음
실습
- Car클래스
public class Car {
String name;
int number;
public Car(){
this("이름없음", 0);
}
public Car(String name){
this(name, 0);
}
public Car(String name, int number){
this.name = name;
this.number = number;
}
}
- CarExam클래스
// 실행을 위한 코드입니다.
public class CarExam {
public static void main(String[] args) {
Car car1 = new Car();
Car car2 = new Car("자동차");
Car car3 = new Car("자동차", 1234);
}
}
패키지
- 서로 관련이 있는 클래스 또는 인터페이스들을 묶어놓은 묶음
- 패키지를 사용함으로써 클래스들이 필요할 때만 사용될 수 있게 함
- 클래스를 패키지 이름과 함께 계층적인 형태로 사용
- 다른 그룹에 속한 클래스와의 관계에서 생길 수 있는 클래스 이름 간의 충돌을 방지하므로 클래스의 관리를 편하게 해줌
패키지 정의 방법
- package이름은 보통 도메인 이름을 거꾸로 적은 후, 그 뒤에 프로젝트 이름을 붙여서 만듦
- 물론, 프로젝트 이름 뒤에 또 다른 이름이 나올 수도 있음
- 도메인으로 사용하는 이유는 패키지가 중복되는 것을 방지하기 위함이므로, 반드시 존재하는 도메인이 아니라도 상관없음
- package이름은 ‘ 폴더명.폴더명.폴더명 ‘ 과 같은 형식으로 만들어짐
- 각각의 폴더명은 숫자로 시작할 수 없음
- 예시
- com.eightcruz.javastudy.Hello로 패키지를 지정
- 도메인명: 8cruz.com, 프로젝트명: javastudy, 클래스명: Hello
- 도메인이 숫자로 시작되는데 패키지명은 첫 글자에 숫자를 사용할 수 없으므로 eightcruz처럼 적절하게 수정
- com.eightcruz.javastudy.Hello로 패키지를 지정
이클립스에서 패키지 생성하기
- src폴더를 선택한 후 우측버튼을 클릭하여 패키지 생성을 선택
- 패키지 이름에 com.eightcruz.javastudy를 입력
- 해당 패키지를 선택하고 Hello클래스 생성
- 작성된 클래스 파일의 첫 줄에 package com.eightcruz.javastudy; 생성된 것을 볼 수 있음
- 패키지를 생성하는 예약어는 package
패키지에 생성된 클래스 사용하기 (import)
- java.lang패키지를 제외하고는 다른 패키지에 있는 클래스를 사용하려면 import라는 구문을 적어줘야 함
- import com.eightcruz.javastudy.Hello;
- 위의 코드는 com.eightcruz.javastudy패키지 아래의 Hello클래스를 사용한다고 컴파일러와 JVM에게 알리는 것 (import문을 쓰지 않으면 컴파일 오류 발생)
- 클래스 이름 대신에 * 를 적어도 됨 (패키지 전체를 import하겠다는 뜻)
- import com.eightcruz.javastudy.*;
- * import 단축키: Ctrl + Shift + O
- 객체를 생성한 후에 누르면 자동으로 해당 패키지의 클래스가 import됨
package javaStudy.part6;
import com.eightcruz.javastudy.Hello; //2. 자동으로 패키지의 클래스가 import됨
//Hello 클래스명 대신 *를 사용해도 됨
public class HelloExam {
public static void main(String[] args) {
Hello hello = new Hello(); //1. 이렇게 객체 생성 후 **Ctrl + Shift + O 누르면**
}
}
import하지 않고 사용하는 방법
- 만약 import를 하기 싫거나, 각기 다른 패키지에 존재하는 같은 이름의 클래스 파일을 사용해야 한다면 클래스 경로 전체를 객체로 생성해 사용
- com.eightcruz.javastudy.Hello hello = new com.eightcruz.javastudy.Hello();
- 클래스를 쓸 때마다 패키지명을 전부 써줘야 함
'☕ Java 웹 프로그래밍 > Java' 카테고리의 다른 글
[프로그래머스] Java(자바) 입문 | Part 8. 인터페이스와 다른 형식의 클래스 (0) | 2023.05.06 |
---|---|
[프로그래머스] Java(자바) 입문 | Part 7. 상속 (2) | 2023.05.03 |
[프로그래머스] Java(자바) 입문 | Part 5. 클래스와 객체 (0) | 2023.05.02 |
Java | 클래스, 객체, 인스턴스, 인스턴스화 (0) | 2023.05.01 |
[프로그래머스] Java(자바) 입문 | Part 4. 배열 (0) | 2023.04.28 |