* 본 포스팅은 제가 국비지원교육을 받으며 노션에 정리한 내용을 옮겨놓은 것입니다.
발전을 위한 피드백과 지적은 언제나 환영합니다.
7.1 상속 개념
- 상속받으면 부모클래스가 갖는 필드나 메소드를 자식클래스에서도 쓸 수 있다. (부모클래스에서 private 접근 제한을 갖는 필드나 메소드는 제외)
7.2 클래스 상속
class 자식클래스 extends 부모클래스 {
//필드
//생성자
//메소드
}
- 다른 언어와 달리 자바는 다중 상속을 허용하지 않음 (한개의 클래스만 상속받을 수 있다)
extends : 상속(확장) - 부모 클래스는 단 1개만 허용(단일상속) - 부모 인터페이스는 한개 이상 implements : 구현(미완성인 기능을 완성) - 1개 이상의 부모 클래스를 허용
1) 부모와 자식 모두가 class 유형인 경우
- class A extends P {...} (A : 자식, P : 부모클래스)
- class A extends P1, P2 (x) / 부모 클래스는 한번만 사용
2) 부모와 자식 모두가 interface 유형인 경우
- interface A extends I1, I2 { ... } (o) / 인터페이스는 여러개 사용 가능
(=> 그래서 extends라는 복수 용어로 사용)?
3) 부모는 interface 자식은 class 유형인 경우
- class A implements I1, I2 { ... }
- 인터페이스는 "구현한다" (implements)
4) 부모는 class, 자식은 interface 유형인 경우 -> 불가 (존재할 수 없음)
이 네가지 방법을 통해서 구현을 해야된다.
- 부모 자식이 똑같으면 extends
- 부모 자식이 다르면 implements (interface -> class)
7.3 부모 생성자 호출
- 자식클래스 SuperCar가 Car 클래스를 상속받는다고 했을때, SuperCar의 객체만 생성했어도 부모 객체가 먼저 생성된다! (부모없는 자식은 없으니까)
- 부모 객체를 생성하기 위해 부모 생성자를 어디서 호출?
public SuperCar(){
super(); // 부모의 기본 생성자를 호출
}
- 자식생성자의 맨 첫줄에서 부모생성자가 명시적으로 호출되지 않았다면, 자바에서는 자동으로 super( )를 통해 부모의 기본 생성자를 호출한다.
- 만약 부모 클래스에 기본생성자가 없고 매개값만 있는 생성자만 있다면, 매개변수 반드시 작성
ex) public Car(String model, String colour){
}
-------------------------------------------------------
public SuperCar(){
super("Hyundai", "red");
}
7.4.1 메소드 재정의 (@Override)
메소드 오버라이딩 규칙
- 부모의 메소드와 동일한 리턴타입, 메소드 이름, 매개변수 리스트
- 접근제한을 더 강하게 오버라이딩할 수 없다. (ex. 부모가 public인데 자식은 private할 수 없다)
- 새로운 예외(Exception)를 throws할 수 없다.
- 즉, 다 똑같고 내용만 수정할 수 있음!!
7.4.2 부모 메소드 호출 (super)
super.부모메소드();
- 그냥 method() 하면 본인 클래스 내 오버라이딩 된 메소드를 호출하고, super.method() 하면 부모 메소드를 직접적으로 호출한다.
부모 부른적도 없는데 나오는 이유? 부모 개체가 먼저 생성되기 때문에
자식 개체 생성되면서 매개변수가 없는 기본 생성자가 딸려서 같이 출력된다
Super() : 매개변수 없는 부모의 생성자 호출
Super(50) : 매개변수 있는 부모의 생성자 호출
But, super 호출을 안 하는 경우라도 부모 객체가 먼저 생성이 되어야 자식 개체가 나오기 때문에 부모 클래스의 매개변수 없는 기본형 생성자가 같이 호출된다. (생성자는 하나만 호출됨)
Example (UI)
Function1 : JInternalFrame을 상속받음
- 부모 생성자 호출하지 않았는데도 프레임이 생성된다는 것 : 기본적으로 인스턴스 f1을 만들 때 부모생성자도 같이 (기본형)
- 그러나 매개변수 없는 기본형이므로 닫기버튼 등 여러가지 기능은 없음
7.7 타입변환과 다형성
(부모인 P 클래스에 자식인 C나 D클래스를 대입할 수 있을까?)
P a1 = new P();
P a1 = new C(); // (o) 부모 자식의 관계인 경우 가능
P a2 = new D(); // (o) 부모 자식의 관계인 경우 가능
=> Class C extends P { ... } 라는 코드가 있을것으로 예상
=> Class D extends P { ... }
대입할 수 있다면 P와 C는 부모 자식의 관계인 경우
자식개체의 생성자를 가지고 부모 객체에 대입할 수 있다.
C c1 = new P(); // (x)
D d1 = new P(); // (x) 반대의 경우는 불가
* 부모객체를 생성하여 자식 클래스의 변수에 대입할 수는 없다.
P는 C도 되고 D도 된다 → 여러가지 형태를 지님 (다형성)
AccoutCreate 의 부모 = Panel
(Deposit, Withdraw도 마찬가지)
AccountCreate ac = new AccountCreate();
⇒ JPanel ac = new AccountCreate(); // 부모타입의 변수에 자식개체 만들어서 대입해서 사용
Deposit de = new Deposit();
=> JPanel de = new Deposit();
// 첫번째 방법으로 메소드 만드는 경우
Public void method(AccountCreate ac){ ... }
Public void method(Deposit de) { ... }
(메소드 이름 같아도 됨. 매개변수 타입이 다르므로 오버로딩)
개선 -->
public void method(JPanel p) {...}
=> 이렇게 하나만 만들면 JPanel 하나의 타입만 매개변수로 선언해서
나머지 다섯개를 전달받을 수 있다.
(AccountCreate, Deposit 등 다른 애들도 다 JPanel 타입이니까 돌려쓰기 가능)
다형성
- 매개변수가 다양한 생성자
- 부모 타입의 변수에 자식개체 만들어서 대입해서 사용
- 자식클래스에서 객체를 생성하고 부모 클래스 변수에 대입하면 자동 타입 변환이 일어난다. (Promotion)
//자동타입변환 예시 (Animal 부모 Cat 자식)
Cat cat = new Cat();
Animal animal = cat;
혹은 Animal animal = new Cat();
cat과 animal 변수는
타입만 다를뿐동일한 Cat 객체를 참조한다!
but, 제한사항이 있음!!
개체를 생성 후 자식클래스에서 추가하면 그
추가된 내용은 사용할 수 없다.
ChildExample - p.311
- 부모 타입으로 자식객체를 생성한 parent로 method1 불렀을때 : 부모클래스에 있는 method1 호출 (Child에는 method1없음)
- method2 불렀을때 : 재정의한 자식클래스의 method2 호출
- method3은 자식클래스에만 있는 메소드인데, 이런 경우에 호출 불가능!
자식클래스에서 추가한 내용을 사용하고 싶으면...
public void method(JPanel p){
Deposit de = (Deposit)p;//자식 클래스에서 추가된 멤버를 사용
}
⇒ 자식클래스로 캐스팅하여 추가된 멤버를 사용할 수 있다.
ChildExample2 - 강제캐스팅
Parent parent = new Child();
Child child = (Child) parent;
//이제 부모클래스뿐만 아니라 자식클래스에 있는 모든 요소도 사용 가능
강제캐스팅 예시2
- JPanel타입의 panel (스톱워치가 들어갈 공간)
- StopWatchThread는 JPanel을 상속받음
- JPanel타입의 panel을 StopWatchThread로 강제 캐스팅
- 이렇게 함으로써 StopWatchThread가 가지고 있는 필드 flag와 그 외 추가한 기능들을 사용할 수 있게 된다.
- 강제 캐스팅을 하려면 먼저 자식객체 생성하여 부모객체에 대입한적이 있어야 하는데 (자식타입이 부모타입으로 자동 변환한 후, 다시 자식타입으로 변환할때 가능)
7.7.4 매개변수의 다형성
- 매개 변수의 타입이 클래스일 경우, 해당 클래스의 객체 뿐만 아니라 자식 객체까지도 매개값으로 사용할 수 있다.
- 자식객체에서 오버라이딩한 메소드를 쓰고 싶을때 → 메소드의 매개변수를 자식객체로.
run(Vehicle vehicle){
...}
Vehicle 타입만 들어갈 수 있는 run의 매개변수에
Vehicle을 상속받는 Bus를 대입할 수 있다.
Bus bus = new bus();
run(bus){
...}
인터페이스 특징
- 완전추상
- 필드는 무조건 상수
- 메소드는 body가 없다. 즉 {} 중괄호가 없다.
존재이유
"주행한다"라는 Action하나에 너무 다양한 메소드가 만들어질 수 있다. ex) 김씨 - start, 이씨 - run ⇒ Interface 만들어서 "자동차 주행은 run으로 통일해라" 주행 관련 만들때 Tire 상속받아서 주행이라는 개념은 무조건 run을 쓰도록.
Interface → Class
상속보다는 "구현한다" (implements) 라는 표현으로.
Tire[] tire = new Tire[4];
이렇게 선언하면 어떨까?
금호, 한국 상관없이 Tire(인터페이스) 이면 다 OK
7.7.6 객체타입확인 (instance of)
⇒ 어떤 객체가 어떤 클래스의 인스턴스인지 확인할때
7.8 추상클래스
7.8.1 추상클래스의 개념
- 클래스간의 공통된 특성을 추출하여 선언한 클래스
- 추상클래스는 실체 클래스의 공통되는 필드와 메소드를 추출해서 만들었기 때문에 객체를 직접 생성해서 사용할 수없다. ⇒ new 연산자로 인스턴스 생성 X
- 부모클래스로만 사용
7.8.2 추상 클래스의 용도
- 실체 클래스들의 공통된 필드와 메소드의 이름을 통일 ⇒ 협업시, 동일한 기능은 같은 이름으로 통일 ⇒ 각각 클래스에서 사용할 필드와 메소드를 추상 클래스에 선언하고, 추상 클래스를 상속받으면 이름을 통일시킬 수 있다.
- 실체 클래스를 작성할 때 시간을 절약 ⇒ 메소드랑 필드 처음부터 다 선언 안 하고 상속받으면 끝!
- 설계자가 코더에게 클래스를 어떤 구조로 작성할지 지시할때, 이 내용들을 추려내어 추상 클래스로 설계 규격을 만들고 이를 상속하도록 한다.
public abstract Class 클래스 {
//필드
//생성자
//메소드
}
7.8.4 추상 메소드와 오버라이딩
- 추상메소드란? ⇒ 중괄호가 없이 메소드 이름만 선언된 경우
- 정해진 action이 아니라, 클래스마다 다른 액션을 취해야하되 같은 메소드 이름으로 통일해야 하는 경우 ex) Animal 추상클래스를 상속받는 Dog, Cat 클래스는 sound ( ) 메소드의 내용이 다르게 기술되어야 한다.
- this.kind : 부모객체의 필드 (super.kind도 가능)
매개변수 타입을 부모객체인 Animal로 받음으로써 Animal을 상속받는 모든 자식객체는 들어갈 수 있도록 했다 (다형성)
추상클래스와 인터페이스의 차이점
일부만 추상메소드가 있으면 → 추상클래스 모두 추상메소드면 → 인터페이스
왜 둘로 나누는지?
클래스는 상속받을 때 하나만 받을 수 있다. 반면 인터페이스는 한개 이상 상속받을 수 있다. (확장성 측면에서 유리) * 인터페이스내에서는 메소드의 내용 기술 불가
Notion2Tistory
boltlessengineer.github.io
이것이 자바다
『이것이 자바다』은 15년 이상 자바 언어를 교육해온 자바 전문강사의 노하우를 아낌 없이 담아낸 자바 입문서이다. 자바 입문자를 배려한 친절한 설명과 배려로 1장에 풀인원 설치 방법을 제
book.naver.com
'JAVA' 카테고리의 다른 글
[이것이 자바다] 11 기본 API 클래스 (2) getProperty, Collection (0) | 2021.03.10 |
---|---|
[이것이 자바다] 11 기본 API 클래스 (1) 객체비교 compare, 오름차순까지 (0) | 2021.03.09 |
[이것이 자바다] 10 예외 처리 (Exception) (0) | 2021.03.09 |
[이것이 자바다] 08 인터페이스 (0) | 2021.03.09 |
[이것이 자바다] 06 클래스 (Class), 객체지향 (0) | 2021.03.09 |
Uploaded by Notion2Tistory v1.1.0