1. 메서드

    1. 특징
      1. 재사용성
        1. 같은 코드를 여러 번 쓰지 않고, 메서드로 묶어서 필요할 때마다 호출 가능
      2. 캡슐화
        1. 클래스 안에서 동작을 정의해, 외부에선 “이름만” 보고 사용할 수 있음
      3. 매개변수와 인자
        1. 매개변수
          1. 메서드 정의할 때 받는 변수
        2. 인자
          1. 메서드 호출할 때 전달하는 실제 값
      4. 리턴
        1. 메서드 실행 후 결과를 호출한 쪽으로 돌려줄 수 있음
    2. 종류
      1. 인스턴스 메서드

        1. 특징
          1. 객체를 통해 호출되는 메서드

          2. 객체의 상태(필드 값)를 활용하거나 수정할 수 있음

          3. 객체를 생성해야 호출 가능

          4. this 키워드로 자기 자신 객체 참조 가능

          5. 객체마다 상태가 다를 수 있어서, 각 객체에서 독립적으로 동작

          6. static이 아니므로 클래스 이름으로 호출 불가

            class Calculator{
            	int add (int a, int b){return a + b;}
            }
            Calculator c =new Calculator();
            int result = c.add(3, 5); // 객체로 호출
            
      2. 클래스 메서드(static 메서드)

        1. 클래스 전체에서 공유되는 메서드
        2. this 사용 불가 (객체 참조가 없기 때문)
        3. 객체 생성 없이 클래스 이름으로 바로 호출 가능
        class MathUtil{
        	static int square (int x) {return x * x;}
        }
        
        int result = MathUtil.square(4);  //클래스 이름으로 호출
        
        1. 특징
          1. 인스턴스 변수를 사용하지 않는 계산이나 유틸리티에 적합
          2. 성능 상 조금 더 빠름
  2. void 메서드

    1. 결과를 반환하지 않는 메서드
    2. 단순히 동작만 수행
    void printHello() {
        System.out.println("Hello");
    }
    
    
    1. 특징
      1. return 값이 없으므로 호출한 쪽에서는 아무것도 받지 않음
      2. 출력, 상태 변경, 이벤트 처리 등 부작용
  3. 오버로딩

    1. 같은 이름의 메서드를 여러개 정의, 매개변수 타입/개수/순서로 구분
    2. 호출 시 인자에 맞는 메서드가 자동 선택
    int add(int a, int b) {return a + b;}
    double add(double a, double b){return a + b;}
    
    add(2,3); //int 버전 호출
    add(2.0, 3.0); //double 버전 호출
    
    1. 특징 코드의 직관성
    2. 리턴 타입만 다른 건 오버로딩이 아님
  4. 오버라이딩

    1. 특징
      1. 상속 관계에서 부모 클래스 메서드를 자식 클래스에서 재정의
      2. 동일 시그니처(메서드 이름, 매개변수, 리턴타입 호환) 필요
    2. 특징
      1. 다형성 구현 핵심
      2. 부모 타입으로 선언해도 실제 객체 타입의 메서드가 실행됨
    class Animal {
        void sound() {
            System.out.println("동물 소리");
        }
    }
    
    class Dog extends Animal {
        @Override
        void sound() {
            System.out.println("멍멍");
        }
    }
    
    Animal a = new Dog();
    a.sound();  // 결과: "멍멍"
    
    
    1. 설명
      1. Animal a = new Dog();
        1. 변수 타입은 Animal → qnah xkdlq
        2. 실제 객체는 Dog → 자식 클래스
      2. a.sound() 호출시
        1. 컴파일러는 a가 Animal 타입이니까 sound() 가 있구나 하고 확인
        2. 실행 시점 에는 a가 실제로 가리키는 객체 타입DOG의 sound가 호출됨
        3. 즉 참조변수 타입이 부모라도, 실제 객체가 자식이면 자식 메서드가 실행 이게 핵심
    2. 특징
      1. 다형성 구현 핵심
      2. 부모 타입으로 선언해도, 실제 객체 타입의 메서드가 실행됨