09일차 학습내용
1. 다형성 polymorphism 2. 추상클래스 3. 인터페이스 interface |
sc.close( ) <9:38 Test91 아쉬운 부분 더 정리
1. 다형성 polymorphism
여러가지 형태를 가질 수 있는 능력인데, 상속관계에서 성립 가능합니다.
참조형의 업/다운 캐스팅
다형성 객체 생성 | 기본 객체 생성 |
class A {int x;} A 부모클래스 class B extends A {int y;} B 자식클래스 ----------------------------------- 메인메서드 내부 A a = new B(); -> x, y를 가지고는 있지만 -> 사용시 a.멤버명에서 쓸 수 있는건 x뿐. (-> y를 쓰고싶으면 다시 형변환하면 가능) ▶ A부모타입 변수에 B자식타입 객체를 생성합니다. 가능합니다. 반대로는 안됩니다. (형변환에서 큰 기본형에 작은 기본형을 넣는게 가능했던 것도 가능하고, 반대는 불가능하듯이 말입니다.) 작은 애한테 큰 옷을 입혀주는거라 업캐스팅입니다. |
------------------------------------------ 메인메서드 내부 A a = new A(); -> x -> 사용할 땐 a.멤버명, x B b = new B(); -> x, y -> 사용할 땐 b.멤버명, x,y둘다쓴다 |
A a; B b = new B (); a = b; ▶ 자식 객체를 부모 변수에 담은것과 동일한 것입니다. 그런데, 여기서는 a=b; 만 봐서는 b의 타입을 잘 알 수 없기 때문에 b가 A타입의 객체라는 것을 형변환표기법으로 표시해주는 것이 좋습니다. 여기서는 생략해도 컴파일 에러는 없습니다. a = (A) b; |
|
A a = new A(); B b; (ClassCastException) ▶ 부모 객체를 자식변수에 담을 수는 없습니다. 런타임에러를 방지하려면 형식만 갖추면 되는 것이 아니라 실제 들어있는 게 무엇인지 파악해야 합니다. |
▶ 타입이 안전하지 않다(자바의 타입 엄격성) -> 제네릭도입 |
A a; B b = new B(); B b2; a = b; ▶컴파일 에러X 정상작동(형변환 생략 가능) b2 = (B)a; ▶정상작동 (실체가 자식이라고 자식옷 입히는거 다운캐스팅) (b2는 이제 y를 쓸 수 있습니다.) |
so, 이러한 형변환을 할 때는 그것이 사실인지(변수가 담은 객체의 실제타입) 검증하는 절차가 필요합니다. (검증절차 = 예외처리)
그 때 사용하는 키워드가 instanceof입니다. 이 키워드는 true/false의 값을 돌려주기 때문에 조건문에서 잘 쓰겠쥬?
위의 마지막 코드를 예로 들면. (변수a의 실제 내용이 B타입 객체인지 체크해라~~~ 시키려면)
if (a instanceof B){
b2 = (B)a;
} else{
}
이러한 예외 처리를 하는 이유는 프로그램이 에러를 만나 작업을 중단하는 일을 미연에 방지하기 위함입니다. 에러 만나면 그냥 넘기든지, 다른 명령을 내려줘야, 다음 코드들이 순차적으로 이어지겠죵?
* 주의사항: (B) 자리에 상속해준 부모 클래스 (A)를 넣어도 true를 리턴.
그 위 최초 조상 클래스 Object까지 다 true리턴.
so, 여기서는 목적에 맞게 작은 범위를 지칭해서 해당 클래스 요소를 담고 있는지를 체크해야 합니다.
아니, 다 좋은데 다형성을 왜쓰는거지?
다형성을 이용하면 매개변수parameter 값을 널널하게 잡아줄수 있고, 해당 매서드를 여기저기서 가져다 쓸 수 있습니다.
29번째 줄에 (괄호) 안에 들어가 있는 매개변수 타입은 Goods타입(부모클래스)
실제 구현되는 44번 째 줄의 (매개변수)로 자식객체가 들어가 있는 걸 볼 수 있습니다.
또 다형성을 이용해서는 클래스를 확장해서 쓸 수 있습니다. 이 때 쓰는 게 오버라이딩입니다.
33, 34줄) 메인 메서드에 보면 객체를 생성해서 paint() 메서드에 담아서 보내고 있습니다.
28줄) 매개변수 타입으로 부모클래스인 Shape를 지정해주고 있습니다. (그걸 상속받은 Line, Rect, Circle 그리고 자기자신 Shape도 매개변수에 들어갈 수 있게 됩니다.(다형성)
34) line 객체의(.) draw()메서드를 실행합니다.
35) Shape 객체의(.) draw()메서드를 실행합니다.
...
이런식으로 객체마다 동일한 이름의 메서드이지만 다른 기능을 수행하여 다른 결과를 낼 수 있게 되는 것이 오버라이딩으로 객체를 따로 정의해놓아서 가능한 것입니다.
다형성(오버라이딩) 구현의 예 - #linkedlist #링크트리스트 #링크드리스트
2. 추상클래스 : 개발의 밑그림이다~~ abstract
1) 개발할 때, 밑그림을 그리는 것. 프로그램 설계와 구현 중 설계에 해당하는 것입니다.
2) 키워드 : abstract
3) 추상메서드 : abstract 키워드를 붙여 메서드의 선언부만 있고,
구현부(중괄호{코드작성..}부분)은 되어있지 않습니다.
추상 클래스 | 일반 클래스 |
클래스 내부에 메서드 부분 abstract void func(); public abstract String getName(); public abstract void setName(String str); |
클래스 내부 메서드 부분 void func() { ... } public String getName() { ... }; public void setName(String str){ ... }; |
4) 추상클래스 : 일반 멤버들과 함께 추상 메서드를 포함하는 클래스
추상메서드가 하나라도 있으면 무조건 추상 클래스가 됩니다.
클래스 앞에 abstract 붙여야합니다. // (메서드가 없어도 이걸 붙이면 추상클래스가 됨.. 메서드 없을바에 추상클래스 만들 필요는 없어서 거의 없지만..)
5) 추상클래스는 객체 생성이 불가합니다. 불완전한/ 미완성인 클래스라고 인식하니까 (구현부 없는 메서드 포함하니까 실행이 불가능..)
-> 상속받은 새로운 클래스로 객체를 생성합니다.
6) 상속에서 수퍼클래스로 사용됩니다. 필. 실제 클래스의 프레임으로 사용려는 목적이니까. 부모클래스가 될 수 있음. 킹키워드 extends
추상클래스 Calculator | |
|
상속받은 클래스 MyCalc |
상속받은 클래스로 객체 생성 |
7) 추상클래스를 물려받은 서브클래스를 완성시키려면,
추상 메서드를 오버라이딩 한 후, 구현부{} 를 작성해서 일반 클래스로 만들어야 합니다.
(구현하지 않는다면 그 클래스도 추상이되니까 abstract 또붙여야 - # 추상클래스 단순 상속)
3. 인터페이스 interface : 규격 호환성~~ implements / 일종의 추상클래스지만 차이가 있다~~
스프링 프레임워크는 내부가 인터페이스 기준으로 되어있어서 앞으로 인터페이스 만들어야
1) 키워드 : interface //클래스가 아님. 클래스 대신 interface써.
interface PhoneInterface {
// 내용..
}
2) 인터페이스 멤버는 추상메서드와 상수(변치않는 값)만으로 구성된다.
일반변수와 일반메서드는 못들어감.
interface PoneInterface{
public static final int BUTTONS = 20; // 상수
public abstract 리턴타입 메서드명(); //추상메서드만
public abstract void receiveCall();
public abstract void sendCall();
}
* 규격이니까 인터페이스 멤버는 누구나 다 접근 가능하게 전부 public을 붙여야 한다.
3) 모든 메서드는 public abstract 다 붙으니까, 생략 가능하다.
4) 상수는 public static final이며, 생략 가능하다. 어차피 변수를 만든다면 그건 상수니까.
(static 객체 생성 없이도 쓸 수 있게끔. )
int BUTTONS = 20; // 상수
리턴타입 메서드명(); //추상메서드만
void receiveCall();
void sendCall();
5) 인터페이스로 객체 생성 불가능. (new ~~ 안됨)
메서드는 모두 구현이 전혀 안된(미완성인) 추상메서드이므로...
6) 인터페이스로 레퍼런스변수 선언은 가능.
PhoneInterface iPhone; (O)
.. new PhoneInterface(); (X)
7) 인터페이스 상속
인터페이스는 다른 인터페이스를 상속받을 수 있다.
인터페이스는 규격과 같은 것으로, 상속을 통해
기존 인터페이스에 새로운 규격을 추가한 새로운 인터페이스를 만들 수 있다.
다른 규격들을 상속받아서 많은 규격을 만들겠다는거지
extends 키워드 사용
interface MobilePhoneInterface extends PhoneInterface {
void sendSMS();
void recieveSMS();
}
* 추상보다 좋은 점은 인터페이스는 다중상속을 허용한다는 거! 뭔가 구현 만들어진게 없으니까 겹쳐도 된다...실행되다 충돌될일도 없어서
interface DualCameraPhoneInterface extends PhoneInterface, CameraInterface {
void makeVideo(); //자기것도 추가하고..
}
8) 인터페이스 구현 (사용하기)
: 인터페이스의 추상메서드를 모두 오버라이드로 구현한 클래스를 작성하는 것.
클래스를 만들어서 내부에 상속받은 추상메서드들을 {} 오버라이ㅣ드형태로 작성해요~~~
키워드 : (다르다.) implements
ex) 모바일폰인터페이스로 아이폰 만들겠다 / 일반클래스로 객체를 생성.
class IPhone implements MobilePhoneInterface {
//추상 메서드를 모두 구현해좌야 한다.
원형이 public abstract 인데 구현에는 abstract빼야
public void sendCall() {...} 구현
public void receiveCall() {...}
상수까지 5개 중에 메서드4개만 구현하면 됨. 중괄호 내용물은 없어도 되니까 중괄호는 열어놔야.
public void sendSMS(){...}
public void receiveSMS(){...}
//추가적으로 일반 메서드나 변수 작성
public int getButtons() {...} 일반 메서드 추가 작성.
}
* 추상 메서드 중 하나라도 구현을 안하면 에러!!!
9) 인터페이스의 목적 // 다형성의 하나. 아이폰은 객체 생성할 때 자기가 구현한 모바일 폰인터페잇의 자식으로 담을 수 있음. 규범만 주는 규격.......
내용은 다르게 돌아가지만 전화, 문자, 사진 등 모든 폰을 제어하기 쉬워짐. 다형성의 실행 도구중 하나가 인터페이스이다.
설계, 가이드라인
다형성을 실현하는 도구
10) 인터페이스 좋은 점 다중 구현도 됨. (다중 상속 뿐만 아니라)
클래스는 하나이상의 인터페이스를 구현가능 ->
class IPhone implements MobilePhoneInterface {
//추상 메서드를 모두 구현해야 한다.
다중구현 다중상속 다되 . 확장성이 더 좋아. 한번에 클래스를 만들수있다는데........
그럼 추상클래스가 나은 경우는 내부 메서드말고 기본 더 가이드라인 주려고 할때
ArrayList 의 부모격 List 인터페이스 격체에. 느슨하게 호환. 범용으로 받게 개발
그래서 인터페이스 구현해서 클래스 새로 잘 만들어놨어~ 근데 이걸 어따쓰나?
응 그 클래스로 객체를 만들어서 Thread객체 생성할 때 생성자 매개변수로 넘겨~~~~~~~
'코딩' 카테고리의 다른 글
2022.02.21_11일차_패키지와 API (0) | 2022.02.25 |
---|---|
2022.02.18_10일차_내부클래스와 익명클래스, 예외처리 (0) | 2022.02.24 |
2022.02.16_8일차_상속과 오버라이딩 (0) | 2022.02.22 |
2022.02.15_7일차_생성자와 this키워드 (0) | 2022.02.21 |
2022.02.14_6일차_메서드와 메서드 오버로딩 (0) | 2022.02.20 |
댓글