본문 바로가기

Development/JAVA

(Java) Chapter13. Object

1. 상속

  - 자바에서는 상속하건 하지 않았건 기본적인 상속을 하게된다.

ex) class O = class O extends Object {}

  - 자바에서 모든 클래스는 모든 클래스의 조상인 Object를 암시적으로 상속받고 있는데, 그 이유는 모든 클래스가 공통으로 포함하고 있어야하는 기능을 제공하기 위해서이다. 즉, object라는 클래스가 기본적으로 가지고 있는 메소드를 제공받기 위해서 굳이 표시하지 않아도 자동적으로 상속받는 구조로 기능한다.

 

2. 대표적인 메소드

  1) toString

  - 객체를 문자로 표현하는 메소드

  - 굳이 "class A extends Object" 하지 않아도 Object를 상속받아 포함되어있는 toString 메소드를 불러와 사용할 수 있게 됨

  - 상속받은 toString은 overriding하여 재정의 할 수 있다.

  ※ JRE를 인스톨하면 Object의 메소드 소스코드를 열람할 수 있음을 참조

  - 기본적으로 println하면 소속 클래스정보와 위치정보를 보여주게 되는데 이를 재정의하면 원하는 값을 return할 수 있게 된다. 

  - 여기에 super를 사용해서 재정의하면 소속클래스 + 재정의 리턴값을 출력하게 된다.

 

  2) equals

  - 객체와 객체가 같은 것인지를 비교하는 API

  - 기본적으로 같은 인자를 다른 변수에 인스턴스화하면 서로 다르다고 설명하지만, 변수가 같다면 둘이 동등하다고 표현하려고 하는 경우 다음과 같이 변환할 필요가 있다.

package chapter_12;
//class Student {
//    String name;
//    Student(String name) {
//        this.name = name;
//    }
//}
//
//class _01_Object {
//    public static void main(String[] args) {
//        // 인스턴스 변수가 둘 다 egoing
//        Student s1 = new Student("egoing");
//        Student s2 = new Student("egoing");
//        System.out.println(s1 == s2);           // false
//        System.out.println(s1.equals(s2));      // false
//    }
//}

class Student {
    String name;
    Student(String name) {
        this.name = name;
    }
    // 인스턴스의 변수가 둘 다 같은 경우 true 값을 출력하도록 하는 방법, equals 를 overriding
    public boolean equals(Object obj) { // 매개변수의 데이터 타입이 Object, s2의 데이터 타입은 Student, 그러므로 Object 의 변수에는 name 이 포함되지 않음
        // Student s = obj;             // obj 는 Student 데이터타입으로 전환이 불가능함. 즉, 부모가 자식행세를 할 수 없다.
        Student s = (Student)obj;       // 데이터 형식을 강제적으로 형변환 함(다형성 편 참고)
        return this.name == s.name;
    }
}

class _01_Object {
    public static void main(String[] args) {
        Student s1 = new Student("egoing");
        Student s2 = new Student("egoing");
        System.out.println(s1 == s2);           // false, 서로 다른 데이터이다
        System.out.println(s1.equals(s2));      // true, 서로가 동등하다고 나타내는 오버라이딩된 equals 로 인하여 출력된 값
    }
}

  - 객체를 비교할 때는 new 연산자로 equals를, 원시데이터형(byte, short, int, long, float, double, boolean, char)를 비교할 경우 비교 연산자(==)를 사용하자.

  3) finalize

  - 객체가 소멸될 때 호출되기로 약속된 메소드, 자바 전문가들은 이 메소드의 사용을 만류하고 있다. why??

  - garbsge collection(가비지 컬렉션): 컴퓨터 프로그램은 램에 데이터가 저장된 뒤 동작하게 되는데 더 이상 사용되지 않는 인스턴스의 경우 삭제되는 것이 램의 사용용량을 줄이게 될 것이다. 자바에서는 변수(램)에 저장된 인스턴스를 더 이상 사용하지 않는 경우 제한적으로, 자동으로 변수를 비워주는 작업을 하는데 이를 자동화 한 것을 가비지 컬렉션이라고 한다. 이런 이유에서 finalize는 어차피 자동으로 작업이 실행되는데 굳이 넣을 필요가 있을까?

 

  4) clone

  - 클래스를 복제하는 메소드

  - clone의 특성

    clone은 접근제어자가 protected 이기 때문에 다른 클래스에서 사용하지 못함.

    따라서 cloneable을 통해 복제하고자 하는 클래스를 복제 가능하도록 만들어야 함

    cloneable을 통해 복제 가능을 명시해야하는데 문제는 이 키워드가 비어있는 인터페이스라는 것. 즉, 새롭게 정의 해줘야한다는 것.

    cloneable은 기본적으로 처리가 강제되는 예외(exception)를 가지고 있으므로 예외 처리도 고려해야함

package chapter_12;
//class Student2 {
//    String name;
//    Student2(String name) {
//        this.name = name;
//    }
//}
//
//class _02_Clone {
//    public static void main(String[] args) {
//        Student2 s1 = new Student2("egoing");
//        s1.clone();               //  에러, 클래스의 변수를 복제할 수 없음, clone은 protected임. 즉, 다른 패키지에서 사용 불가능
//    }
//}

class Student2 implements Cloneable {
    // cloneable 의 인터페이스는 비어있는 상태, cloneable 은 클래스가 복제 가능한 클래스임을 자바 버츄얼머신에게 알려주기 위한 구분자 역할을 함
    String name;
    Student2(String name) {
        this.name = name;
    }
    public Object clone() throws CloneNotSupportedException { //exception 이기 때문에 사용자에게 예외 처리 던짐
        return super.clone();               // protected 접근제어자를 복제하는 것이기 때문에 public으로 변경
    }
}

class _02_Clone {
    public static void main(String[] args) {
        Student2 s1 = new Student2("egoing");
        try {
            Student2 s2 = (Student2) s1.clone();  // object 의 데이터타입으로 사용 불가하므로 형변환
            System.out.println(s1.name);          // egoing
            System.out.println(s2.name);          // egoing
        } catch (CloneNotSupportedException e) {
            throw new RuntimeException(e);
        }
    }
}

  - object의 클론메소드를 사용하면 객체를 복제하여 새로운 객체를 생성하는데 있어서 복제하고자하는 클래스가 복제 가능한 객체임을 명시를 하기 위해 cloneable 인터페이스로 명시하고, clone의 접근제어자가 protected이기 때문에 다른 패키지에 있는 클래스에서 직접적으로 사용할 수 없으므로(object는 java.lang이라는 다른 패키지에서 불러와지는 것이기 때문) 사용 가능하게 하기 위해서 public 접근제어자를 붙인 clone을 사용한다. 또한, 여기서 나타나는 Exception을 반드시 처리해야하므로 throw를 사용하고, 이를 통해 사용자에게 처리를 위임한다면 최종적으로 메인영역에서 try~catch, throw로 빌드. 

  - 알아둬야 할 점은, 클론을 오버라이딩으로 재정의할 때 object로부터 재정의이므로 반드시 인스턴스화하여 변수에 담을 때 형변환(object > Student2)을 해주어야한다.  

'Development > JAVA' 카테고리의 다른 글

(Java) Chapter15. Reference  (0) 2023.01.29
(Java) Chapter14. enum  (0) 2023.01.29
(Java) Chapter12. 예외  (0) 2023.01.23
(Java) Chapter11. 접근 제어자  (0) 2023.01.17
(Java) Chapter10. API  (0) 2023.01.10