본문 바로가기
JAVA

[Java] 클래스, 객체

by 햄과함께 2020. 12. 19.
320x100

클래스 (Class), 객체 (Object)

객체지향프로그래밍(OOP; Object Oriented Programing)에서는 현실세계 정보를 프로그래밍 세상으로 가져오기 위해 객체 개념을 도입한다. 하나의 독립된 단위를 하나의 객체로 보고 객체간의 데이터 전달, 처리로 프로그래밍해나간다.

이 객체를 만들기 위한 틀을 클래스라고 한다.

접근제어자 class 클래스이름 {
  멤버변수;
  멤버함수;
} 

멤버변수

접근제어자 타입 변수명;

접근제어자를 제외하고는 일반 변수 선언과 동일하다.

메소드

접근제어자 반환타입 함수이름(매개변수) {
   // ...
}

파라미터를 받아 멤버변수와 받은 파라미터들을 사용하여 로직을 처리 후 결과를 반환한다.

객체 외부에서는 어떤 처리가 되는지 알 수 없으므로 함수명을 잘지어 어떤 일을 하는지 알 수 있게 짓는게 중요하다.

class Member {

    int age; 

    int getAgeOfNextYear() {
        return age+1;
    }
}

 getAgeOfNextYear  함수는 객체 데이터 age에 1을 더해 내년 나이를 반환해주는 함수다.

접근제어자

접근제어자 클래스 같은 패키지 서브클래스 이 외
private O X X X
default O O X X
protected O O O X
public O O O O

변수와 메소드에 접근제어자를 지정하여 접근 가능 범위를 지정할 수 있다.

정적 변수, 함수

class Member {
    
    static String description = "desc";
    
    int no;
    String name = "name";
    
    Member(int no) {
        this.no = no;
    }
    
}

Member member = new Member(1);
        
System.out.println(Member.description); // desc
System.out.println(Member.no); // error
System.out.println(Member.name); // error

System.out.println(member.description); // error
System.out.println(member.no); // 1
System.out.println(member.name); // name

static이 붙는 변수, 함수.

멤버변수, 메소드는 객체가 가지고 있어 객체를 생성하지 않으면 사용할 수 없다.

정적 변수, 함수는 클래스가 가지고 있다.

생성자

class 클래스이름 {
    public 클래스이름(매개변수) {
        // ...
    }
}

 클래스에 원하는 데이터를 담은 객체를 생성해준다.

생성자의 이름은 클래스 이름과 같다.

class Member {
    int no;
    String name;
    
    private Member(String name) {
        this.name = name;
    }
    
    Member(int no) {
        this("name");
        this.no = no;
    }
    
}

Member member = new Member(1); // 생성
System.out.println(member); // Member@6a6824be

new 키워드로 객체를 생성할 수 있다.

new 키워드를 사용하면 클래스란 틀에 원하는 데이터를 세팅(생성자)한 수  메모리(heap) 영역에 저장 공간 할당 수 공간 주소를 반환해준다.

즉, 위에서 member 변수에는 Member(1) 생성자로 생성된 객체가 실제로 저장된 위치의 메모리 주소를 가진다.

 

생성자에도 접근제어자를 줘서 접근가능 범위를 설정할 수 있다.

위 코드에서 String을 매개변수로 가지는 생성자는 클래스 내부에 선언한 함수에서만 접근 가능하다.

 

디폴트 생성자 (기본 생성자)

class 클래스이름 {
    public 클래스이름() {
        // ...
    }
}

파라미터가 없는 생성자를 의미한다.

class Member {
    int no;
    String name;
    
    Member() {
        this.no = 1;
        this.name = "name";
    }   
}

Member member = new Member(); // 생성

 

정적 팩토리 메서드 (static factory method)

static 메소드로 객체 생성을 제공한다.

 

장점

- 생성자에 의미를 가진 이름을 줄 수 있어 가독성이 좋아진다.

Integer tmp = Integer.valueOf("1");

 Integer 타입에서는 String 타입을 파라미터로 받아 Integer 데이터를 생성하는 정적 팩토리 메서드를 제공한다.

 

- 상황에 따라 생성되는 객체의 하위 타입을 변경해서 반환할 수 있다.

class Member {
    int no;
    String name;
    
    Member() {
        this.no = 1;
        this.name = "name";
    }
    
    public static Member makeByType(String type) {
        if(type == "VIP") return new VIP();
        else if(type == "VVIP") return new VVIP();
        else return new Member();
    }
}

class VIP extends Member {}
class VVIP extends Member {}

System.out.println(Member.makeByType("VIP").getClass().getSimpleName()); // VIP
System.out.println(Member.makeByType("VVIP").getClass().getSimpleName()); // VVIP
System.out.println(Member.makeByType("something").getClass().getSimpleName()); // Member

makeByType 정적 함수에서 type 파라미터에 따라 서브클래스 VIP, VVIP 혹은 Member 클래스를 생성 후 반환해 줄 수 있다.

 

- 캐싱처리를 할 수 있어(미리 생성된 객체 반환 가능) 객체 생성하는데 드는 비용을 절약할 수 있다.

public static Integer valueOf(String s) throws NumberFormatException {
    return Integer.valueOf(parseInt(s, 10));
}

public static Integer valueOf(int i) {
    if (i >= IntegerCache.low && i <= IntegerCache.high)
        return IntegerCache.cache[i + (-IntegerCache.low)];
    return new Integer(i);
}

valueOf 함수는 내부적으로 IntegerCache.cache 배열을 가져서 이미 new로 생성된 객체를 반환만 해준다.

즉, new 키워드를 이용하여 새로운 객체를 만들지 않는다. -> 성능 향상.

[github] IntegerCache.cache 세팅 참고

this 키워드

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

class Member {
    
    int no;
    
    Member() {
        this(1);
    }
    
    Member(int no) {
        this.no = no;
    }
    
    Member get() {
        return this;
    }
    
}

Member member = new Member();

System.out.println(member); // Member@5c8da962 
System.out.println(member.get()); // Member@5c8da962

기본생성자에서  this(1) 으로 int형 파라미터를 받는 생성자를 호출한다.

생성자에서는  this.no  로 자기자신(객체)의 no로 접근하여 파라미터로 받은 no 값으로 갱신한다.

 get  함수에서는 this 함수로 자기자신을 반환한다.

println으로 응답값을 출력해보면 member와 동일한 것을 확인할 수 있다.

객체의 동등비교

equals 함수

public boolean equals(Object obj) {
    return (this == obj);
}

클래스는 기본적으로 서로 같은 객체인지 판단하는 equals 함수를 제공해준다.

기본 구현은 객체의 주소를 비교한다.

class Member {
    
    int no;
    
    Member(int no) {
        this.no = no;
    }
}

Member member1 = new Member(1);
Member member2 = new Member(1);

 System.out.println(member1.equals(member2)); // false

 

위 코드에서 member1과 member2를 비교하면 다른 객체이기 때문에 false를 반환한다.

class Member {
    
    int no;
    
    Member(int no) {
        this.no = no;
    }
    
    @Override
    public boolean equals(Object obj) {
        if(!(obj instanceof Member)) return false;
        return this.no == ((Member)obj).no;
    }
}

Member member1 = new Member(1);
Member member2 = new Member(1);

System.out.println(member1.equals(member2));

하지만 만약 각 객체들의 특정 정보가 같을 때 같은 객체라고 판단하고 싶다면 이 equals 함수를 오버라이딩 해주면 된다.

equals 함수는 파라미터가 Member 타입과 같은지 판단한 후, 같은 no를 같다면 true, 다르면 false를 반환한다.

320x100

'JAVA' 카테고리의 다른 글

[Java] 상속(Inheritance)  (0) 2020.12.24
[Java] 이진검색트리(BST) 구현  (0) 2020.12.19
[Java] 연결리스트(Linked List), Stack, Queue 구현  (0) 2020.12.12
[Java] Github API 통신  (0) 2020.12.11
[Java] 선택문, 반복문  (0) 2020.12.10

댓글