DAY_013[국비] 자바 웹프로그래밍 과정

Bona의 블로그 입니다.·2022년 10월 15일
0

국비과정

목록 보기
14/99

 🌞 Day 013 : class의 상속, Object클래스, toString, equals 



 🐬 상속 

  • 어제 마지막에 수업 했던 Extends04 class를 이어서 수업

  • 상속된 자식 클래스의 객체가 만들어질 때,
    자식 클래스의 생성자가 먼저 호출되고,
    자식클래스의 첫 번째 명령은 부모클래스의 생성자 호출이다.

  • super();는 일부러 밖에 꺼내 쓰지 않아도 이미 자식클래스의 생성자의 첫 번째 줄에 존재하는 명령이다.

  • 다만 super();는 부모클래스의 생성자 중 매개변수가 없는 디폴트 생성자를 호출하는 명령이므로, 혹시라도 부모클래스의 생성자가 매개변수 있는 생성자로 대체되었다면 이는 에러를 발생한다.

  • 이 에러를 해결할 수 있는 방법

    1. 부모클래스의 매개변수 형태 대로 호출
      -> super();에 전달인수를 넣어준다. super(10);

    2. 부모클래스의 생성자를 오버로딩해서 자식클래스 생성자에서 호출하는 형태로 부모클래스의 생성자 추가

      ∴ 부모클래스의 생성자 형태로 호출하거나,
         자식클래스 생성자에서 호출하는 형태로 부모클래스의 생성자를
         추가하거나

  • 자식 클래스의 오버로딩된 생성자의 첫 번째 실행코드는
    super();혹은this();가 올 수 있다
    BUT 한 번에 둘 다 올 수는 없다.

  • 아무것도 쓰지 않으면 super();를 호출한다.
    이 때, 공교롭게도 부모클래스의 디폴트 생성자가 없다면 ERROR!!

  • 여기서 선택할 사항은 부모클래스의 생성자에 맞게 호출하던가,
    이미 (부모클래스를 형태에 맞춰서) 호출하고 있는 형제 생성자를,
    this();를 이용해서 재호출 하던가

 💙 정리 

  • 오버로딩된 생성자 모두 첫 번째 명령이 this();일 수는 없다.

  • 여러 생성자 중 하나는 반드시 super();가 있어야 한다.

  • 자식클래스 생성자에서 super를 호출했으면,
    "그에 맞게 오버로딩된 부모 생성자가 있거나", 없으면
    "지금 존재하는 부모생성자에 맞춰서 호출하거나"...


 🎯 시험 문제 

  • 부모클래스도 여러개 오버로딩 && 자식클래스도 여러개 오버로딩

  • 시험에는 (출력)순서가 바뀔 수 있음



 🐬 메서드 오버라이딩(Overriding) 

 🔸 개념 - 메서드 오버라이딩 이란? 

  • 각각의 클래스에서 발견되는 공통변수, 메서드 등을 하나의 클래스로 만들어 다른 클래스에게 물려주는 것이 "상속"

  • 부모클래스에서 정의되는 변수, 메서드들은 (private 제외)
    모든 자식클래스에서도 정상적으로 동작해야 하므로 부모자식에 공통으로 적용할 수 있는 사항들이 정의되고는 한다.

  • 하지만 가끔 상속 받은 메서드들이 자식 클래스의 생성 목적이나 용도에 따라 어울리지 않는 메서드일 가능성이 있다.

  • 이 때, 자식클래스에서 물려받은 부모클래스의 메서드를 재정의 하여 사용하는데, 이를 메서드 오버라이딩(overriding) 이라고 한다.

  • 자식클래스는 부모클래스에서 물려받은 메서드를 자신의 용도에 맞게 재정의(overriding)할 수 있다.

  • 메서드 오버라이딩은 자식클래스에서 부모클래스의 메서드의 내용을 다시 정의하는 문법이다.

  • 메서드 오버라이닝으로 메서드를 재정의하면 자식클래스의 객체에서 물려받은 메서드는 무시되고 새로 재정의한 메서드가 실행된다.

 💙정리 - 메서드 오버라이딩 

  1. 메서드 이름이 동일해야 한다.

  2. 메서드의 매개변수 타입, 개수, 순서, 리턴값 등이 다를 경우 다른 메서드로 인식한다.

  3. 부모클래스의 메서드 원형(리턴 타입, 매개변수 타입 · 개수 · 순서 등)이 일치해야 한다.

  4. 상속관계에서만 사용이 가능

  5. 접근지정자는 축소될 수 없다. (public -> private X)

  6. 부모클래스 메서드가 "final"로 정의 되어있다면 오버라이딩 할 수 없다.

  7. super.crying()처럼 super키워드를 이용하여 오버라이딩 되기 전 부모메서드를 호출 실행할 수 있다.

  8. 클래스의 외부에서는 super라는 말을 쓸 수 없으므로, 생성된 객체에 super를 붙여서 사용할 수 없다.
    예 ) Cat 클래스의 객체 c를 이용하여 c.super.crying() -> ERROR!!


 🔸 상속 - 캐스팅연산 (형 변환) 

 💙 캐스팅 연산 - 기본 

  • 기본 자료형 같의 형변환(TypeCasting)은 자료형의 크기에 제약을 받는다.

    • 자동 형변환(스마트캐스팅) : 작은용량에서 큰 용량의 변수로
      short -> int

    • 강제 캐스팅 : 큰 용량에서 작은 용량의 변수로
      int -> short
      강제 캐스팅 연산자를 앞에 붙여서 사용
      short k = (short)j;

    • 강제캐스팅도 두 자료형 간의 호환성이 있어야 가능
      String str = i; (X)String.valueOf(i); (O)
      int p = "1234"; (X)Integer.parseInt(1234); (O)

  • 클래스의 레퍼런스 변수 간의 형변환은 각 레퍼런스의 접근 범위에 영향을 받는다.

  • 서로 다른 클래스 객체 간의 형변환은 허용되지 않는다.

 💙 캐스팅 연산 - 부모-자식 클래스 간 

  1. 부모클래스의 참조변수에 자식클래스의 인스턴스주소는 아무런 조치 없이 저장 가능하다

  2. 자식클래스의 참조변수에 부모클래스의 인스턴스주소는 아무런 조치 없이 저장할 수 없다.
    자식참조변수 ← 부모 인스턴스 주소 (X)

  3. 그래도 자식클래스의 참조변수에 부모클래스의 인스턴스 주소를 저장하고 싶다면, 강제캐스팅을 이용할 수는 있다.
    SuperE super4 = new SuperE();
    SubE sub4 = (SubE) super4; // RUNTIME ERROR!!
    ※ 런타임에러(실행할 때 생기는 에러)
    : 코드 작성상에는 문제가 없으나 프로그램을 실행하면 에러가 발생

  4. 이런 런타임 에러를 방지 하려면?

    • 자식참조변수(Sub5)에 저장하려는 부모참조변수(Sper5)가 저장하고 있는 인스턴스 주소가 자식 인스턴스 주소(new SubE())였다면,

    • 즉, "자식 참조변수 <- (부모참조변수 <- 자식 인스턴스주소)"

    • 그렇다면 SubE sub5 = (SubE)super5; 이코드는 정상 실행된다.
      최종적으로 자식인스턴스 주소를 자식 참조변수에 저장한 셈이 되므로

    • 자식인스턴스 주소가 부모참조변수에 저장될 때는 문제가 없지만
      다시 나와서 자식참조변수에 저장될 때는 강제캐스팅이 반드시 필요하다.

  5.  [중요!!] 자식 인스턴스 주소를 저장한 "부모참조 변수"는 부모클래스에서 물려준 멤버들에만 접근이 가능하다. 

  • 부모참조변수(<-자식인스턴스 주소)는 부모가 물려준 멤버변수 자유롭게 사용가능하다

  • 예시) super6.subNum = 200;
    ★★★★★ ERROR!! 자식 멤버변수에는 접근이 불가능

  • ★★★★★
    부모클래스 메서드보다 재정의 된 자식클래스의 메서드가 우선 실행

  • 부모참조변수로 접근이 불가능한 자식 멤버변수를 사용하려면?
    저장된 자식 인스턴스 주소를 자식 참조변수에 옮겨담고 접근하는 수 밖에 없다.


 💙 캐스팅 연산 - instanceof 연산자 

  • 그렇다면 캐스팅연산을 하려는 참조변수가 저장하고 있는 인스턴스 주소의 타입을 어떻게 알 수 있는가?
    (부모클래스 타입인지, 자식클래스 타입인지 알 수 없는 경우엔?)

  • instanceof 연산자를 사용하여 부모와 자식클래스의 타입을 비교한다.
    주의할 점은 반드시 부모클래스는 마지막에 비교한다.

  • 부모클래스로의 캐스팅 검사가 자식캐스팅 검사보다 뒤에 있다면 자식 캐스팅 검사들의 기회가 없어질 수도 있다.



 🐬 Object 클래스 

 🔸 Object 클래스란? 

  • 개발자가 클래스 하나를 새롭게 만들면 자동으로 상속(extends)되는 클래스

  • 자바 내부에 존재하는 그리고 새롭게 만들어지는 모든 클래스는 보이지 않는 곳에 extends Object 가 존재한다.

  • 자바 내부에 존재하는 그리고 새롭게 만들어지는 모든 클래스의 부모클래스

  • 자바의 클래스는 한 클래스 당 하나의 부모클래스만 가질 수 있다.

  • Object 아닌 다른 클래스를 상속하면 그 클래스는 extends Object가 지워진다.

  • extends Object가 없는 경우는 다른 클래스를 상속하는 경우이며,
    그 부모클래스가 이미 Object를 상속하고 있기 때문에 결국 Object의 자식(손자)클래스가 된다.

 💙 Object 클래스에서 물려받은 메서드 

  • .getClass() 메소드 : 해당 객체의 클래스 이름을 리턴해주는 메서드

  • .hashCode() 메소드 : 해당 객체의 해시코드값을 리턴
    ※ 해시코드 : JVM에 의해서 관리되고 있는 다른 객체와 구분해주는 값

  • .toString() 메소드 : 해당 객체의 정보를 문자열로 리턴해주는 메서드
    .toString()을 생략하고 객체이름만 출력해도 출력 내용이 같다.
    출력 내용은 → 패키지이름.클래스이름@해시코드

    • obj 참조변수가 "패키지이름.클래스이름@해시코드"을 저장하고 있다가 출력되는 것이 아니라 Object에 있는 toString메서드가 "패키지이름.클래스이름@해시코드"를 리턴하고 print가 그것을 출력.


 🔸 toString() 메서드 

  • 메서드 오버라이딩을 할 때, 메서드이름, 변수의 개수·타입·순서 등이 전부 일치해야 한다!!!


 🔸 Object 클래스의 equals 메서드 

  • Object 클래스의 equals 메서드 : 객체 간의 비교를 위해서 사용되는 메서드

  • Object가 상속한 메서드들 중 toString과 함께 가장 많이 오버라이딩 된다.

  • ★★★★★
    Object 클래스 안의 equals 메서드는 "참조변수값들끼리" 비교하도록 제작되어 있다.

  • String 클래스 안의 equals 메서드는 글자들끼리 비교하도록 오버라이딩 되어 있다.

  • s1==s2 연산의 결과가 true라는 것은 글자가 같아서 true가 아니라, 참조값이 같아서 true라는 뜻이다. (s1,s2 모두 참조변수)

  • 예를 들어 이런 코드가 있을 때, String s1 = "Hello";
    최초 String 데이터가 새로운 공간에 저장되고 그 주소가 s1에 저장된다.

  • 그러나 String s2 = "Hello";가 실행되면, 새 공간이 만들어지는 것이 아니라, HEAP에 저장된 "Hello"의 주소를 s2에 저장한다.
    즉, new 명령이 없어서 있는 자료를 재활용한 셈이다.

  • 지금껏 String을 기본자료형인 것처럼 그냥 사용했지만 String 또한 참조변수이며, new를 사용하여 객체를 만들 수 있는 클래스이다.

  • new를 사용해서 각각 새로운 메모리를 할당해서 s1과 s2를 만들었다면 (인스턴스 주소값이 다르므로) s1==s2는 false이다.


 🔸 메서드 오버라이딩 연습하기 

 1. toString() 

  • toString() 메서드 오버라이딩 하기
    출력 양식 ⇒ "이름:XXX 나이:@@"

  • 문제 (주어진 코드)

  • 내가 작성한 메서드

 🎯 시험 문제 : equals() 오버라이딩 

  • 오버라이딩 되는 메서드의 조건
    : 리턴값의 유형, 매개변수의 유형·개수·순서가 같아야 한다.

  • equals 메서드는 어떤 클래스 내부에서도 오버라이딩 될 준비를 해야하므로 매개변수가 모든 클래스가 전달 가능하도록 모든 클래스의 부모클래스인 Object 자료형으로 정해져 있다.

  • Object는 부모참조변수이므로 자식클래스의 멤버변수에 접근이 안된다.
    Object인 매개변수가 자식클래스의 멤버변수에 접근하려면 다시 자식 클래스 형으로 변환(강제캐스팅)을 해야 한다.

  • equals() 오버라이딩 만들기

    1. 접근지정자 리턴값 이름 (매개변수) {} 작성
      public boolean equals(Object obj) { }
    2. 여기서는 Human 클래스끼리 비교하는 메서드이므로,
      Human이 아닌 다른 클래스의 인스턴스 주소인지 먼저 확인하기
      다른 클래스의 인스턴스 주소라면 더 볼 것도 없이 false 리턴
    3. Human 클래스 인스턴스 주소를 가지고 있다면,
      Human형으로 강제 캐스팅 → 자식클래스인 멤버변수에 접근하기 위해서
      (이유는 바로 위에 설명임)
    4. 비교할 멤버 변수인 name, age를 비교하고 둘 다 같으면 true를 리턴하는 코드 작성하고 끝!


 💙 연습 문제 (혼자 해보기) 

  • 문제 : toString, equals 오버라이딩

  • 내가 작성한 메서드와 출력 결과


 🎯 시험 문제 : 쇼핑하기 

  • 오늘 배운 내용이 전부 나오는 예제, 시험 가능성 매우 높음!!!

  • 클래스로 만들어질 대상 : 판매상품(TV, Computer, Audio), 구매자

  • 구매자가 상품을 사고, 환불하는 행위가 가능하도록 class와 프로그램을 제작

  • Vector

    • 벡터란 배열의 확장형 리스트 구조
      : 객체들을 저장할 수 있는 배열이라고 해도 무방
    • import해서 사용한다.
    • 사용자가 만든 클래스의 객체(메모리를 할당 받은 레퍼런스값) 등이 저장되는 다형성 객체 저장 리스트
    • 추가된 순서로 번호(index)도 설정이 되어 나중에 번호로 검색할 수 있다.
    •  .add() 
      : Vector클래스의 멤버 메서드, 벡터에 객체를 추가
      itemList.add(c); (item:벡터이름, c:벡터에 넣을 객체 이름)
      public boolean add(Object obj){}
    •  .isEmpty() 
      : Vector가 비어있으면 true, 하나라도 채워져 있으면 false를 리턴
    •  .size()  : 저장된 요소의 개수 리턴
    •  .get(n) 
      : Vector에서 저장요소를 꺼내는 멤버메서드, 0부터 시작 (n에는 꺼낼 객체의 순서를 정수로...)
    •  .remove(p) 
      : 벡터에서 상품을 삭제, remove하려는 p(객체이름)가 존재하여 잘 지워졌다면 true 리턴 아니면 false
  1. 클래스 작성하기, toString(), buy(), summary() 만들기

  2. refund() 만들기 (환불 메서드)

    • 제일먼저 itemList가 비어있으면 '해당 상품 구매한 내역이 없습니다.' 출력하기
    • 환불하려는 상품이 없으면 '해당 상품이 없습니다.' 출력
    • 벡터.remove(상품) 사용하기 .remove가 true를 리턴하면,
    • 잔액이 상품 가격만큼 늘어나고 보너스 포인트 줄어듬
    • itemList에서 상품이 삭제됨



🐣 정리하면서...

  • 오늘은 부모-자식 클래스 간의 캐스팅연산, 오버라이딩 등 어려운 내용이 많았다.
  • 코드를 여러번 반복해서 읽어야 이해가 되는 내용들이 많았다.
  • 복잡해보이지만 실제로 많이 사용하는 문법들이라고 하고 시험에도 나올 예정인 것들이 많아서 복습에 시간이 가장 오래 걸렸다.
profile
제가 공부하고 공유하고 싶은 글을 올리고 있습니다.

0개의 댓글