Notice
Recent Posts
Recent Comments
Link
«   2024/10   »
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31
Tags more
Archives
Today
Total
관리 메뉴

밤빵's 개발일지

[TIL]20240626 3주차 마무리 ① 본문

개발Article

[TIL]20240626 3주차 마무리 ①

최밤빵 2024. 6. 27. 01:20

3주차 마무리 하는 중...! 

어느정도 이해하고 넘어가고싶었는데 한계인 것 같아서 Spring 강의를 위해 일단 4주차로 넘어가기로 결정.

굉장히 찝찝하고 내키진않지만, 언제든 필요하면 다시 참고할 수 있도록 열심히 기록하고 있다.

 

▶생성자에서 다른 생성자 호출하기 - this()

생성자 간에도 서로 호출이 가능하다. 단. 두 가지 조건을 만족 시켜야 한다.

 

- 생성자의 이름으로 클래스이름 대신 this를 사용.

- 한 생성자에서 다른 생성자를 호출할 때는 반드시 첫 줄에서만 호출이 가능하다. 

Car (String color) {
    door = 5; // 첫 번째 줄 
    Car(color, "auto", 4); 
}

door = 5; 부분이 첫 번째 줄이고,

Car(color, "auto", 4); 에서는 에러 두 가지 있다.

1. 생성자의 두 번째 줄에서 다른 생성자를 호출

2. this(color, "auto", 4)로 해줘야 한다.

- 첫 줄에서만 호출이 가능한 이유는 생성자 내에서 초기화 작업도중 다른 생성자를 호출하게 되면 호출된 다른 생성자 내에서도 멤버변수들의 값을 초기화 하기 떄문에 다른 생성자를 호출하기 이전 초기화 작업이 무의미해 질 수 있기 때문이다.

 

- 같은 클래스 내의 생성자들은 일반적으로 서로 관계가 깊은 경우가 많아서 서로 호출하도록 해서 유기적으로 연결해주면 더 좋은 코드를 얻을 수 있다. 수정이 필요할 때 보다 적은 코드만을 변경하면 되서, 유지보수가 쉽다.

 

▶ 객체 자신을 가리키는 참조변수 - this

Car (String c, String g, int d) {
  color = c;
  gearType = g;
  door = d;
}
Car (String color, String gearType, int door){
    this.color = color;
    this.gearType = gearType;
    this.door = door;
}

위쪽 의 코드는 변수 color과 c 이름만으로도 서로 구별이 되기에 문제가 없지만.

아래 쪽 코드는 매개변수로 선언된 변수의 이름이 color로 인스턴스 변수 color과 같을 경우에는 이름만으로는 두 변수가 서로 구별이 안된다. 이런경우에 인스턴스 변수 앞에 'this'를 사용한다. 

- this.color대신 color = color 를 하게되면 둘 다 지역변수로 간주된다. 

 

this는 참조변수로 인스턴스 자신을 가리킨다. 참조변수를 통해 인스턴스의 멤버에 접근할 수 있는것 처럼 this로 인스턴스 변수에 접근할 수 있다. 하지만 this를 사용할 수 잇는건 인스턴스멤버뿐이다. 

 

▷ 요약

this(), this(매개변수) : 생성자. 같은 클래스의 다른 생성자를 호출할 때 사용한다.

this : 인스턴스 자신을 가리키는 참조변수. 인스턴스의 주소가 저장되어 있고, 모든 인스턴스 메서드에 지역변수로 숨겨진 채로 존재한다. 선언을 안해도 사용이 가능하고, 지역변수와 인스턴스변수를 구별할 때 사용한다. 생성자포함 인스턴스 메서드에서 사용이 가능하다. 

 

▶ 생성자를 이용한 인스턴스의 복사 

- 인스턴스 간의 차이는 인스턴스 변수의 값 뿐! 나머지는 동일하다. 

- 생성자에서 참조변수를 매개변수로 받아, 인스턴스 변수들의 값을 복사한다.

- 똑같은 속성값을 갖는 독립적인 인스턴스가 하나 더 만들어진다. 

Car (Car c){ // 인스턴스의 복사를 위한 생성자
    color = c.color;
    gearType = c.gearType;
    door = c.door;
}
Car (Car c) { 
    this(c.color, c.gearType, c.door);
}

 

▶ 변수의 초기화

멤버변수(클래스 변수와 인스턴스변수)와 배열의 초기화는 선택이지만. 지역변수의 초기화는 필수이다.

인스턴스 변수는 초기화를 해주지 않아도 자동적으로 (예를들어 int라면) int형의 기본값인 0으로 초기화 된다. 지역변수는 자동으로 초기화 되지 않으므로, 초기화 되지 않은 상태에서 사용할 수 없다.

컴파일 에러 발생.

  

▶ 상속

기존의 클래스를 재사용해서 새로운 클래스를 작성하는 것. 두 클래스를 부모와 자식으로 관계를 맺어준다. 자식은 부모의 모든 멤버를 상속 받는다( 생성자, 초기화 블럭 제외). 상속을 구현하는 방법은 새로 작성하고자 하는 클래스 이름 뒤에 상속받고자 하는 클래스의 이름을 키워드 'extends'와 함께 써주면 된다.

자식 클래스는 부모 클래스의 모든 멤버를 상속받기 때문에 , Child클래스 Parent클래스의 멤버들을 포함한다. 

class Parent {}
class Child extends Parent {
    
}

 

Child클래스에 새로운 코드가 추가되어도 부모인 Parent클래스는 아무런 영향을 받지 않는다. 이처럼 부모 클래스가 변경되면 자식 클래스는 자동적으로 영향을 받게 되지만, 자식 클래스가 변경되는 것은 부모 클래스에 아무런 영향을 주지않는다. 자식 클래스는 부모 클래스의 모든 멤버를 상속 받으므로 항상 부모 클래스보다 같거나 많은 멤버를 갖는다. 상속에 상속을 거듭할수록 상속받는 클래스의 멤버 개수는 점점 늘어나게 된다. 

 

▷ 상속은 공통적인 코드를 관리해서 코드의 추가와 변경이 쉬워질 수 있다. 적은양의 코드로 새로운 클래스를 작성할 수도 있고, 코드의 중복을 제거해서 재사용성이 크게 증가하므로 생산성과 유지보수성에 매우 유리해진다. 

 

" 상속을 받는다는 것은 부모 클래스를 확장(extend)한다는 의미로 해석할 수도 있고, 

이것이 상속에 사용되는 키워드가 'extends'인 이유기도 하다." 

 

▶ 클래스 간의 관계 - 포함관계(composite)

상속 이외에 클래스를 재사용하는 방법인 클래스간에 포함(composite) 관계를 맺어 주는 것이다. 클래스 간의 포함 관계를 맺어주는 건 한 클래스의 멤버변수로 다른 클래스 타입의 참조변수를 선언하는것을 뜻한다. 

class Circle {
    int x;
    int y;
    int r;
}

class Point {
    int x;
    int y;
}

예를 들어 원(Circle)을 표현하기위한 클래스와 좌표상의 한 점을 다루기 위한 Point클래스를 작성.

x와 y는 원점의 좌표이다. r은 반지름(radius)

 

class Circle {
    Point c = new Point();
    int r;

Point클래스를 재사용해서 Circle클래스를 작성.

 

작성한 것 처럼 한 클래스를 작성하는 데 다른 클래스를 멤버변수로 선언해서 포함시키는 건 좋은생각이다!  하나의 거대한 클래스를 작성하는 것 보다는 단위별로 여러 개의 클래스를 작성한 후 이 단위 클래스틀을 포함관계로 재사용하면 보다 간결하고 손쉽게 클래스를 작성할 수 있다. 또한 작성된 단위 클래스들은 다른 클래스를 작성하는데 재사용될 수 있다. 

 

▶ 클래스 간의 관계 결정 

상속 관계를 맺어줄건지, 포함관계를 맺어 줄 건지 결정하는 것.

가능한 한 많은 관계를 맺어주어 재사용성을 높이고 관리하기 쉽게 한다. 

class Circle {
    Point c = new Point();
    int r;
}

class Circle extends Point (
        int r;
)

두 경우를 비교해보면 Point클래스를 포함시키거나 받도록 하는 건 결과적으로 별 차이가 없어 보인다. 

이럴 땐! '~은 ~이다.' (is -a)와 '~은 ~를 가지고 있다.(has -a)를 넣어서 문장을 만들어보면 명확해진다.

원(Circle)은 점(Point)이다. - Circle is a Point
원(Circle)은 점(Point)을 가지고 있다. - Circle has a Point    

원은 원점과 반지름으로 구성되니까 위 의 두 문장중 두 번째 문장이 더 옳다는 걸 알 수 있다.

 

이렇게 클래스를 가지고 문장을 만들었을 때 ' ~은 ~이다.' 라는 문장이 성립하면 상속관계.

ex) 고래는 포유류다. 스포츠카는 자동차다.

' ~은 ~를 가지고 있다.'는 문장이 성립되면 포함관계를 맺어주면 된다. 

ex) 자동차는 핸들을 가지고있다. 자동차는 타이어를 가지고있다. 

 

▶ 단일 상속

C++이라는 다른 객체지향언어는 다중상속을 허용한다는데, java는 단일상속만을 허용한다. 

다중상속을 허용하게 되면 여러 클래스로부터 상속받을 수 있기 때문에 복합적인 기능을 가진 클래스를 쉽게 작성할 수 있다는 장점이 있지만, 클래스간의 관계가 매우 복잡해진다는 것과 서로 다른 클래스로 부터 상속받은 멤버간의 이름이 같은경우 구별할 수 있는 방법이 없다는 단점이 있다. 

 

단일 상속은  하나의 조상 클래스만을 가질 수 있기때문에 다중상속에 비해 불편한 점도 있지만, 클래스 간의 관계가 보다 명확해지고 코드를 더욱 신뢰하게 만들어 준다는 점에서 다중상속보다 유리하다. 

 

 ▶ Object클래스 - 최상위 클래스 

모든 클래스 상속계층도의 최상위에 있는 부모 클래스 . 다른 클래스로부터 상속 받지 않는 모든 클래스들은 자동적으로 Object클래스로부터 상속받게한다. 상속계층도를 단순화하기 위해서 Object클래스를 생략하는 경우가 많다. 그래서 java의 모든 클래스들은 Object클래스에 정의된 멤버들을 사용할 수 있다.

 

▷ Object클래스의 주요 메서드 

→ Object clone() : 해당 객체의 복제본을 생성하여 반환.

→ boolean equals(Object object) : 해당 객체와 전달 받은 객체가 같은지 여부를 반환. 

→ String toString() : 해당객체의 정보를 문자열로 반환한다. 

 

▶ 오버라이딩(overriding)

부모 클래스로 부터 상속받은 메서드의 내용을 재정의 하는 것을 오버라이딩이라고 한다. 

상속받은 메서드를 그대로 사용하기도 하지만, 자손 클래스 자신에 맞게 변경해야하는 경우가 많기 때문. 

class Point {
    int x;
    int y;
    
    String getLocation() {
        return x + y;
    }
}

class MyPoint extends Point {
    int z;
    
    String getLocation() { // 오버라이딩 
        return x + y + z;
    }
}

 

▶ 오버라이딩의 조건 

오버라이딩은 메서드의 내용만을 재정의 하는 것이므로 메서드의 선언부(메서드 이름, 매개변수, 반환타입)는 부모와 일치해야한다. 다만 접근 제어자와 예외 에는 제한된 조건 하에서만 다르게 변경할 수 있다. (예외 아직 모름.....) 그리고 접근 제어자는 부모 클래스의 메서드보다 좁은 범위로 변경 할 수 없다. 만약 부모 클래스에 정의된 접근 제어자가 protected라면,  이를 오버라이딩 하는 자식 클래스의 메서드는 접근 제어자가 protected나 public이어야 한다. 대부분의 경우 같은 범위의 접근 제어자를 사용한다. 

 

▶ 오버로딩과 오버라이딩

혼동하기 쉽지만 차이는 명확하다. 오버로딩은 새로운 메서드를 추가하는것이고, 오버라이딩은 부모로부터 상속받은 메서드의 내용을 재정의 하는 것이다. 

class Parent {
    void parentMethod() {}
    
    }

class Child extends Parent {
    void parentMethod() {} // 오버라이딩 
    void parentMethod(int i) {} // 오버로딩 

    void ChildMethod() {} // 메서드 정의 
    void ChildMethod(int i) {} // 오버로딩 
    
    }

 

 

😢오늘의 회고 

3주차 강의를 아주아주 조금 이해한 상태로 4주차 가려니 찝찝한 마음에 좀 불편하지만, 다른 분들의 조언으로 일단은 실행하기로 했다. 이번 주는 유독 시간이 빠르게 간 느낌이다.. 3주차를 그렇게 계속 들여다봤는데 아직도 잘 알지 못한다는게 내 머리의 한계인가 싶다. 그래도 뒤에가서 또 이해되는게 있다고 하니까 위안 삼는 중. 시간이 빠르게 간 건 좋은 조원 분들과 , 그 분들께 받은 크고작은 도움들로 많은 배움을 얻게 되서 그런 것 같다. 오늘  3주차 정리를 다 적으려했는데, 내일까지 내가 얼마나 기억하는지 알고 싶어서 여기까지. 내일부턴 4주차를 들어야하니까 남은시간동안 3주차 열심히 들을예정! 오늘은 피곤하지도않고, 할 수 있는 만큼 최대한 실컷 보고 자야겠다!