상속
- 부모에서 private으로 막아놓은걸 자식이 오픈할 순 없음
새로운 설계도를 만들 때 맨땅에서 새로 시작하는게 아니라 기존에 만들어둔 class에 플러스해서 새로운 걸 만들 수 있지 않을까? ⇒ 상속이란, 기존의 설계도를 재사용하기 위해 등장
- 상속 : 어떤 클래스의 특성을 그대로 갖는 새로운 클래스를 정의한 것
- 기존 클래스 : 상위 클래스, 부모클래스, super class
- 상속받은 클래스 : 하위 클래스, 자식클래스, sub class
- ⇒ 그래서! 자식 클래스에서 부모클래스 내에 있던 메소드나 변수 볼 수 있는 거
- 상속 안 받은 경우 : → 자동완성 창에 클래스 자기 자신의 이름이 뜸
- 상속을 받은 경우 : 해당 변수나 메소드를 어떤 부모에게 상속 받았는지 자동완성에 뜸.
- Object클래스는 상속 받은 적 없는데 자동완성 창에 왜 뜰까?
- 별도의 extends 선언이 없는 클래스는 extends Object가 생략된 것이며 다른 클래스를 상속하더라도 그 상속된 클래스가 또 Object class를 상속함. 상속받은 부모 클래스가 Object클래스를 상속받아 그 자식 클래스도 Object class를 상속받게 되는 것. (꼬리물기 !!)
- 확장성, 재사용성
- 부모의 생성자와 초기화 블록은 상속받지 않음
- ⇒ 도장을 찍은 것만 상속 받는 것.
- 멤버변수나 메서드만 상속 받음
- 클래스 선언 시, extends 키워드 명시
- Java는 다중 상속 허용X, 단일 상속 지원
- extends 다음에 여러 클래스가 나오면 안 됨.
- 두 클래스를 상속 받는다면? 두 클래스에 같은 이름의 변수나 메서드가 있을 때 두 변수나 메서드 사이의 충돌이 되므로 안 됨!
- 자식 클래스는 부모 클래스의 멤버변수, 메소드를 자신의 것처럼 사용할 수 있다. 단 접근제한자에 따라 사용여부가 달라진다.
- private : 상속 불가
- (default) : 같은 패키지 내라면 상속 가능
- protected : 같은 패키지에 있어도, 다른패키지에 있더라도 상속관계가 되면 사용 가능.
- public : 가능
super (this와 비슷하다 !)
해당하는 위치로 가서 가장 가까운 변수랑 메소드를 찾아라!!!
- super 키워드 : 조상 클래스의 생성자 호출
- 부모 클래스의 멤버변수나 메서드를 찾아가는 역할
- this는 객체 자기 자신의 주소를 가리키는 것과 유사하게 super는 자신이 상속한 class가 찍어낸 객체의 주소를 가리키게 됨.
- ⇒(부가설명 : 상속받은 class가 객체를 찍어내면 부모 class를 먼저 찍어낸 후 자식class가 찍힘. this는 여기서 자식class가 찍은 부분의 주소를 가리키게 되고, super는 부모class가 찍어낸 부분의 주소를 가리키게 됨.)
- super와 this가 있으면 이 둘이 가리키는 주소에서 가장 가까이에 있는 그 변수, 메소드를 찾아가 참조하는 것.
- this는 자기 객체 내, 없으면 그 바깥/ super는 부모 class가 찍은 객체 부분
- 생성자로 멤버변수 초기화 할 때
- 자기 자신의 멤버변수를 초기화하고 싶을 때 this를 사용하듯이 부모에게 물려받은 변수를 초기화할 때는 super 사용.
오버라이딩(재정의, overriding) : 메서드
- 상위 클래스의 메서드를 상속받은 후, 재정의해서 사용하는 것.(재정의)
- 메서드의 이름, 반환형, 매개변수(타입, 개수, 순서) 동일해야함
- 하위 클래스의 접근제어자 범위가 상위클래스보다 크거나 같아야한다.
- 조상보다 더 큰 예외를 던질 순 없다.
- 부모 클래스가 메서드에서 예외를 던질 수 있는데 그보다 더 높은 수준의 예외를 던질 수 없음.
- 어노테이션 : 컴파일러가 있는 주석
- 컴파일러에게 부모클래스에 있는 메서드를 오버라이드 하려함을 알려서 실수 등으로 인해 부모클래스에 없는 메서드를 오버라이딩하게 되는 사고를 예방 가능. 사용 권장!
메서드 오버로딩
한 클래스에서 같은 이름의 메서드가 파라미터를 달리하여 만들 수 있음.
오버라이딩
같은 메서드를 자식 클래스가 재정의하여 사용하는 것.
Object 클래스
- 가장 최상위 클래스로 모든 클래스의 조상
- Object의 멤버는 모든 클래스의 멤버
- equals()
- 두 객체가 같은지 비교하는 메서드.
- Object class에서는 주소값을 비교하는 메서드.
- String에서는 실제 문자열 값을 비교하는 것으로 재정의해서 쓰고 있음.
- hashCode
- 시스템에서 객체를 구별하기 위해 사용되는 정수값
- 특징
- 2개의 다른 해시값 ⇒ 두 객체가 동일하지 않음.
- 2개가 같은 해시값 ⇒ 두 객체가 동일할 수도, 아닐 수도 있음.
- HashSet, HashMap 등에서 객체의 동일성을 확인하기 위해 사용
- equals 메서드를 재정의할 때는 hash코드도 재정의할 것.
- ⇒ equals()가 같을 때 hashCode()도 같은 값을 리턴해야 하므로 -! (규칙)
- 객체를 비교할 때 드는 비용을 낮추기 위해 사용.
- 두 객체를 비교할 때 hashCode를 비교하면 절대 같을 수 없는 경우를 빠른 연산으로 확인 가능. hashCode가 같으면 그 때, equals()을 사용하여 두 객체 같은지 확인
equals와 hashCode함수의 오버라이딩에 관련해서는 아래 글을 참고하며 추가로 공부했다.
https://mangkyu.tistory.com/101
해시(Hash)
데이터를 다루는 기법 중 하나.
- 해시 함수 : 데이터를 효율적으로 관리하기 위해 임의의 길이의 데이터를 고정된 길이의 데이터로 매핑하는 함수 ( 매핑하는 과정 : 해싱(Hashing))
String name = "이름";
//String이라는 타입으로 인해 stack에 메모리 공간 확보하고 그 공간에 name이라 이름 붙임.
//Hash 공간에 "이름"이라는 데이터 생성(임의의 길이의 데이터)
고정된 길이의 데이터인 name과 Hash의 "이름"을 Mapping
- 해시 테이블(Hash Table) : key와 value가 하나의 쌍을 이루는 데이터 구조.
- key를 해시 함수로 계산하여 그 값을 배열의 인덱스로 사용.
- 해시코드(HashCode) : 해시 함수에 의해 반환된 데이터의 고유 숫자 값. 이 값을 배열의 index로 사용 → 해당하는 Index에 data 넣기
- ⇒ 이런 식으로 데이터를 저장하다보면 인덱스 값 중복 가능. (충돌) → 충돌이 적은 hash함수 사용하는 게 좋음.
- 장점 : 적은 리소스로 많은 데이터 관리, 검색, 삽입, 삭제가 빠름.
final
- 해당 선언의 최종상태, 결코 수정 불가
- final class 수정금지
- final 메서드 : overriding 금지
- final 변수 : 더 이상 값을 바꿀 수 없음 상수화
- 수정될 수 없기 때문에 초기화 필수
- 객체 내 변수라면 생성자, static블럭을 통한 초기화까지는 허용.
- final 클래스 : 다른 클래스가 상속할 수 없는 클래스
- static + final : 그 값을 계!속! 쓴다는 뜻. 어차피 같은 값을 쓸 경우, 변수가 객체마다 생성돼서 메모리 차지하지 말고 static으로 쓴다면 효율성이 높아짐.
다형성
- 상속관계에 있을 때, 조상 클래스의 타입으로 자식 클래스 객체를 참조할 수 있다.
- (부모클래스) 객체명 = new (자식클래스) ;
- ⇒ 부모클래스의 필터 안경을 쓰고 자식클래스가 찍어낸 객체를 바라보자. 부모클래스에 없는 변수나 메서드는 볼 수 없으며, 부모클래스에 있는 변수의 경우 인지할 수 있으므로 자식클래스가 정의한 데이터값으로 그 변수를 인지한다. (super로 가리킨 경우는 부모의 값을 가져오겠지?!)
- 활용
- 매개변수의 다형성메서드가 호출되기 위해서는 메서드 이름과 파라미터가 맞아야 한다.
- 코드로 살펴보는 매개변수의 다형성
//기존 코드 class Product { int price; int point; } class Tv extends Product {} class Computer extends Product {} class Buyer{ int money = 100000; int myPoint = 0; void buy(Tv t) { money -= t.price; myPoint += t.point;
//필드 다형성 Product p1 = new TV(); Product p2 = new Computer(); Product p3 = new Phone(); //매개변수 다형성 void buy(Product p) { money -= p.price; myPoint += p.point; }
- 참조형 매개변수는 메서드 호출시 자신과 같은 타입이나 자손타입의 인스턴스를 넘겨줄 수 있음
- 배열에서의 활용 : 같은 배열 내에 여러가지 타입의 데이터를 넣을 수 있음
- 일반 변수 타입을 배열 선언할 때 하듯이 class를 변수 타입으로 설정하고 이 class를 상속받은 class들을 배열 요소로 넣을 수 있음
ex. Tv, Computer, Phone은 Product 내의 값은 아니지만 이 세 클래스는 Product를 상속하므로 Product를 변수로 갖는 itemList에 들어가 수 있음.Public static void main(String[] args) { Product[] itemList = new Product[3] itmeList[0] = new Tv(); itemList[1] = new Computer(); itemList[2] = new Phone();
- 매개변수의 다형성메서드가 호출되기 위해서는 메서드 이름과 파라미터가 맞아야 한다.
- 참조를 하게되면 제약사항 발생 : Student로 만들어도 Person의 관점(필터)으로 보기 때문에 Person에는 없고 Student에만 있는 속성들이 보이지가 않아.
- 형변환
- 작은집(우변)에서 큰집(좌변) : 묵시적 캐스팅 / 즉, 부모 타입 = new 자식 클래스 는 묵시적
- 큰집에서 작은집 : 명시적 캐스팅 / 자식 타입 = new 부모 클래스 는 명시(잘 안 씀 ,, )⇒ 조상을 무작정 자손으로 바꿀 수 없음. instanceOf연산자를 통해 한번 체크 후 형변환 가능
- ⇒ (super 일수록 큰 것.)
- instanceOf 연산자 : 객체가 어떤 클래스이며 어떤 클래스를 상속받았는지 확인하는 데 사용
- ⇒ A instanceOf B : A가 B class이거나 B를 상속받는 클래스라면 true 리턴(리턴값 boolean)
'Learning-log > JAVA' 카테고리의 다른 글
[Java] 람다식(Lamda) 개념 및 사용 정리 (0) | 2023.06.20 |
---|---|
패키지, import, 캡슐화, 접근제한자, 접근자, 설정자, static, JVM 메모리 구조 (Java) (0) | 2023.04.01 |
객체지향 프로그래밍 정리(Java, Class, 생성자, 인스턴스, 변수, 메서드, this) (0) | 2023.03.23 |
배열에서 정렬 없이 최댓값 바로 찾는 문법 (0) | 2023.03.23 |
[Java] Comparable, Comparator 알아보기 (0) | 2023.03.23 |