티스토리 뷰
day12 190306
드디어 객체지향의 정말 중요한 부분인, 상속을 배웠습니다.
상속의 특징으로 파생되는 메소드 재정의(Override), 다형성 등을 같이 배웠습니다.
--클래스의 관계 2가지
-상속 관계 (is a관계)
ex) iphone is a phone, android is a phone
-포함 관계 (has a관계)
ex) car has a engine
<상속> : 객체 지향의 중요한 특징, extends키워드 사용
*자바는 단일 상속만 지원
*자식클래스는 부모클래스의 생성자와 private으로 선언된 것은 사용할 수 없다. (상속되지 않음)
상속의 목적 : 부모의 기능을 구현없이 사용하려고.
부모와 같은 종류가 되려고
1 2 3 4 5 6 7 8 9 10 | public class Phone { String tel; public void connect() { System.out.println(tel + "에서 전화를 겁니다."); } public void disconnect() { System.out.println(tel + "에서 전화를 끊습니다."); } } | cs |
>> tel이라는 문자열 변수와, 전화를 걸고 끊는 connect, disconnect메소드를 가진 Phone클래스파일입니다.
1 2 3 4 5 6 7 8 9 10 | public class SmartPhone extends Phone { String ipAddress; public void facetime() { System.out.println(tel + "화상통화를 시작합니다."); } public void internet() { System.out.println(ipAddress + "로 인터넷에 접속합니다."); } } | cs |
>> ipAddress문자열 변수, 화상통화, 인터넷접속 메소드를 가진 SmartPhone클래스파일입니다.
여기서 1행을 보면, extends Phone이라는 부분이 바로 상속입니다. Phone클래스파일을 SmartPhone이 상속받는 것이죠.
(부모클래스 : Phone / 자식클래스 : SmartPhone)
어떤 결과를 가져오게 되는지 확인해보겠습니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | public class PhoneApp { public static void main(String[] args) { Phone p1 = new Phone(); p1.tel = "010-2345-5678"; p1.connect(); p1.disconnect(); SmartPhone p2 = new SmartPhone(); p2.tel = "010-1111-2222"; p2.connect(); p2.disconnect(); p2.ipAddress = "192.168.10.254"; p2.internet(); } } | cs |
>> 위 두 클래스파일을 사용해봤습니다. 실행결과를 먼저 보면,
---------- 실행 ----------
010-2345-5678에서 전화를 겁니다.
010-2345-5678에서 전화를 끊습니다.
010-1111-2222에서 전화를 겁니다.
010-1111-2222에서 전화를 끊습니다.
192.168.10.254로 인터넷에 접속합니다.
위와 같이 출력됩니다. 3~6행은 앞서 다뤘던 메소드부분에서 봐오던 형식입니다.
8~13행을 보시면, SmartPhone에 따로 구현하지 않았던 tel변수, connect메소드, disconnect메소드를 사용하고 있습니다.
이 부분이 바로 상속의 효과입니다. 자식클래스는 부모클래스의 변수나 메소드등을 따로 구현하지않아도 가져와서 사용할 수 있습니다.
--메소드 재정의 (@Override) / 매우 많이 사용됨.
: 부모클래스에 있는 메소드를 자식클래스에서 다르게 사용하려 할 때 자식클래스 안에서 다시 정의하는 것
*반환타입, 매개변수 등의 구조는 무조건 같아야한다. ( 수행문을 달리함)
*재정의된 메소드는 실행에서 최우선순위를 갖는다. ( 재정의의 재정의시 가장 최근에 재정의 된 메소드가 최우선)
1 2 3 4 5 6 7 8 9 10 11 | public class Camera { public void picture() { System.out.println("사진을 찍었습니다."); } public void save() { System.out.println("사진을 저장합니다."); } public void delete() { System.out.println("사진을 삭제합니다."); } } | cs |
1 2 3 4 5 6 7 8 9 | public class WebCamera extends Camera { // 메소드 재정의 public void save() { System.out.println("클라우드에 사진을 저장한다."); } public void delete() { System.out.println("클라우드에 사진을 삭제합니다."); } } | cs |
>> Camera클래스파일과, 그 클래스파일을 상속받은 WebCamera파일입니다.
두 클래스의 메소드타입과 이름을 보면 일치하고, 안의 수행문은 다릅니다.
(이때, 재정의된 메소드를 사용하면, WebCamera의 재정의된 메소드의 수행문이 우선적으로 실행되게 됩니다.)
1 2 3 4 5 6 7 8 9 | public class CameraApp { public static void main(String[] args) { WebCamera c = new WebCamera(); c.picture(); // 부모로부터 상속받은 메소드 사용 c.save(); // WebCamera에 재정의된 기능 사용 c.delete(); // WebCamera에 재정의된 기능 사용 } } | cs |
---------- 실행 ----------
사진을 찍었습니다.
클라우드에 사진을 저장한다.
클라우드에 사진을 삭제합니다.
--다형성 : 같은 타입에서 실행 결과가 다양한 객체를 쓸 수 있게 하는 것.
( 메소드 재정의와 타입 형 변환을 통해서 이뤄짐. )
--타입 형 변환 : 객체를 생성해서 참조변수에 대입할 때, 생성한 객체와 참조변수의 타입이 다른 경우 생성된 객체의 안쪽 방향으로 객체를
탐색해서 참조변수와 동일한 타입의 객체를 찾아서 그 객체의 주소값을 참조변수에 담는 것
(부모클래스는 자식클래스의 객체를 담는 것이 가능하다.)
ex) 부모클래스 : Tire 자식클래스 : NormalTire, SnowTire
Tire t1 = new NormalTire();
(자식클래스는 부모클래스의 객체를 담을 수 없다.)
NormalTire t2 = new Tire(); << 불가능
1 2 3 4 5 | public class Tire { public void go() { System.out.println("바퀴가 굴러갑니다."); } } | cs |
1 2 3 4 5 6 7 8 9 | public class SnowTire extends Tire { // 메소드 재정의 public void go() { System.out.println("눈에서 안전하게 바퀴가 굴러갑니다."); } public void chain() { System.out.println("타이어에 체인을 추가로 장착할 수 있습니다."); } } | cs |
1 2 3 4 5 | public class KumhoSnowTire extends SnowTire { public void go() { System.out.println("금호의 신 기술이 적용된 바퀴가 눈을 밀어내며 굴러갑니다."); } } | cs |
1 2 3 4 5 | public class HankookSnowTire extends SnowTire { public void go() { System.out.println("한국의 신기술이 적용된 타이어가 눈을 녹이면서 갑니다."); } } | cs |
>> Tire에서 SnowTire, SnowTire에서 KumhoSnowTire와 HankookSnowTire로 상속된 네 가지 클래스입니다.
1 2 3 4 5 6 7 8 9 10 11 | public class TireApp { public static void main(String[] args) { KumhoSnowTire t1 = new KumhoSnowTire(); SnowTire t2 = new KumhoSnowTire(); Tire t3 = new KumhoSnowTire(); t1.go(); t2.go(); t3.go(); } } | cs |
1 2 3 4 5 6 7 8 9 10 11 12 13 | public class TireApp2 { public static void main(String[] args) { Tire t1 = new KumhoSnowTire(); Tire t2 = new HankookSnowTire(); Tire t3 = new SnowTire(); Tire t4 = new Tire(); t1.go(); t2.go(); t3.go(); t4.go(); } } | cs |
1 2 3 4 5 6 7 8 9 10 | public class TireApp3 { public static void main(String[] args) { // KumhoSnowTire객체를 HankookSnowTire타입으로 형변환할 수 없다. HankookSnowTire t1 = new KumhoSnowTire(); //형변환 오류로인한 컴파일 오류 // Tire객체를 SnowTire타입으로 형변환할 수 없다. // 부모타입객체를 자식타입의 참조변수에 담을 수 없다. SnowTire t1 = new Tire(); } } | cs |
컴파일을 하면 4,8행은 오류가 나게 됩니다. 4행은 서로 전혀 다른 두 클래스파일이므로 형변환이 불가능하고,
8행은 자식클래스가 부모클래스를 참조할 수 없으므로 불가능하다. ( 위에서 말했듯, 부모클래스는 자식클래스 참조, 형변환 가능!)
코딩Tip!
*개방폐쇄원칙
( 확장에는 열려있고, 변화에는 닫혀있다.)
= 버전변경시 기존코드를 건드리지않고, 새로 덧붙여서 확장을 하는 것을 의미.)
상속, 상속에서 비롯된 다형성, 메소드재정의(오버라이드), 다형성을 배워봤습니다.
여러 파일들을 사용하게 되서 헷갈리실 수 있으니, 그림을 참조하셔서 이해하시는게 도움이 될 것 같습니다.
'Programming > JAVA' 카테고리의 다른 글
JAVA Web#14 Day 14 super & 추상화 (0) | 2019.03.10 |
---|---|
JAVA Web#13 Day 13 Casting & InstanceOf (0) | 2019.03.08 |
JAVA Web#11 Day 11 상수(static, final) & 패키지 (0) | 2019.03.06 |
JAVA Web#10 Day 10 this키워드 & 접근제한자 & 메소드 응용 ( getter, setter) (0) | 2019.03.05 |
JAVA Web#9 Day 9 메소드 오버로딩 & 생성자 (0) | 2019.03.04 |
- Total
- Today
- Yesterday
- h#
- Class
- spring
- querybox
- 자바 독학
- 오라클 문법
- API
- 프레임워크
- Oracle
- jhta
- 비등가조인
- 이클립스
- copotter
- 블록엘리먼트
- 태그
- sql
- 스프링
- 강제형변환
- html
- 인라인엘리먼트
- block element
- 자바 국비
- 자바 기초
- 자바
- 국비
- inline element
- 중앙HTA
- 브라캣
- Database
- 데이터베이스
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
31 |