6. 클래스

6.6 필드의 선언과 사용

6.6.1 필드 선언

필드는 객체의 데이터를 저장하는 역할 객체의 데이터에는 고유데이터 /현재 상태 데이터 수시로 변경 예) 차속도/부품데이터 자동차를 만드는 부품 가 있다.
데이터들 필드 선언 변수와 동일하지마 필드라고 한다.
필드타입 필드명 [=초기값]; //[]생략가능하다는 뜻

필드와 변수의 차이점
선언위치 필드 클래스 선언블록 / 변수 생성자 메소드선언블록 -> 클래스선언블록에서 선언한거 제외하고는 전부다 변수임.
존재위치 객체 내부에 존재 / 생성자 메소드 호출시에만 존재(잠깐만들어지고 없어지는 존재임.)
사용위치 객체 내외부 어디든사용 / 생성자 메소드 블록내부에서만 사용.

타입은 필드에 저장할 데이터의 종류를 결정 기본타입(byte short int long float double boolean)와 참조타입(배열 클래스 인터페이스) 모두 가능
필드명은 첫문자를 소문자로 하되 캐멀스타일(변수처럼)
String model = "그랜져"; // 고유데이터 필드
int speed = 300; // 상태데이터필드
boolean strat = true;
Tire tire = new Tire(); // 부품객체 필드

설계도에 초기값이 들어가잇으면 이걸로 객체를 만들면 초기값이 들어가잇음.
초기값 제공하지 않으면 자동으로 기본값으로 초기화된다.
String model; // null
int speed; // 0
boolean strat; // false
Tire tire; // null

Car myCar = new Car(); //받을 변수 만들기 <- 뒤먼저 쓰고

//Car 객체의 필드값 읽기
System.out.println("모델명: " + myCar.model);
System.out.println("시동여부: " + myCar.start);
System.out.println("현재속도: " + myCar.speed);


필드선언할때 초기값을 줄수도 잇고 안줄수도잇는데 굳이 넣을필요는 없음.

6.6.2 필드사용

필드를 사용한다는 것은 필드값을 읽고 변경하는 것을 말한다.
클래스에서 필드를 선언한다고 바로 사용할 수 있는 것은 아님.
필드는 객체데이터이므로 객체가 존재하지 않으면 필드도 존재하지 않는다.
1.생성자 블록안에서 필드의 값을 읽거나 변경하기
2.메소드 블록안에서 하기.
3.외부객체에서 생성 변경하기 객체 외부에서는 변수.객체(도트연산자)로 가기

Car myCar = new Car(); // Car타입의 변수에 저장한다.<- new 번지생성 객체생성연산자

System.out.println("제작회사: " + myCar.company); //myCar로 객체로 가서 불러온다. 
System.out.println("모델명: " + myCar.model);
System.out.println("색깔: " + myCar.color);
System.out.println("최고속도: " + myCar.maxSpeed);
System.out.println("현재속도: " + myCar.speed);

//Car객체의 필드값 변경
myCar.speed = 60;
System.out.println("수정된 속도: " + myCar.speed);

6.7 생성자 선언과 호출

객체를 생성할때 생성자를 이용함. 클래스이름(){}생성자호출 / 클래스 변수 = new 클래스()(이부분이 생성자호출); 결국클래스(){이부분이 실행되는거임
생성자 호출이란 생성자의 블록을 실행시키는 것을 의미한다.
new연산자는 객체를 생성한 후 생성자를 호출해서 객체를 초기화하는 역할을 한다.
객체를 부르고 객체를 이용할수있도록 '준비'하는 것= 객체 초기화 객체초기화역할을 담당하는 것이 '생성자'이다.
객체초기화란 필드 초기화하거나 메소드를 호출해서 객체를 사용할 준비를 하는것임.

기본 생성자 public(얘는 있을수도 있고없을수도) 클래스() {} 작성안하면 컴파일단계에서 자동적으로 만들어줌.
public붙은 클래스면 자동생성자에도 있음 아니면 없음.
이거를 볼수잇느냐? 이크립스 내부에서 볼수잇음 window show view Navigator 보면 바이트코드파일이 보임. 사진참조
바이트코드 파일 형태는 소스파일 코드와 다름 자바 가상 머신(JVM)이 이해할수잇는 모양으로 자동생성됨.

6.7.1 생성자 선언

안해도 알아서 되지만 개발자가 명시적으로 생성자를 선언하는 경우가 더 많다.
클래스(매개변수, ...) {}-> ()는 생성자를 선언하기 위해 필요한 데이터
Car mycar = new Car("그랜저", "검정", 300);
Car(String model(매개변수), String color(매개변수), int maxSpeed){...}

Car mycar = new Car("그랜저", "검정", 300); // 각각 매개변수에 저장이되어서 사용할 수 있다. 매개변수의 수만큼 안넣으면 컴파일에러발생
Car mycar = new Car() 기본생성자 호출 못함.

6.7.2 필드초기화

생성자 {}안에 뭔가해야하는 게 들어가야함.
그래서 필드 초기화가 나옴 필드에 값을 최초로 넣는 행위 언제?
1.클래스 선언시(sec06에서 초기값 넣음.) -> 모든 객체가 다 동일할 경우
2.객체를 만들때(sec07우리가 준값으로 넣기) -> 객체마다 다 다른값을 가져야 하는경우 예를들어 사람마다 주민번호가 다름.

//Korean 객체
public class Korean {
//필드선언
String nation = "대한민국"; 대한민국사람이면 다 대한민국임.
String name; // 이름과 주민번호는 다 다름. 이래서 여기서 초기값주면안됨.
String ssn;

//생성자 선언
    public Korean(String n, String s) {
    name = n;
    ssn = s;
    }

실행파일에서 Korean k1 = new Korean("박자바", "011225-1234567"); 하면 앞에거 n에 뒤에거는 s에 들어감

//korean객체생성
Korean k1 = new Korean("박자바", "011225-1234567");
System.out.println("k1.nation : " + k1.nation);
System.out.println("k1.name : " + k1.name);
System.out.println("k1.ssn : " + k1.ssn);

Korean k2 = new Korean("김자바", "930525-0654321");
System.out.println("k2.nation : " + k2.nation);
System.out.println("k2.name : " + k2.name);
System.out.println("k2.ssn : " + k2.ssn);

위 예제에서 매게변수이름으로 각각 n과 s를 사용햇는데 매게 변수의 이름이 너무짧으면 코드 가독성이 좋지 않기때문에 가능하면 초기화시킬 필드명과 동일한 이름을 사용하는것이 좋다.

생성자를 생설할때 필드이름과 똑같이 주는 경우 외부에서 받은 변수값을 바로 저장하기 위한 목적이라면 이름과 필드 이름을 같게만들어라.
문제점? name = name 이면 앞에거를 필드로 생각하느냐? 아님.
내가 나를 부를때? this라고함. this.필드 내가 가지고 있는 필드로 표현해줘야함.
this.필드 = 매개변수 매개변수를 필드에 저장해야한다. name = name 이면 매개변수 = 매개변수로 이해해버림.

public Korean(String name, String ssn) {
this.name = name; 
this.ssn = ssn;
}
//여기서 잠깐 이클립스는 필드의 색은 파란색, 매개변수의 색을 갈색으로 보여주기 때문에 매개변수를 쉽게 구별할 수잇다.

6.7.3 생성자 오버로딩

매개변수를 달리하는 생성자를 여러개 만들수잇다 이것이 생성자 오버로딩(Overloading)임.
매개변수 타입 개수 순서가 다르게 여러개의 생성자 선언
순서만 바꾸는거는 아님.
public class Car{
Car(){...}
Car(String model){...}
Car(String model, String color){...}
Car(String model, String color, int maxSpeed){...}}

타입이 같을경우 단순히 순서만 다른거는 안됨
public Car(String model, String color){...}
public Car(String color, String model){...}

타입이 다르면 다르게 인식해서 괜찮음.
public Car(int speed, String model){...}
public Car(String model, int speed){...}

왜 이렇게 하나?
매개값으로 다양하게 객체의 필드를 초기화하기 위해서
예를들어 이름만 넣거나 이름과 속도 이름과 색등을 만들고 싶을때 사용

Car(){}

Car(String model){
    this.model = model;    
    }

Car(String model, String color){
    this.model = model;
    this.color = color;
}

Car(String model, String color, int maxSpeed){
    this.model = model;
    this.color = color;
    this.maxSpeed = maxSpeed;
}

//오버로딩 실습.
Car car1 = new Car();//생성자 호출
System.out.println("car1.company: " + car1.company);
System.out.println();

Car car2 = new Car("자가용");//생성자 호출
System.out.println("car2.company: " + car2.company);
System.out.println("car2.model: " + car2.model);
System.out.println();

Car car3 = new Car("자가용", "빨강");//생성자 호출
System.out.println("car3.company: " + car3.company);
System.out.println("car3.model: " + car3.model);
System.out.println("car3.model: " + car3.color);
System.out.println();

Car car4 = new Car("자가용", "빨강", 200);//생성자 호출
System.out.println("car3.company: " + car4.company);
System.out.println("car3.model: " + car4.model);
System.out.println("car3.model: " + car4.color);
System.out.println("car3.model: " + car4.maxSpeed);
System.out.println();

6.7.4 다른 생성자 호출

생성자 오버로딩이 많아질경우 생성자 간의 중복된 코드가 발생할 수있다.
매개변수의 수만 달리하고 필드초기화 내용이 비슷한 생성자에서 이런 중복코드를 많이 볼 수 있다.
밑에거가 100개가 넘어가면 너무 길어짐.

Car(String model){
    this.model = model;
    this.color = "은색"
    this.maxSpeed = 250;
}

Car(String model, String color){
    this.model = model;
    this.color = color;
    this.maxSpeed = 250;
}

Car(String model, String color, int maxSpeed){
    this.model = model;
    this.color = color;
    this.maxSpeed = maxSpeed;
}

  Car(String model){
this(model,"은색",250);
//다른실행문 
}

Car(String model, String color){
    this(model,color,250);
}

Car(String model, String color, int maxSpeed){
    this.model = model;
    this.color = color;
    this.maxSpeed = maxSpeed;
}

this(내가 가지고 있는 생성자)
내가 가지고 있는 생성자 중에서 호출할수 있는 것을 실행해줘
1번실행시 3번이 실행되고 1번돌아가서 1번실행됨
this()쓰면 무조건 이거부터 쓰고 다른실행문 적어야함.

6.8 메소드 선언과 호출

메소드 선언은 객체의 동작을 실행블록으로 정의하는것
리턴타입 메소드면(매개변수,...) {} 호출을하고나서 돌려받는값 = 리턴

6.8.1 메소드 선언

int add(int x, int y) <-메소드 선언부
{ int result = x + y; <- 실행부분
return result;}
메소드 호출 객체 내부 or객체 외부에서도 가능
메소드선언부 타입과 리턴이후 변수가 호환이 가능해야한다.
add(3,5);

void 실행후 리턴값이 없을때 사용
int double등 결과값이 얘로 나온다.
메소드명 첫문자 소문자 캐멀스타일
매개변수 메소드 실행시 데이터 필요없으면 안써도됨 -> 메소드는 타언어 함수랑 비슷함.

public class Calculator {
//리턴값이 없는 메소드 선언
void powerOn()
{
    System.out.println("전원을 켭니다.");
}

//리턴 값이 없는 메소드 선언
void powerOff()
{
    System.out.println("전원을 끕니다.");
}

//호출시 두 정수 값을 전달받고
//호출한 곳으로 결과값 int를 리턴하는 메소드 선언
int plus(int x, int y)
{
    int result = x + y;
    return result; //리턴값 지정
}

//호출시 두 정수 값을 전달받고
// 호출한 곳으로 결과값 double를 리턴하는 메소드 선언
double divide(int x, int y)
{
    double result = (double) x / (double) y;
    return result;    
}
}

6.8.2 메소드 호출

메소드를 호출한다는 것은 메소드 블록을 실행하는 것임. 클래스에서 메소드를 선언햇다고 바로 호출할수 잇는 것은 아니고 메소드는 객체의 동작이므로 객체가 존재하지 않으면 메소드를 호출하지 못함.
클래스로부터 객체가 생성된 후에는 메소드는 생성자와 다른 메소드 내부에서 호출가능하고 객체 외부에서도 호출가능하다.
외부에서 호출시 참조변수와 도트(.)이 필요 사진참조
리턴타입이 잇을경우 매개변수를 넣어줘야한다.

// Calculator 객체생성
Calculator myCalc = new Calculator();

//리턴값이 없는 powerOn() 메소드 호출
myCalc.powerOn();

//plus메소드 호출시 5와 6을 매개값으로 제공하고 덧셈결과를 리턴받아 result1 변수에 대입
int result1 = myCalc.plus(5, 6);
System.out.println("result1: " + result1);

6.8.2 가변길이 매개변수

메소드를 호출할때는 매개변수의 개수에 맞게 매개값을 제공해야한다. 그런데 매게변수의 개수를 모르는 경우도 존재한다.
만약 메소드가 가변길이 매개변수를 가지고잇다면 매개변수의 개수와 상관없이 매개값을 줄수잇다.
int sum(int ... values){} 이건 배열이고 낱개로 제공하거나 배열자체를 줘도됨.
int result = sum(1,2,3); or int result = sum(1,2,3,4,5); // 같은 타입만 가능 그러나 갯수는 정해져잇지않음.
매개값들은ㅇ 자동으로 배열항목으로 변환되어 메소드에서 사용된다. 그렇기 때문에 호출시 직접 배열을 매개값으로 제공해도된다.
int[] values = {1,2,3}; int result = sum(values);
int result = sum(new int[] {1,2,3});

public class Computer {
//가변길이를 매개변수를 갖는 메소드 선언
int sum(int ... values)
{
    //sum 변수 선언
    int sum = 0;

    //values는 배열 타입의 변수처럼 사용
    for (int i =0; i < values.length; i++)
    {
        sum += values[i];
    }

    //합산결과를 리턴
    return sum;

}

//컴퓨터 객체생성
Computer myCom = new Computer();

//sum()메소드 호출 시 매개값 1,2,3을 제공하고 합산겨로가를 리턴받아 result1변수에 대입
int result1 = myCom.sum(1,2,3);
System.out.println("result1: " + result1);

//sum()메소드 호출시 배열을 제공하고 result2 변수에 대입
int[] values = {1,2,3,4,5};
int result2 = myCom.sum(values);
System.out.println("result2: " + result2);

//sum()메소드 호출시 배열을 제공하고 합산결과를 리턴받아 result3에 대입
int result3 = myCom.sum(new int[] {1,2,3,4,5});
System.out.println("result3: " + result3);

만약에 sum ... values 대신 int[] values 면 배열 바로제공하는 아래 두개는 된다.

6.8.3 return문

리턴문은 메소드의 실행종료와 리턴값을 지정할때 사용한다.
리턴문; 다음의 실행문은 실행안됨.

public class Car {
//필드선언
int gas;

//리턴값이 없는메소드로 매개값을 바당서 gas 필드값을 변경
void setGas(int gas)
{
    this.gas = gas;
}

boolean isLeftGas()
{
    if (gas ==0)
    {
        System.out.print("gas가 없습니다.");
        return false;
    }
    System.out.print("gas가 있습니다.");
    return true;
}

//리턴값이 없는 메소드로 gas필드값이 0이면 return문으로 메소드 종료
void run()
{
    while(true)
    {
        if (gas > 0)
        {
            System.out.println("달립니다.(gas잔량: " + gas + ")");
            gas -= 1;
        }
        else
        {
            System.out.println("멈춥니다.(gas잔량: " + gas + ")");
            return; // 메소드 종료
        }
    }
}

//car객체 생성
Car myCar = new Car();

//리턴값이 없는 setGas()메소드 호출
myCar.setGas(5);

//isLeftGas()메소드를 호출해서 리턴값이 true일 경우if블록 실행
if(myCar.isLeftGas())
{
    System.out.println("출발합니다.");

//리턴값이 없는 run()메소드 호출
myCar.run();
}
System.out.println("gas를 주입하세요.");

6.8.4 메소드 오버로딩 메소드

이름은 같되 매개변수의 타입 개수 순서가 다른 메소드를 여러개 선언하는것.

//정사각형 넓이 구하기
double areaRectangle(double width)
{
    return width * width;
}

//직사각형 넓이 구하기
double areaRectangle(double width, double height)
{
    return width * height;
}

//객체생성
Calculator myCalc = new Calculator();

// 정사각형 넓이 구하기
double result1 = myCalc.areaRectangle(10);

// 직사각형 넓이 구하기
double result2 = myCalc.areaRectangle(10, 20);

System.out.println("정사각형 넓이: " + result1);
System.out.println("직사각형 넓이: " + result2);

'기초단계 > JAVA' 카테고리의 다른 글

2022.11.18-1 JAVA 클래스 4  (0) 2022.11.18
2022.11.17-3 JAVA 클래스 3  (0) 2022.11.17
2022.11.17-1 JAVA 클래스 1  (0) 2022.11.17
2022.11.16-3 JAVA 참조타입 3  (0) 2022.11.16
2022.11.16-2 JAVA 참조타입 2  (0) 2022.11.16

+ Recent posts