본문 바로가기
  • GDG on campus Ewha Tech Blog
4-1기 스터디/CS 기초

[CS 기초 스터디] 12주차 회의록

by seoyoee 2023. 1. 14.

정규 회의록

일시 : 2023.01.14 11:00

범위 : 자바의 정석

강의 : 자바의 정석

활동 : github에 올린 내용 정리본 읽고 공부한 내용에 대해 발표 및 질의응답

정리 : https://github.com/GDSC-Ewha-4th/Study-CS.git


류서영

상속

상속(inheritance)의 정의와 장점

상속

  • 기존의 클래스를 재사용해서 새로운 클래스를 작성하는 것
  • 두 클래스를 부모와 자식으로 관계를 맺어주는 것
  • 자식은 부모의 모든 멤버를 상속받음 (생성자, 초기화 블럭 제외)
  • 자식의 멤버 개수는 부모보다 적을 수 없음 (같거나 많음)
class 자식클래스 extends 부모클래스 {
    // ...
}

클래스간의 관계

  1. 상속 관계부모의 변경은 자식에 영향을 미치지만 자식의 변경은 부모에게 영향 X
     class Point {
         int x;
         int y;
     }
  2. class Circle extends Point { int r; }
  3. 공통 부분 부모에서 관리, 개별 부분 자식에서 관리
  4. 포함 관계
     class Circle {
         Point c = new Point();
         int r;
     }
     class Point {
         int x;
         int y;
     }
  5. 한 클래스의 멤버 변수로 다른 클래스를 선언하는 것

단일상속 (single inheritance)

자바는 단일상속만을 허용

비중이 높은 클래스 하나만 상속관계로, 나머지는 포함관계로 설정

Object 클래스

부모가 없는 클래스는 자동적으로 Object 클래스를 상속

상속 계층도의 최상위에 Object 클래스 위치

모든 클래스는 Object 클래스에 정의된 11개의 메서드 상속

오버라이딩

오버라이딩(overriding)

부모 클래스로부터 상속받은 메서드의 내용을 상속받는 클래스에 맞게 변경하는 것

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

오버라이딩의 조건

  1. 선언부가 같아야 한다. (이름, 매개변수, 리턴타입)
  2. 접근 제어자를 좁은 범위로 변경할 수 없다.
    부모의 메서드가 protected라면 범위가 같거나 넓은 protected나 public으로만 변경할 수 있다.
  3. 부모클래스의 메서드보다 많은 수의 예외를 선언할 수 없다.

오버로딩 vs 오버라이딩

오버로딩(overloading) - 기존에 없는 새로운 메서드를 정의하는 것(new)

오버라이딩(overriding) - 상속받은 메서드의 내용을 변경하는 것(change, mocify)

class Parent {
    void parentMethod() {}
}
class Child extends Parent {
    void parentMethod() {}  // 오버라이딩
    void parentMethod(int i) {}  // 오버로딩
    void childMethod() {}
    void childMethod(int i) {}  // 오버로딩
    void childMethod() {}  // 에러(중복 정의)
}

super - 참조 변수

  • this - 인스턴스 자신을 가리키는 참조 변수, 인스턴스의 주소 저장되어 있음, 모든 인스턴스 메서드에 지역변수로 숨겨진 채로 존재
  • super - this와 같음, 부모의 멤버와 자신의 멤버를 구별하는 데 사용
class Point {
    int x;
    int y;
    String getLocation() {
        return "x :" + x + ", y :" + y;
    }
}
class Point3D extends Point {
    int z;
    String getLocation() { // 오버라이딩
        return super.getLocation() + ", z :" + z;  //부모의 메서드 호출
    }
}

super() - 부모의 생성자

자식 클래스의 인스턴스를 생성하면, 자식의 멤버와 부모의 멤버가 합쳐진 하나의 인스턴스가 생성

부모의 멤버들도 초기화되어야 하기 때문에 자식이 생성자의 첫 문장에서 부모의 생성자 호출해야 함

class Point extends Object {
    int x;
    int y;
    Point() {
        this(0,0);
    }
    Point(int x, int y) {
        super();  // object();
        this.x = x;
        this.y = y;
    }
}

채지은

Generics

  • 다양한 타입의 객체들을 다루는 메서드나 컬렉션 클래스에 컴파일 시에 타입 체크를 해주는 기능 (compile-time type check)
  • ex) ArrayList와 같은 컬렉션 클래스에 다양한 종류의 객체를 담을 수 있지만, 보통 한 종류의 객체만 담음
    • -> 꺼낼 때마다 타입 체크 & 형 변환 불편, 원하지 않는 종류의 객체가 담기는 것을 막을 수 없음

지네릭스의 장점

  1. 타입 안정성
  2. 타입 체크와 형변환을 생략 -> 코드 간결성

지네릭 클래스 선언

  • 지네릭 타입은 클래스와 메서드에 선언 가능

클래스 선언

// Box 클래스
class Box{
    Object item;

    void setItem(Object item){this.item=item;}
    Object getItem() {return item;}
}
// 지네릭 클래스로 변환
class Box<T>{
    T item;
    void setItem(T item){this.item=item;}
    T getItem() {return item;}
}
  • <T>를 타입 변수라고 하며, 'Type'의 첫 글자에서 따왔다
    • T가 아닌 다른 것도 가능
    • ArrayList<E> -> Element의 E
    • Map<K, V> -> Key, Value
  • 상황에 맞게 의미 있는 문자 선택
  • 기호의 종류만 다를 뿐 '임의의 참조형 타입'을 의미하는 것은 같음

지네릭 클래스가 된 Box 클래스의 객체를 생성할 때, 참조변수와 생성자에 타입 T 대신 실제 사용될 타입을 지정해야 함

Box<String> b = new Box<String> ();
b.setItem(new Object());    // X - String 이외의 타입을 불가
b.setItem("ABC");   // O - String 타입이므로 가능
String item = b.getItem();  // (String)으로 형 변환할 필요 X

=> 지네릭 클래스의 <T> 대신 String이 들어갔다고 생각

지네릭스의 용어

class Box<T> {}
  • Box<T> : 지네릭 클래스. T의 Box 또는 T Box라고 읽음
  • T : 타입 변수, 타입 매개변수 (T는 타입 문자)
  • Box : 원시 타입
Box<String> b = new Box<String> ();
  • Box<String> : 지네릭 타입 호출
  • String : 대입된 타입(매개변수화된 타입)

지네릭 클래스의 객체 생성과 사용

class Box<T> {
    ArrayList<T> list = new ArrayList<T> ();
    void add (T item) {list.add(item;)}
    T get(int i) {return list.get(i);}
    ArrayList<T> getList() {return list;}
}
  • 참조변수와 생성자에 대입된 타입이 일치해야함
    • Box<Apple> appleBox = new Box<Grape> () -> 에러
  • 두 타입이 상속관계라고 해도 안 됨
    • Box<Fruit> appleBox = new Box<Apple> () -> 에러

추정이 가능한 경우 생략

  • Box<Apple> appleBox = new Box<>();

댓글