본문 바로가기
네이버클라우드/JAVA 웹 프로그래밍

JAVA 18일차 (2023-06-16) 자바 기초 DAY16_다형성, Object 클래스와 상속, Overriding

by prometedor 2023. 6. 16.
## 19. 다형성을 이용하여 범용으로 사용할 수 있는 목록 클래스 만들기

- 목록 관리 범용 클래스 ArrayList 정의
  - 다형성의 polymorphic variable 문법 활용
- equals() 메서드와 오버라이딩 활용
  - Object 클래스와 상속

다형성, Object 클래스와 상속, Overriding

ㄴ MemberList.java 복사

 

ㄴ 복사한 파일 같은 위치에 붙여넣기 -> 이름은 ArrayList 로 설정

 

 

상속 테스트를 위한 패키지 및 클래스 새로 생성

ㄴ Test 라는 이름으로 패키지 생성

 

 

ㄴ Calculator 클래스 생성

 

Calculator.java

 

Calculator2.java

 

 

ㄴ Test 클래스는 main 메서드까지 같이 생성

 

Test.java

 

클래스 파일 삭제 후 실행

ㄴ Project > Clean... 선택 후 >  새로 컴파일 모두 실행 하고 싶은 프로젝트 선택 > [Clean] 선택

=> 해당 프로젝트의 모든 파일을 새로 컴파일 해줌

 

Test.java

ㄴ Calculator2 클래스가 Calculator 클래스를 상속하고 있으므로 plus 메서드 사용 가능

 

Test.java

ㄴ Calculator2 클래스에 생성한 메서드는 minus(int a, int b) 밖에 없지만 Calculator 클래스를 상속하고 있어 Calculator 클래스에 존재하는 plus(int a, int b) 메서드도 사용 가능

ㄴ 나머지 equals(Object obj), hashCode(), toString() 등은 자바 클래스 모두의 super class 인 Object 의 메서드임

 

Test.java

ㄴ  다형성을 이용하여 Calculator2 객체를 Calculator 타입으로 다루기

ㄴ Calculator c = new Calculator2(); 코드는 Calculator2 클래스의 인스턴스를 생성하여 Calculator 타입의 변수 c에 대입함

=> Calculator2 객체를 Calculator 타입으로 다룰 수 있게 됨

ㄴ Calculator는 Calculator2의 상위 클래스(부모 클래스) => Calculator2 클래스는 Calculator 클래스를 상속 받음
ㄴ Calculator2 c2 = (Calculator2) c; 코드는 c 변수를 Calculator2 타입으로 형변환하여 c2 변수에 대입함

=> c 변수를 다시 Calculator2 타입으로 사용할 수 있게 됨

=> 이를 통해 Calculator 타입으로 다양한 하위 클래스 또는 구현 클래스를 다룰 수 있으며, 각각의 클래스에 정의된 minus()와 plus() 메서드를 호출할 수 있음

 

 

Test.java

ㄴ 형변환 불가

=> c 레퍼런스 변수에는 Calculator 객체가 들어있음

=> 그런데 그 주소가 Calculator2 객체의 주소라고 속이고 컴파일을 시도하면 컴파일러는 그냥 통과시켜줌
     ㄴ 문제는 실행할 때 들통남 (자바 컴파일러는 레퍼런스가 실제 어떤 인스턴스를 가리키는지(인스턴스 주소) 따지지 않고 레퍼런스의 타입에 한정하여 인스턴스나 클래스의 멤버 사용을 허락함)
          Calculator2 c2 = (Calculator2) c; => JVM이 형변환을 처리할 때 진짜 Calculator2 객체가 맞는지 검사함

          => 실행 오류 발생

 

상위 클래스의 레퍼런스로 하위 클래스의 인스턴스를 가리킬 때 형변환 필요

Test.java

ㄴ Calculator2 클래스가 Calculator 클래스를 상속받고 있으므로, Calculator2 클래스의 인스턴스는 Calculator 클래스의 타입으로 다룰 수 있음

ㄴ Calculator 객체의 변수 c 에 Calculator2 객체의 주소를 넣음

ㄴ Calculator2의 minus(int a, int b) 메서드 실행 시 형변환 해줘야 함

    => 레퍼런스 변수가 실제 가리키는 것이 무엇인지 알려줘야 함
    => ((실제 레퍼런스가 가리키는 인스턴스의 타입) 레퍼런스).멤버

 

 

다형적 변수

Test.java

ㄴ Object 클래스는 는 자바에서 모든 클래스의 Super Class 이므로 Object 클래스 레퍼런스 c에 Calculator2 클래스의 인스턴스 주소를 담을 경우, Calculator 클래스의 plus(int a, int b) 메서드와 Calculator2 클래스의 minus(int a, int b) 메서드 사용 시 모두 형변환 필요

=> 레퍼런스 변수가 실제 가리키는 것이 무엇인지 알려줘야 함
=> ((실제 레퍼런스가 가리키는 인스턴스의 타입) 레퍼런스).멤버

 

 

Object 클래스의 equals 메서드 테스트 (Overriding)

 

Test2.java

ㄴ [control] + [Spacebar] 이용하여 import 해주기

=>

Test2.java

 

Test2.java

ㄴ System.out.println(m1 == m2); 코드는 각 레퍼런스에 저장된 인스턴스 주소를 비교함

ㄴ equals() 는 수퍼 클래스 Object 의 메서드임 (두 인스턴스가 같은지 비교함)

 

개인프로젝트_마트 관리 시스템 적용

Member.java

ㄴ obj가 null인지 확인하여 만약 null이라면 두 객체는 동등하지 않으므로 false를 반환
ㄴ obj의 클래스와 현재 객체의 클래스를 비교하여 두 클래스가 다르다면 두 객체는 동등하지 않으므로 false를 반환

 

Member.java

ㄴ this와 obj가 동일한 클래스의 인스턴스인지 확인한 후에 동등성을 비교하는 것이므로 obj를 Member 타입으로 형변환하여 동일한 클래스의 인스턴스인지 비교하는 것이 필요

ㄴ this.getClass()는 this가 가리키는 객체의 클래스를 반환하고, obj.getClass()는 obj가 가리키는 객체의 클래스를 반환함

    => 두 클래스가 같은지 비교하여 동일한 클래스의 인스턴스인지 확인

    => 이 때, 비교를 위해 obj를 Member 타입으로 형변환하여 비교합니다.
    => 형변환을 통해 obj를 Member 타입으로 변환하여 클래스의 필드나 메서드에 접근할 수 있게 됨

    => 이를 통해 this와 obj의 필드 값을 비교하여 동등성 여부를 판단할 수 있음

 

Member.java

=>

Member.java

ㄴ if 문을 이용하여 this 가 가리키는 객체의 no, name, phone, password, position 와 obj 객체를 Member 타입으로  형변환 한 후 해당 객체의 no, name, phone, password, position 를 각각 비교

Member.java

 

Test2.java

ㄴ 우리가 원하는 대로 문자열을 비교하여 true 를 리턴함

 

Test2.java

ㄴ no, Name, phone, password, position 중에 하나라도 다르면 false 를 리턴함

=>

 

ㄴ m1.equals(m2); 코드에서 equals() 메서드는 Object 메서드임

ㄴ 이 메서드는 두 인스턴스가 같은지 비교하는 메서드임

ㄴ 다형적 변수는 컴파일이 통과되면, JVM이 메서드를 호출할 때 다형적 변수가 실제 가리키는 인스턴스의 클래스부터 찾아 올라 감

=> Member 클래스에서 재정의한 equals() 메서드를 사용함

 

ㄴ 우리가 원하는 것은 번호를 비교하여 this가 가리키는 인스턴스 no 와 파라미터 obj가 가리키는 인스턴스의 no 의 문자열이 같지 않다면 false, 같다면 true를 리턴하는 것이므로 나머지는 주석처리 (번호만 비교해도 됨)