HJW's IT Blog

[JAVA] 객체와 클래스 본문

JAVA

[JAVA] 객체와 클래스

kiki1875 2024. 10. 13. 17:36

Static

  • java 관점으로 static 은 ‘클래스의’ , 공통적인 이라는 의미를 가진다
  • 이러한 개념을 이해하기 java가 어떤 방식으로 동작하는지를 알 필요가 있다

  • java application 을 실행하면 JVM 은 OS 로부터 메모리를 할당한다
  • java 컴파일러가 java 소스코드를 바이트코드로 컴파일한다
  • 클래스 로더를 통해 JVM 메모리로 로딩한다
  • 로드된 클래스 파일들은 기계가 읽을수 없으므로 execution engine 을 통해 기계어로 변환된다
  • 이 과정에서 실행엔진에 의해 garbage collector 등도 동작된다

즉, 자바는 용도에 따라 여러 영역으로 나누어 메모리를 관리한다.

 

  • 메소드 영역 → 클래스 파일을 읽어 데이터를 저장하는 영역
  • 힙 영역 → 인스턴스가 생성되는 공간이다
  • 호출 스텍 → 메소드의 작업에 필요한 메모리 공간, 메소드 호출시, 호출 스택에 메모리가 할당되고, 해당 메소드가 수행되는 동안 필요한 값등을 저장

 

Static 변수

  • 클래스 변수, 한 클래스 내에서 공통적인 값을 유지해야 할 때 선언
  • 메모리에 로딩되어 프로그램이 종료될 때 까지 유지된다
  • 객체를 생성하지 않고도 호출이 가능하다
  • instance 변수의 경우, 인스턴스 객체를 생성해야 호출이 가능하다
  • Static 멤버들은 인스턴스 맴버를 참조할 수 없다 → 인스턴스가 언제 생성될 지 모르기 때문

클래스 메서드

  • 인스턴스 생성 없이도 ClassName.ClassMethod() 로 호출
  • 메서드 내에서는 인스턴스 맴버 사용이 안된다
  • 같은 클래스 내라면 클래스 명 생략 가능

인스턴스 메서드

  • 인스턴스를 반드시 생성한 후, 참조변수.메서드면() 으로 호출 가능
  • 메서드 내에서 인스턴스 맴버 및 정적 맴버들 사용이 가능
  • → 인스턴스 메서드를 호출할 수 있을때는 이미 인스턴스가 생성되어 있다

메서드 오버로딩

오버로딩

  • 하나의 클래스에 같은 이름의 메서드를 여러 개 정의하는 것
  • 오버로딩의 조건
    • 메서드의 이름이 같아야 한다
    • 매개변수의 개수 또는 타입이 달라야 한다
    • 매개변수는 같고 리턴 타입이 다른 경우는 오버로딩이 성립되지 않는다
    <aside> 💡 즉, 다시 말해 메서드들은 매개변수의 개수와 타입에 의해서만 구별된다
  • </aside>

예를 들어 다음과 같은 경우가 오버로딩이다

public class OverloadingExample {

    // 첫 번째 메서드: 매개변수가 없음
    public void display() {
        System.out.println("No parameters");
    }

    // 두 번째 메서드: 매개변수가 하나 (int)
    public void display(int a) {
        System.out.println("One parameter: " + a);
    }

    // 세 번째 메서드: 매개변수가 두 개 (int, int)
    public void display(int a, int b) {
        System.out.println("Two parameters: " + a + ", " + b);
    }

    // 네 번째 메서드: 매개변수가 하나 (String)
    public void display(String s) {
        System.out.println("One parameter: " + s);
    }

    public static void main(String[] args) {
        OverloadingExample obj = new OverloadingExample();
        obj.display();           // 출력: No parameters
        obj.display(5);          // 출력: One parameter: 5
        obj.display(10, 20);     // 출력: Two parameters: 10, 20
        obj.display("Hello");    // 출력: One parameter: Hello
    }
}

Final 필드

  • 최종적인 값을 갖고 있는 멤버 변수 → 값의 변경이 불가능하다
  • Class 앞에 붙으면 해당 클래스는 더이상 확장되지 않는다
  • 맴버 변수로 선언시 초기화를 한다
  • 생성자에서 단 한번 초기화가 가능하다

NEW 키워드

  • 객체를 생성하기 위해 사용된다
  • 메모리 상에 새로운 객체를 할당하고 초기화 하는 역할을 한다
  • 클래스의 생성자가 호출되며, 생성된 객체에 대한 참조가 반환된다

생성자

  • 생성자란 무엇인가?
    • 생성자도 함수(메서드) 이다
    • 객체가 만들어질 때, 클래스 내에서 제일 먼저 자동으로 호출이 되어 실행되는 함수
    • 그렇기에 new 를 사용하여 객체를 생성할때, new Person(); 과 같은 식으로 생성자 함수 호출
    • 객체 생성시 객체의 초기화를 담당
    • 생성자 오버로딩이 가능하다
    • 생성자명은 클래스명과 같아야 한다
    • 생성자는 반환이 없는 함수이다
public class Main {
    public static void main(String[] args) {

        Person p1 = new Person("길동", "kildong@gmail.com", 22);
        p1.walk();
    }
}

class Person{
    String name;
    String email;
    int age;

    Person(String name, String email, int age) { // 생성자
        this.name = name;
        this.email = email;
        this.age = age;
    };

    public void walk(){
        System.out.println("walking");
    }
}

Getter / Setter

  • 객체의 캡슐화에 있어 중요한 개념
  • 클래스의 필드에 직접 접근하는 것이 아니라, 메서드를 통해 접근함으로써
  • 데이터의 무결성을 유지하고 불필요한 변경을 방지
public class Main {
    public static void main(String[] args) {

        Person p1 = new Person();
        p1.setName("철수");
        p1.setEmail("chulsoo@gmail.com");
        p1.setAge(25);

        System.out.println("Updated Name: " + p1.getName());
        System.out.println("Updated Email: " + p1.getEmail());
        System.out.println("Updated Age: " + p1.getAge());

    }
}

class Person{
    private String name;
    private String email;
    private int age;

    public void walk(){
        System.out.println("walking");
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        if(age > 0) {
            this.age = age;
        }else{
            System.out.println("invalid");
        }
    }
}