자바의 정석

[복습] 자바의 정석 6강 클래스 부분부터

snooop 2022. 8. 15. 21:03

main쓰레드가 종료되어도 다른 쓰레드가 종료 되어야 프로그램이 종료 된다
싱글스레드보다 멀티 스레드가 더 시간이 많이 걸림
사용자로부터 입력을 기다리는 구간에 쓰레드 2가 그 때 실행되어 시간을 단축할 수있다 
(메인 쓰레드 작업과 쓰레드 작업은 별개이기 때문)


클래스 Tv설계도
객체 TV

객체 = 속성(변수) + 기능(메서드)
ex) 속성 : 크기, 길이, 높이 ..  String color;// 색깔, boolean power; // 전원 상태
     기능 :  켜기, 끄기, 볼륨 높이기 
            void power() { power = !power;}  void channelUp(){ channel++;}

클래스가 왜 필요한가?(설계도) 객체를 생성하기 위해(제품)
객체가 왜 필요한가? 객체를 사용하기 위해
객체를 사용한다는 것은? 객체가 가진 속성(변수)과 기능(메서드)을 사용하려고 

클래스 변수 : 클래스 생성 시 초기화
인스턴스 변수 : 객체 생성 시 생성자를 통해 초기화

memberId getter/setter 작성 문제

public class TestPassMainEx3{
     public static void main(String[] args){
        MemberInfo memberInfo = new MemberInfo();
        memberInfo.setMemberId("1004");
        System.out.println(memberInfo.getMemberId());

class MemberInfo{
    private String memberId; // 인스턴스 필드를 생성하고 접근제한 함.
    // 게터는 접근제한자가 public 이고 
    // 일반적으로 인스턴스 필드의 값을 반환함
    public String getMemberId(){
         return memberId; // 해당 인스턴스 필드 값을 반환
// 새터는 일반적으로 반환 값이 없고, (값을 세팅하는 것임) 매개변수로 값을 전달 받음 
} public void setMemberId(String memberId){
        this.memberId = memberId;
}
}
 

클래스는 여러개의 데이터와 함수을 저장 할 수 있는 역할, 사용자 정의 타입 이다 
int hour; int minute; int second; 보다(다른 배열로 존재함)
class Time{int hour, int minute, int second;} 
Time t = new Time();
t.hour = 12;
t.minute = 34;
t.second = 56;
가 바람직 객체지향적 코드 하나의 배열로 묶여 있음 
<선언 위치 변수종류>
class Variables{ int iv; // 인스턴스 변수
                     static int cv; // 클래스 변수(static 변수. 공유변수) ->클래스가 메모리에 올라 갈때 생성, 객체 생성 필요 없음

void method(){int lv = 0; // 지역 변수}   --> 메서드 종료시 자동제거
**인스턴스변수 :  인스턴스가 생성되었을때
**객체 -> iv(인스턴스 변수) 를 묶어 놓은 것main쓰레드가 종료되어도 다른 쓰레드가 종료 되어야 프로그램이 종료 된다
싱글스레드보다 멀티 스레드가 더 시간이 많이 걸림
사용자로부터 입력을 기다리는 구간에 쓰레드 2가 그 때 실행되어 시간을 단축할 수있다 
(메인 쓰레드 작업과 쓰레드 작업은 별개이기 때문)


클래스 Tv설계도
객체 TV

객체 = 속성(변수) + 기능(메서드)
ex) 속성 : 크기, 길이, 높이 ..  String color;// 색깔, boolean power; // 전원 상태
     기능 :  켜기, 끄기, 볼륨 높이기 
            void power() { power = !power;}  void channelUp(){ channel++;}

클래스가 왜 필요한가?(설계도) 객체를 생성하기 위해(제품)
객체가 왜 필요한가? 객체를 사용하기 위해
객체를 사용한다는 것은? 객체가 가진 속성(변수)과 기능(메서드)을 사용하려고 

클래스 변수 : 클래스 생성 시 초기화
인스턴스 변수 : 객체 생성 시 생성자를 통해 초기화

memberId getter/setter 작성 문제

public class TestPassMainEx3{
     public static void main(String[] args){
        MemberInfo memberInfo = new MemberInfo();
        memberInfo.setMemberId("1004");
        System.out.println(memberInfo.getMemberId());

class MemberInfo{
    private String memberId; // 인스턴스 필드를 생성하고 접근제한 함.
    // 게터는 접근제한자가 public 이고 
    // 일반적으로 인스턴스 필드의 값을 반환함
    public String getMemberId(){
         return memberId; // 해당 인스턴스 필드 값을 반환
// 새터는 일반적으로 반환 값이 없고, (값을 세팅하는 것임) 매개변수로 값을 전달 받음 
} public void setMemberId(String memberId){
        this.memberId = memberId;
}
}
 

클래스는 여러개의 데이터와 함수을 저장 할 수 있는 역할, 사용자 정의 타입 이다 
int hour; int minute; int second; 보다(다른 배열로 존재함)
class Time{int hour, int minute, int second;} 
Time t = new Time();
t.hour = 12;
t.minute = 34;
t.second = 56;
가 바람직 객체지향적 코드 하나의 배열로 묶여 있음 
<선언 위치 변수종류>
class Variables{ int iv; // 인스턴스 변수
                     static int cv; // 클래스 변수(static 변수. 공유변수) ->클래스가 메모리에 올라 갈때 생성, 객체 생성 필요 없음

void method(){int lv = 0; // 지역 변수}   --> 메서드 종료시 자동제거
**인스턴스변수 :  인스턴스가 생성되었을때
**객체 -> iv(인스턴스 변수) 를 묶어 놓은 것

 

<클래스변수 인스턴스변수>

인스턴스변수 : 개별 속성
클래스변수 : 공통 속성

class Card{
String kind; 
int number;

static int width = 100;
static int height = 250; }

사용 
Card c = new Card();
c.kind = "HEART";
c.number = 5;
Card.width = 200;
Card.height = 300;

<메서드란? 메서드의 선언부와 구현부>

메서드는 중복 되는 코드를 메서드로 간결하게 호출함
메서드 = 선언부 + 구현부

반환 타입 메서드이름(타입 변수명, 타입 변수명, .....) ==> 선언부 
{ // 메서드 호출시 수행될 코드 } ==> 구현부

ex) int add(int x, int y){
int result = x + y;
return result;
}

<메서드 호출>

메서드이름(값1, 값2,...) // 메서드를 호출하는 방법
print99danAll(); // void print99danAll()을 호출
int result = add(3,5); // int add(int x, int y)를 호출하고, 결과를 result에 저장

메서드 클래스영역애서만 정의 가능

<return문>
실행 중인 메서드를 종료하고 호출한 곳으로 되돌아 간다.
void printGugudan(int dan){
    if(!(2 <= dan && dan <= 9))
       return; // dan의 값이 2~9가 아닌경우, 호출한 곳으로 그냥 되돌아간다.

 

for(int i = 1; i <= 9; i++){

     System.out.printf("%d * %d = %d%n" dan, i, dan * i); 

 

 

return; // 반환 타입이 void이므로 생략가능, 컴파일러가 자동추가
}
* 반환타입이 void가 아닌 경우, 반드시 return문 필요
void 일 경우 출력문을 포함해서 써야함 (return 값이 없으므로)
반환 타입과 메소드 타입이 같아야함

 

<호출스택>

메서드 수행에 필요한 메모리가 제공되는 공간
메서드가 호출되면 호출스택에 메모리 할당, 종료되면 해제 

아래 있는 메서드가 위의 메서드를 호출한 것 
맨 위의 메서드 하나만 실행 중, 나머지는 대기 중

***중요***<기본형매개변수>
기본형 매개변수 - 변수의 값을 읽기만 할 수 있다.
참조형 매개변수 - 변수의 값을 읽고 변경할 수 있다. -> 객체의 주소를 주고 받는 것 
-> 호출 스택 그림 그려보기
static 변수는 객체 생성없이 호출 가능
같은 클래스 안에 있는 메소드면 객체 생성없이 호출 가능

<static메서드와 인스턴스 메서드>

long add(); // 인스턴스 메서드 --> 클래스 전체에서 사용
static long add(long a, long b) // 클래스 메서드(static 메서드) static만 붙음, 매개변수는 지역 변수 
-> 인스턴스 메서드
- 인스턴스 생성 후, '참조변수.메서드이름()'으로 호출
- 인스턴스 멤버(iv, im(인스턴스 메소드))와 관련된 작업을 하는 메서드
- 메서드 내에서 인스턴스 변수(iv) 사용 가능

->static 메서드(클래스메서드)
-객체생성없이 '클래스이름.메서드이름()'으로 호출
  ex)Math.random
- 인스턴스 멤버(iv, im)와 관련없는 작업을 하는 메서드
- 메서드 내에서 인스턴스 변수(iv) 사용불가

MyMath2.add (200,100); ----> 클래스이름으로 호출 : 클래스메서드 호출
                                iv를 사용하지 않을 때 static 사용
MyMath2 mm = new MyMath2(); ---> 인스턴스 생성
mm.add() ---> 참조변수로 호출 : 인스턴스메서드 호출 
객체는 인스턴스 변수의 묶음
static : 공통 속성에 static을 붙임  + iv을 사용하지 않는 메서드에 static을 붙임

void instanceMethod(){ // 인스턴스 메서드 : 객체 생성 후 호출 가능(인스턴스 변수로 작업하는 메소드 이므로)
     System.out.println(iv); // 인스턴스 변수를 사용 : 인스턴스 메서드를 사용 했으므로 객체가 생성 되어 가능
     System.out.println(cv); // 클래스 변수를 사용

}

 

static void staticMethod() { // static메서드  : 객체 생성없이 호출 가능
    System.out.println(iv); // 인스턴스 변수 사용X
    System.out.println(cv); // 클래스 변수는 사용
}
-> static메서드는 인스턴스 메서드(im)를 호출할 수 없다. : static 메서드 호출 시 객체가(iv 묶음)가 없을 수도 있어서

<오버로딩>
- 한 클래스 안에 같은 이름의 메서드 여러 개 정의하는 것 
 ex) long add(int a, long b) { return a+b;}
      long add(long a, int b) { return a+b;}

<생성자, 기본 생성자>
-생성자 : 인스턴스가 생성될 때마다 호출되는 '인스턴스 초기화 메서드' (인스턴스 변수 초기화를 의미)
-인스턴스 생성시 수행할 작업(iv 초기화 : 대입문)에 사용 
 초기화 : 변수에 값을 대입해 주는 것 
ex) Time t = new Time(12,34,56);
-이름이 클래스 이름과 같아야 한다.
-리턴값이 없다.(void 안붙임)
- 모든 클래스는 반드시 생성자를 가져야 한다. Card c = new Card(); ==> 생성자 호출, 기본 생성자
ex)클래스이름(타입 변수명, 타입 변수명, ...)
    // 인스턴스 생성 시 수행될 코드,
   // 주로 인스턴스 변수의 초기화 코드를 적는다.
}
class Card {
     Card() { // 매개변수 없는 생성자.
         // 인스턴스 초기화 작업
     }
    Card(String kind, int number) { // 매개변수 있는 생성자 
       // 인스턴스 초기화 작업
     }
}

 

기본 생성자
-매개변수가 없는 생성자 
-생성자가 하나도 없을 때만, 컴파일러가 자동 추가

   클래스이름() { } // 기본 생성자
   Point() { } // Point클래스의 기본 생성자  =>직접 작성

ex) class Data_1 {
         int value;
} ==> 생성자 없음 자동으로 Data_1( ) { } 기본생성자 추가
class Data_2{ 
    int value;
    Data_2(int x){
      value = x;
  }
}
class Ex6_11{
   public static void main(String[ ] args){
        Data_1 d1 = new Data_1();
        Data_2 d2 = new Data_2(); // compile error발생 => Data_2( ) { } --> 기본 생성자를 추가해주어야 함 
       }
}

class Car {
   String color;   // 색상
   String gearType; // 변속기 종류
   int door; // 문 개수

    Car( ) { } // 기본 생성자
    Car(String c, String g, int d){ // 매개변수가 있는 생성자 
          color = c;
          gearType = g;
          door = d;
       }
   }

main)) Car c = new Car("white", "auto", 4);
Car c = new Car( );
c.color = "white";
c.gearType = "auto";
c.door  = 4; --> 같은 코드지만 코드가 너무 길어져서 생성자를 사용한 코드를 사용 하는 것이 좋음

 

** 생성자는 프로그램 부품의 초기 설정을 자동으로 하기 위한 장치


<생성자 this(), 참조변수 this>

생성자 this()
- 생성자에서 다른 생성자 호출할 때 사용 
- 다른 생성자 호출시 첫 줄에서만 사용 가능
- this()를 사용하여 코드의 중복을 제거할 수 있음

 

참조변수 this
-인스턴스 자신을 가리키는 참조변수 
-인스턴스 메서드(생성자 포함)에서 사용가능
-지역변수와 인스턴스 변수를 구별할 때 사용

Car(String color, String gearType, int door) {
   // this.color는 iv, color는 lv
this.color = color;
this.gearType = gearType;
this.door = door;
}
메서드 안에 선언된 변수(매개변수 포함)는 무조건 lv(지역변수)임

 

<변수의 초기화, 멤버변수의 초기화>

-지역변수(lv)는 수동 초기화 해야함( 사용전 꼭!!) --> 우리가 직접 초기화
-멤버변수(iv, cv)는 자동 초기화 됨

-멤버 변수의 초기화
  1. 명시적 초기화(=)
     class Car {
            int door = 4; // 기본형 변수의 초기화
            Engine e = new Engine(); // 참조형 변수의 초기화
}
  2. 초기화 블럭
     인스턴스 초기화 블럭 : { }
     클래스 초기화 블럭 : static { }
  3. 생성자 
     : iv 초기화, 복잡한 초기화
-멤버변수의 초기화 
> 클래스 변수 초기화 시점 : 클래스가 처음 로딩될 때 단 한번
> 인스턴스 변수 초기화 시점 : 인스턴스가 생성될 때 마다
 초기화 순서 
   1) cv -> iv
   2) 자동 (0으로 초기화) -> 간단(=대입연산자) -> 복잡 (static{ }, 생성자 )

오버로딩, 생성자 조건 짧게 써서 외우기