본문 바로가기

백엔드/JAVA

JAVAIT 클래스

 

 

코드작성후 실행

->

 

Student 클래스를 생성하지 않아서 에러가 발생함

 

간단하게  Student 클래스를 만들어준다.

//Student.java

package JAVAIT;

public class Student { 

}

 

Student 클래스를 만들고 실행한 결과

 

 

클래스의 구성

 

1.필드 int fieldName;           -  객체의 데이터를 저장하는 역활

 

2.생성자 Classname() { }    -   new로 객체를 생성할때 객체의 초기화담당 ,리턴타입이 없고 이름이 클래스명과 동일하다.

 

3.메소드  int MethodName(){ }   - 객체가 수행할 동작이다. 객체 내부의 함수는 메소드라고 부른다. , 객체와 객체간 상호작용을 위해 호출된다. 

 

 

 

** 필드(클래스 선언블록, 객체내부 존재, 객체 내 외부 어디든사용)  vs 변수(로컬)(메소드 선언 블록, 생성자 메소드 호출시 존재 , 생성자 메소드 블록 내부에서만 사용)

 

실습예제

 

1.Car라는 클래스에 필드를 선언한다.

//Car.java

public class Car {

  //******* 1. 필드선언 ********

  //고유 데이터를 저장하는 필드 선언
  String company;
  String model;
  String color;
  String maxSpeed;

  //자동차의 상태를 저장하는 필드
  int speed;
  int rpm;

  //부품 데이터를 저장하는 필드 선언 (나중에사용을 위해 주석처리)
  //Body body;
  //Engine engine;
  //Tire tire;

}

 

2. carExample 클래스에서 Car myCar = new Car(); 생성자를 만들고 myCar인스턴스를 통해서 필들에 있는 기능을 정의한다.

//CarExample.java

public class CarExample {
  public static void main(String[] args) {

    //둘째, 생성자 만들기 class이름과 동일하게 Car으로 생성한다. 
    //객체생성
    Car myCar = new Car();

    System.out.println("모델" + myCar.model);
    System.out.println("현재속도" + myCar.speed);
    System.out.println("최고속도" + myCar.maxSpeed);
  }
}

 

 

필드사용

 

1.필드를 사용한다는것은 필드값을 읽고 변경하는 것을 말한다.
2.객체가 존재하지않으면 필드도 존재하지않는다.

3. 필드는 객체 내부의 생성자 / 메소드 내부 / 객체 외부에서 접근해서 사용할 수 있다. 

 

직접만들기

//Bakery.java
public class Bakery {
  String company;
  String kind;
  int price; }
// BakeryStore.java
public class BakeryStore {
  public static void main(String[] args) {
     Bakery bakery = new Bakery();
    System.out.println("점포:" + bakery.company);
    System.out.println("빵종류:" + bakery.kind);
    System.out.println("빵가격:" + bakery.price);
  }}

 

 

여기서 생성자가 없다면? 아래와같은 에러가 발생한다.

당연하지만 bakery가 정의 되지 않으므로 알수없는 이름으로 생성자를 만들지 않으면 객체를 통해 필드값에 접근할수 없다.

 

 

이제 필드 값을 입력해본다. 여러가지 방법이 있는데


1.Bakery 클래스에서 필드값 직접입력 방법이다.

//Bakery.java
public class Bakery {

  String company = "뚜레쥬르";
  String kind = "소보루빵";
  int price=5000;
}

 

결과

 

2. 생성자 클래스에서 값 직접입력

//BakeryStore.java
public class BakeryStore {
  public static void main(String[] args) {
    Bakery bakery = new Bakery();
    System.out.println("빵가격:" + bakery.price);
    bakery.price  = 500;  //생성자 클래스에서 필드값 변경하기
    System.out.println("빵가격:" + bakery.price);
  }}

가격이 변경됨

 

 

*********************주의사항*********************

 

당연한 이야기겠지만 생성자로 만든 bakery 객체는 해당 main {} 메소드 안에서만 실행된다.


위와 같이 Public class BakerStore{} 클래스 에서는 bakery 생성자를 선언하지않았기에 error이 발생한다.

 

 

**여기서  특이한점은 상위 클래스에서  생성자 객체를 만들어주면 정상적으로 실행된다.

Bakery bakery = new Bakery();
//BakeryStore.java
public class BakeryStore {
  Bakery bakery = new Bakery(); // bakery 생성자를 선언함
  public static void main(String[] args) {
    Bakery bakery = new Bakery();
    System.out.println("점포:" + bakery.company);
    System.out.println("빵종류:" + bakery.kind);
    System.out.println("빵가격:" + bakery.price);
    bakery.price  = 500;  //생성자 클래스에서 필드값 변경하기
    System.out.println("빵가격:" + bakery.price);
    int temp =  bakery.price;  // main안에서 생성된 객체
  }
   int temp =  bakery.price; // BakerStore라는 클래스에서 생성된 객체
}

 

 

 

 

생성자 선언

1.생성자를 호출해서 객체를 초기화 한다. 객체를 사용할 준비를 하는것

2. new연산자는 객체의 주소 리턴, 클래스 변수에 대입되어 객체나 필드 메소드에 접근할때 이용된다.

3. 모든 클래스는 생성자가 존재한다 , 기본생성자 public 클래스() {}

4. 클래스가 있는 자바파일을 실행하면 바이트코드 파일( Car.class)이 생성된다. 
 

 //Car.java ========================> // Car.class
 public class Car{        |         public class Car{ 
                          |              public Car(){  
  }                       |                    } }

 

그렇기 때문에 아래와같이 생성자를 호출할때 new Car(); 라는 클래스가 가진 기본생성자를 적어 주는 것이다.

Car myCar = new Car();

 

 

나중에 객체를 다양하게 초기화 하려면 아래와같이 생성자를 직접 선언할수 있다.

Class( 매개변수, ...){
//객체의 초기화 코드 }


//샘플 ***//

public class Car{
Car(String model, String color, int maxSpeed)
}

 

기본모양이 메소드와 비슷하지만 리턴타입이 없고 기본생성자 호출 시 클래스 이름과  동일하다는점이 차이가 있다.

 


**주의사항1 : Parameta가 있는 생성자를 만들때 , 클래스명과 생성자명을  다르게 하면  아래와 같은 error 발생

//Car.java
public class Parameta {
  Car(String model, String color, int maxSPeed){
  }
}

 

 

java: 잘못된 메서드 선언; error 발생

해결

클래스명과 생성자명을 Car로 동일하게 만듦

 

 

 

**주의사항2: 이미 클래스에서 선언한 생성자가 있으면 컴파일러는 기본생성자를 호출하지못함

Car myCar = new Car();  // xxxxxxxxxx 이미 선언된 생성자가 있을 경우 사용불가

Car myCar = new Car("그랜저","검정","250);  // oooooooooo 이렇게 하면 정상동작함

 

 

아래와같이 오류없이 매개변수 전달, 성공하였다 

 

 

**주의사항3:  기본 생성자가 없는 클래스에서는 필드에 접근이 되지않는다.

하지만 이전에 배운방식대로 myCar.module; 으로  인스턴스 필드값을 불러올수없다.

 

**해당방식은 나중에배울 오버라이딩을 통해 해결가능하다.

 

 

 

 

필드초기화 :

 

1. 객체마다 동일한 값을 갖고 있다면 필드 선언시 초기값을 대입하는 것이 좋다. 

2. 객체마다 다른 값을 가져야 한다면 생성자에서 필드를 초기화하는 것이 좋다.  

3. 만일 주민등록번호나 이름같은경우사람마다 달라서 생성자에서 초기화하는 것이 좋다.

예제를 살펴보면

 

3-1

//korean.java
public class korean {
  String nation = "대한민국";
  String name;
  String ssn;

  public korean(String n, String s){
    name = n;
    ssn  = s;
  }}
//KoreanExample.java
public class KoreanExample {

  public static void main(String[] args) {

    korean k1 = new korean("자바킴","011105-745818555");
    System.out.println(k1.nation);
    System.out.println(k1.name);
    System.out.println(k1.ssn);

    korean k2 = new korean("자바팍","011105-745818555");
    System.out.println(k2.nation);
    System.out.println(k2.name);
    System.out.println(k2.ssn);
  }}

 

 

생성자 오버로딩 

1.매개값으로 객체의 필드를 다양하게 초기화 

2.위에 Car 클래스 실습에서 못한  필드와/생성자가 선언된 클래스를 잠시후 실습에서 테스트 해보자

 

오버로딩 기본 틀 

public class Car{
Car() {...}

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

//매개변수의 타입, 갯수, 순서가 다르게 여러 개의 생성자 선언

 

틀린예제

Car(String model, String color) {...}   // 오버로딩이 아님
Car(String color , String model){...}  // 2개의 매개변수가 동일하고 순서만 바뀜

 

 

1.생성자가 아래와같이 오버로딩 되어있으면
2. new 연산자로 생성자를 호출할 때 제공되는 매개값의 타입과 순서에 맞게
3. 생성자가 자동으로 매칭된다.

Car car1 = new Car();   ======> Car() {...}
Car car2 = new Car("그랜저"); ======> Car(String model) {...}
Car car3 = new Car("그랜저","흰색"); ======> Car(String model,String color) {...}
Car car4 = new Car("그랜저","흰색",300); ======> Car(String model,String color, int maxSpeed) {...}

 

 

예제보기

3-2

//Car2.java
public class Car2 {
  String company = "현대자동차";
  String model;
  String color;
  int maxSpeed;

  Car2(){}// 생성자 선언 1
    Car2(String model){ //생성자 선언2
      this.company = company;
      this.model = model;
    }
    Car2(String model, String color){ // 생성자 선언3
      this.company = company;
      this.model = model;
      this.color = color;
    }
    Car2(String model, String color, int maxSpeed){ // 생성자 선언4
      this.company = company;
      this.model = model;
      this.color = color;
      this.maxSpeed = maxSpeed;
    }}
//CarExample2
public class CarExample2 {
  public static void main(String[] args) {
    Car2 car =new Car2();
    System.out.println("==================");
    
    System.out.println("car: " + car.company); // String 1개 생성자 클래스에서 지정한 필드호출
    System.out.println("==================");
    
    Car2 car1 = new Car2("자가용"); //  String String 2개 생성자 호출
    System.out.println("car1: " + car1.company);
    System.out.println("car1: " + car1.model );
    System.out.println("==================");
    
    Car2 car2 = new Car2("자가용","빨강"); // String String String 3개 생성자 호출
    System.out.println("car2: " + car2.company);
    System.out.println("car2: " + car2.model);
    System.out.println("car2: " + car2.color);
    System.out.println("==================");
    
    Car2 car3 = new Car2("자가용","파랑",200);  //String String String int 4개 생성자 호출
    System.out.println("car3: "+ car3.company);
    System.out.println("car3: "+ car3.model);
    System.out.println("car3: "+ car3.color);
    System.out.println("car4: "+ car3.maxSpeed);
    System.out.println("==================");
 }}

 

 

실습이 잘 마무리되었지만 생각해보면 중복 코드가 많다. 어디에? 생성자 오버로딩에...
매개변수의 수만 달리하고 필드 초기화 내용이 비슷한 생성자 중복코드를 많이 볼수 있다.

 

간소화 시킬수있는 방법

1. this(...)를 사용하여 공통코드를 한 생성자에게만 집중
2. 나머지는 this(...)를사용하여 공통코드를 가지고 있는 생성자를 호출하는 방법으로 개선할 수 있다.

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 = max Speed; // 공통 초기화 코드

 

.this(매개값...)

 

- 생성자의 첫줄에 작성되며 다른 생성자를 호출하는 역할을 한다.

- 생성자의 매개변수에 맞게 매개값을 제공하면 된다.
- this() 다음에 추가적인 실행문을 작성할수 있는데. 호출되는 생성자의 실행이 다시 돌아와 실행문을 실행한다.

 

 

실습문제를 확인해보자

 

//Car3.java

public class Car3 {
  String company ="기아";
  String model;
  String color;
  int maxSpeed;

  Car3(String model){         // 1. 생성자
    this(model,"은색",250);   // 3.생성자로 이동함 
  }
  Car3(String model , String color) { // 2.생성자 
    this(model,color,250);        // 3.생성자로 이동함
  }
    Car3(String model , String color, int maxSpeed){ // 3.생성자에서 1~2번 생성자 this값을 받는다
      this.model = model;
      this.color = color;
      this.maxSpeed = maxSpeed;
}}
// CarExample3.java

public class CarExample3 {
  public static void main(String[] args) {

    Car3 car1 = new Car3("트럭"); // 1. car1생성자를 선언 후 도트연산자 사용가능 
    System.out.println("car 1 회사: "+car1.company);  // 
    System.out.println("car 1 모델"+car1.model);
    System.out.println();

    Car3 car2 = new Car3("자가용","빨강");// car2 생성자 선언후  
    System.out.println("car2 회사: " + car2.company); // company 값;
    System.out.println("car2 모델" + car2.model); // model 값
    System.out.println("car2 색상" + car2.color);
    System.out.println();

    Car3 car3 = new Car3("택시","검정",200);// 3.생성자를 선언
    System.out.println("car3 회사: " + car3.company);
    System.out.println("car3 모델" + car3.model);
    System.out.println("car3 색상" + car3.color);
    System.out.println("car3 최고속도" + car3.maxSpeed);
  }}

 

 

메소드 선언

리턴타입  메소드명(매개변수, ... ) {

실행할 코드를 작성하는 곳 

}

 

리턴타입: 1.메소드 실행 후 호출한 곳으로 값을 전달하는 결과값의 type을 말한다. 
                2. 리턴값이 없으면 void로 설정한다.

void addButton() {....}

double divide(int x , int y) { ... }

 

메소드명 1. 첫문자 소물자로 시작(캐멀스타일) 

void run() {...}

void setSpeed(int speed) {...}

String getName() {...}

 

매개변수 1.메소드를 호출할때 전달한 매개값을 받기위해 사용함

double divide(int x, int y)

 

 

 

실습예제 클래스 그리기(설계도)

// Calculator.java

public class Calculator {
  void powerOn() // powerOn() 메소드 선언
  {  
    System.out.println("계산기 전원이 켜졌습니다.");
  }

  void powerOff() { // powerOff() 메소드 선언
    System.out.println("계산기 전원이 꺼졌습니다.");
  }
  
    int plus(int x, int y)  // plus(int x , int y) 메소드 선언
    {
     int result = x + y;  // 메소드내에서 연산 실행
     return result;      //결과값을 리턴함
    }

    double divide(int x , int y) // int형 매개변수를 받는 메소드선언
    {
      double result = (double)x + (double)y; // int형으로 받아서 연산시 double로 변환
      return result;   //결과값을 리턴함
    }}


void powerOn()
void powerOff()

int plus(int x , int y)

double divide(int x , int y)  등등  총 4개 메소드 선언

 

 

메소드 호출하기

//CalculatorExample.java
package JAVAIT;

public class CalculatorExample {
  public static void main(String[] args) {

  Calculator myCalc = new Calculator(); // 생성자 만들기
    myCalc.powerOn();  //powerOn(); 메소드 호출

    int result1 =  myCalc.plus(5, 6);
    System.out.println("int result1 ==" + result1);

    int x = 10;
    int y = 4;

    double result2 = myCalc.divide(x,y); // 매개변수를 해당 클래스에서 정의하였기때문에
                                        // 타입 제외후 x,y로 받을 수 있다.
                                        // int 형으로 받아서 double형으로 리턴한다.
                                        
    System.out.println("result2==" + result2);

myCalc.powerOff();
    System.out.println("double result2 ==" + result2);
 }}

 

 

 

가변길이 매개변수

int sum (int ...values) {

}

 

 

메소드 호출시 매개값 갯수에 상관없이 받을 수 있다.

int result = sum(1,2,3,);

int result sum(1,2,3,4,5);

 

 

가변길이 매개변수실습

//Computer.java
public class Computer {
  int sum(int ... values) {
    int sum = 0;
    for(int i = 0; i < values.length; i++)
    { sum+=values[i]; }
    return sum;
  }}

 

//ComputerExample.java

public class ComputerExample {
  public static void main(String[] args) {

  Computer myCom = new Computer();

  int result1 = myCom.sum(1,2,3,4,5);
    System.out.println("result1: " + result1);

  int result2 = myCom.sum(1,2,3,4);
    System.out.println("result2: " + result2);

  int[] index =  {1,2,3,4,5};
  int result3 = myCom.sum(index);
    System.out.println("result3: "+ result3);

  int result4 = myCom.sum(new int[] {1,2,3,4,5});
    System.out.println("result4: "+ result4);
  }}

 

 

가변길이 매개변수실습 오류 모음1.

 

i<= values.length; 할 경우 아래와같은 에러가 발생한다.
입력한 값
i < values.length; 할 경우 정상출력됨

 

 

가변길이 매개변수실습 오류 모음2.

 

**error체크
1.위에서 지정한 result3의 이름을  다시사용 x

2. new int[]의 객체생성시 new int[]  = {1,2,3,4,5} 와 같은 표기는 잘못되었고

'='표시는 쓰지않고 myCom.sum(new int[] {1,2,3,4,5}); 와 같이 써야함 

 

 

 

return 문

 

 

public class plus {

  int plus(int x, int y){
    int result = x + y;
  
    return result; // return 마무리된 이후
   
     System.out.println(result);  // 실행불가
  }
}

return result  끝난후 system.out.println(result) 호출 했을 경우 ERROR 발생

 

 

수정후

public class plus {

  int plus(int x, int y){
    int result = x + y;
    System.out.println(result);  // 15 한 번 출력
    return result;  }}

 

public class plusExample {
  public static void main(String[] args) {
  plus num = new plus();
   int result1 = num.plus(10,5); 
    System.out.println(result1);  // 15 두 번 출력
  }}

 

//Car5.java

public class Car5 {
  int gas; // 필드선언, gas안에 값을 넣는다.
  
  void setGas(int gas){  //리턴값 없는 메소드를 받는다.gas 필드값을 변경
    this.gas = gas; }
    
  boolean isLeftGas(){ // 리턴값이 boolean인 메소드로 gas 필드값이 0이면 false
    
    if(gas == 0){      //0이 아니면 true 리턴
      System.out.println("gas가 없습니다.");
      return false; }

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

 

//Car5Example.java
public class Car5Example {
  public static void main(String[] args) {
    
  Car5 myCar = new Car5(); // 객체생성
myCar.setGas(5); // 리턴값이 없는 SetGas() 메소드 호출

if(myCar.isLeftGas()) { // isLeftGas() 메소드 호출해서 받은 리턴값이 true일 경우 if 블록실행
  System.out.println("출발합니다."); 
  }
 
    System.out.println("gas를 주입 하세요");
    myCar.run(); // return값이 없는 run() 메소드 호출
}}

 

 

메소드 오버로딩

 

메소드 이름이 같고 매개변수의 타입,갯수,순서가 다른 메소드를 여러개 선언하는 것을 말한다.

class 클래스{

리턴타입 / 메소드이름 (타입1 변수1 , ...) { ...}

리턴타입 / 메소드이름 (타입2 변수2 , 타입3 변수3 ...) { ...}  }

 

실습

//Calculator2.java
public class Calculator2 {

  double areaRectangle(double width){ // 원본 메소드 선언
    return width * width;
  }
  double areaRectangle(double width, double height){ //원본 메소드와 매개변수 타입과 갯수가 다른 오버로딩임
    return width * height;
  }
}

 

//Calculator2Example.java
public class Calculator2Example {

  public static void main(String[] args) {
    Calculator2 myCal = new Calculator2();
    
    double result1 = myCal.areaRectangle(10); //  매개변수 1개의 메소드를 호출함
    
    double result2 = myCal.areaRectangle(10,20); // 2개의 매개변수로 오버로딩된 메소드를
                                                 // 호출할수 있음
    
    System.out.println("result1: "+ result1);
    System.out.println("result2: "+ result2);
  }

 

 

인스턴스 멤버 

  인스턴스 멤버 -> 객체에 소속됨           (객체를 생성해야 사용할 수 있는 멤버)

정적(static)멤버-> 클래스에 고정된 멤버       (객체없이도  사용할 수 있는 멤버)

 

 

public class Car{
//인스턴스 필드선언 // int gas 필드는 객체에 소속된 멤버임
int gas;

//인스턴스 메소드선언 // 메소드는 코드의 덩어리 이기때문에 메모리효율이 떨어진다.
                   //메소드는 공유해서 사용하되 이때 객체없이 까지는 
                   //사용하지못하도록 제한을 걸어둔것이다.
void setSpeed(int speed) { ... }
}

 

위에서 선언한 gas필드와 setSpeed() 메소드는 인스턴스 멤버이기 때문에 외부 클래스에서 사용하기 위해서는

Car객체를 먼저 생성하고 참조 변수로 접근해서 사용해야 한다..

Car myCar = new Car();
myCar.gas = 10;
myCar.setSpeed(60);

 

this 키워드  

객체 내부에서는 인스턴스 멤버에 접근하기 위해 this를 사용 할수 있다.

this는 객체 자신을 의미한다.

 

생성자와 메소드의 매개변수명이 인스턴스 멤버인 필드명과 동일한 경우 인스턴스 필드임을 강조하고자 할때

this를 주로 사용한다.

public class CarThis {

  String model;
  int speed;
  CarThis(String model){
    this.model = model; // 매개변수를 필드에 대입
  }
  void setSpeed(int speed){

    this.speed = speed; // 매개변수를 필드에 대입 
  }

  void run() {
    this.setSpeed(100);
    System.out.println(this.model+"시속"+this.speed+"km/h");
  }}

 

 

정적멤버(Static) 

1. 자바는 클래스 로더를 이용하여 클래스를 메소드 영역에 저장하고 사용한다.

2. static멤버란 메소드 영역의 클래스에 고정적으로 위치하는 멤버를 말한다.
3. 정적멤버는 객체를 생성할 필요 없이 클래스를 통해 바로 사용이 가능하다.

 

정적멤버선언

필드/ 메소드는 모두 정적 멤버가 될수 있다.

public class 클래스{

//정적 필드 선언
static 타입 필드 [= 초기값];

//정적 메소드 
Static 리턴타입 메소드( 매개변수, ...){ ...}

}

 

 

언제사용할까?

=> 객체마다 가지고 있을  필요가 없는 필드를 선언한다.  

=> 아래실습에서 Calculator클래스에서 원의 넓이나 둘레를 구할 떄 필요한 파이는
=> Calculator 객체마다 가지고 있을 필요가 없기 때문에 정적 필드로 선언하는것이 좋다.

 

실습

public class Calculator{
String color;
void setColor(String color){ this.color = color;}

static int plus(int x, int y ) {return x + y; }
static int minus(int x, int y ) { return x - y;} }

 

 

위와 같이 static을 메모리로 로딩되면 정적 멤버를 바로 사용할 수 있다. 

클래스이름과 함께 도트(.) 연산자로 접근하면된다.

public class CalculatorStaticExample {
  public static void main(String[] args) {
    double result1 = 10 * 10 * CalculatorStatic.pi;
    int result2 = CalculatorStatic.plus(10,5);
    int result3 = CalculatorStatic.minus(10,5);

    System.out.println("result1 :" + result1);
    System.out.println("result2 :" + result2);
    System.out.println("result3 :" + result3);
  }}

 

 

정적블록

static double pi = 3.14159; 
// 필드선언과 동시에 초기값을 주는것이 일반적이다.

//정적 블록은 클래스가 메모리로 로딩될 때 자동으로 실행된다.

// 정적 블록이 클래스 내부에 여러객가 선언 되었을경우 선언된 순서대로 실행된다.

 

** 정적 필드는 객체 생성없이도 사용 할 수 있기 때문에 생성자에서 초기화 작업을 하지않는다.

** 생성자는 객체 생성후 실행되기 때문이다.

 

 

public class Television {
  static String company = "myCompany"; //static 선언시 초기화 
  static String model = "LCD"; //static 선언시 초기화함
  static String info;
  static{
    info = company + "-" + model;
  }}

 

** 인스턴스 멤버 사용 불가

 

1. 정적 메소드와 정적블록은 객체가 없어도 실행된다는 특징
2. 인스턴스 필드나 인스턴스 메소드를 사용할 수 없다.
3. 또한 객체자신의 참조인 this도 사용할수없다.

 

package JAVAIT;

public class ClassName {
  int field1;
  void method1() {  }
  static int field2;
  static void method2() { }

  static {
    field1 = 10;  // Error 발생
    method1();  // Error 발생
    field2 = 10;
    method2();  }
    
  static void method3(){
     ClassName obj = new ClassName();
     obj.field1 = 10;
     obj.method1();

    this.field1 = 10; // Error 발생
    this.method1();  // Error 발생
    field2 = 10;
    method2();
  }}

 

정적 메소드와 정적 블록에서 인스턴스 멤버를 사용하고 싶다면 아래처럼
객체를 먼저 생성하고 참조 변수로 접근해야한다.

Static void method3() {
ClassName obj = new ClassName();
obj.field1 = 10;
obj.method1();

 

 

메인메소드도 동일하게 적용된다.

public class car{
int speed; }

void run(){ ...}

public static void main(String[] args){

car myCar = new Car();
myCar.speed =60;  // 컴파일 에러
myCar.run();  // 컴파일 에러

static 으로 선언한 main() 메소드에서 에러가 발생한 모습

 

public static void main(String[] args){
Car myCar = new Car();
myCar.speed = 60;
myCar.run();
}

main()메소드를 올바르게 수정하면 위와 같습니다. 생성자를 먼저 만들어줍니다.

 

public class CarStatic {
  int speed;

  void run() {
    System.out.println(speed + "달립니다.");
  }
  static void simulate() {  // 정적메소드 1
  //객체생성
    CarStatic myCar = new CarStatic();

    myCar.speed = 200; // 인스턴스 멤버 사용
    myCar.run();
  }

  public static void main(String[] args) {
    simulate(); // 정적 메소드1 호출

//객체 생성
    CarStatic myCar =  new CarStatic();
    //인스턴스 멤버 사용
    myCar.speed = 60;
    myCar.run();}
  }

 

Final 필드와 상수

값변경 하는것을 막고 읽기만 허용해야 할때 사용한다. (상수선언)

final 필드 선언

final 타입 필드 [=초기값]

 

final필드에 초기값을 줄수 있는 방법은 두 가지이다.

1. 필드 선언시 초기값 대입
2. 생성자에서 초기값 대입

 

 

 final 실습

public class Koreanfinal {
    //인스턴스 final 필드 선언
    final String nation = "대한민국";
    final String ssn;
    
    //인스턴스 필드 선언
    String name;

//생성자 선언 
    public Koreanfinal(String ssn, String name){
      this.ssn = ssn;
      this.name = name; } }
public class KoreanfinalExample {
  public static void main(String[] args) {
   //객체생성시 주민번호와 이름 전달
    Koreanfinal k1 = new Koreanfinal("21312323-24242","3434");


//필드값 읽기
    System.out.println(k1.nation);
    System.out.println(k1.ssn);
    System.out.println(k1.name);
    
    //Final 필드는 값을 변경 할 수 없음
  

   // 일반적인 필드는 값을 변경할수 있다. 
    k1.name = "감자바";

    System.out.println(k1.name); }}

 

 

 

상수는 객체마다 저장할 필요가 없고 여러개의 값을 가져도 안되기 때문에

static 이면서 final인 특성을 가져야 한다.

static final 타입 방수;
static {
상수 = 초기값;
}

 

 

패키지

클래스를 식별하는 용도로 사용한다.

회사 도메인명을 적는 경우도 있다. 

package com.samsung.projectname;
import com.hankook.Tire;
import com.hankook.*;

 

접근제한자

public ========> 제한 범위 없이 사용가능

protected =====>  같은 패키지이거나 자식 객체만 사용 가능
default   ======>  같은 패키지만 사용가능

private  ======>   객체 내부에서만 사용가능 ( getter / setter )

 

 

public class A {
  A a1 = new A(true);
  A a2 = new A(1);
  A a3 = new A("문자열");

  public A(boolean b){}
  A(int b){}
  private A(String s){} }

 

 

 

public class B {
  A a1 = new A(true);
  A a2 = new A(1);
  A a3 = new A("문자열"); }

 

 

 

public class C {
  A a1 = new A(true);
  A a2 = new A(1);
  A a3 = new A("문자열");}

 

 

[필드와 메소드의 접근 제한]

//필드 선언
[public | private] 타입 빌드;


//메소드 선언
[public  | private] 라턴 타입 메소드(...) {...}

 

 

private 타입 fieldName;

public 타입 getFieldName() {
  return fieldName; }

public void setFieldname(타입 fieldName){
this.fieldName = fieldName; }


//Getter
private boolean stop;
public boolean isStop(){
return stop;
}
반응형

'백엔드 > JAVA' 카테고리의 다른 글

JAVA 변수 와 매개변수의 값이 다른이유  (0) 2024.09.07
절차지향 vs 객체지향(인프런실습)  (0) 2024.08.29
ch06. 타입변환과 다형 8/22  (0) 2024.08.28
java - map  (0) 2024.08.28
java - lambda  (0) 2024.08.28