자바의 추상화, extends, include, implements 차이
1. 추상화란 무엇인가
추상의 뜻 : 여러 가지 사물이나 개념에서 공통되는 특성이나 속성 따위를 추출하여 파악하는 작용.
抽: 뺄 추
象: 코끼리 상
코끼리 형태의 상의 구조를 빼낸 다는 것이다.
일반화라고 생각하면 된다.
추상화를 사용하면 코드의 재사용성, 가독성을 높이고,
생산성의 증가, 에러의 감소, 유지 보수에 있어 많은 시간을 줄일수 있다.
2. 추상화의 종류
2.1 변수와 상수의 추상화
1 2 3 4 5 6 7 8 | public class MyValue{ int value = 1; static final double PI = 3.14; static final int Week = 7; } | cs |
변수와 상수를 추상화하지 않는다면 매번 같은 value를 반복해서 넣어야 할 것이다.
2.2 반복문의 추상화
1 2 3 4 5 6 7 | System.out.println("a"); System.out.println("a"); System.out.println("a"); for(int i=0; i<3; i++){ System.out.println("a"); } | cs |
반복문 또한 추상화이다.
반복문을 사용하지 않는다면 a의 갯수에 따라 a를 출력하기 위해 3줄 이상 적어야하지만
반복문을 사용한다면 문자 a의 갯수에 따라 a를 찍는 것을 한줄로 끝낼수 있다.
2.3 함수의 모듈화 및 재사용
파람값 리턴값 모두 함수단위로 쪼개서 넣고 받는다.
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 | package test1; public class Animal { public int legsCount = 4; public int tailCount = 1; public int fightingPower = 300; public int weight = 400; // 동물은 기본적으로 다리4개, 꼬리1개, 전투력300, 무게 400을 가지고 있다. public int getLegs() { return legsCount; } public int getTail() { return tailCount; } public int getFightingPower() { return fightingPower; } public int getWeight() { return weight; } } | cs |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | package test1; public class Bird extends Animal{ public int wings = 2; // 동물은 기본적으로 다리4개, 꼬리1개, 전투력300, 무게 400을 가지고 있다. // 새는 동물이지만 다리2개, 꼬리 0개 이다. public int getLegs() { return super.getLegs()-2; } public int getTail() { return super.getTail()-1; } public int getWings(){ return wings; } } | cs |
Animal에서 상속받은 getLegs(), getTail() 메서드를 Bird에서 부모클래스의 메서드값을 불러와 계산하여 리턴값으로 재정의하고 있다.
함수안에서 부모메서드를 호출하는 행동, 선언 및 초기화 해 놓은 변수를 사용하는 행동 모두 모듈화 및 재사용의 포함된다.
그럼 이 개념을 적용해서 모델을 만들어 보자.
구조를 설명하면
Animal(동물)을 상속받은 Bird(조류), Mammal(포유류) 클래스
Animal(동물)을 상속받은 Bird(조류)를 상속받은 IslandChicken(무인도닭)
IslandChicken(무인도닭)은 클래스이므로 자바에서는 단일상속만 가능해 Mammal(포유류)를 상속받을 수 없다.
그래서 Mammal(포유류)를 상속받기 위해서 interface MammalInterface를 만들었고 IslandChicken에서 implements 하고 있다.
나머지 LandAnimalInterface(육지동물인터페이스), AnimalInterface(동물인터페이스)를 implements 하고 있다.
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 | package test1; public class Animal { public int legsCount = 4; public int tailCount = 1; public int fightingPower = 300; public int weight = 400; // 동물은 기본적으로 다리4개, 꼬리1개, 전투력300, 무게 400을 가지고 있다. public int getLegs() { return legsCount; } public int getTail() { return tailCount; } public int getFightingPower() { return fightingPower; } public int getWeight() { return weight; } } | cs |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | package test1; public class Bird extends Animal{ public int wings = 2; // 동물은 기본적으로 다리4개, 꼬리1개, 전투력300, 무게 400을 가지고 있다. // 새는 동물이지만 다리2개, 꼬리 0개 이다. public int getLegs() { return super.getLegs()-2; } public int getTail() { return super.getTail()-1; } public int getWings(){ return wings; } } | cs |
1 2 3 4 5 6 7 8 9 10 | package test1; public class Mammal extends Animal{ // 동물은 기본적으로 다리4개, 꼬리1개, 전투력300, 무게 400을 가지고 있다. // 포유류는 동물의 속성을 다 상속받지만 털을 가지고 있다. public String getFur(){ return "털을 가지고 있다."; } } | cs |
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 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 | package test1; public class IslandChicken extends Bird implements AnimalInterface, LandAnimalInterface, MamalInterface{ public int averageSpeed = 50; public int averageLength = 60; // if you define Override Annotation, eclipse inform you // must override or implement a supertype method // 조류의 다리는 2개이지만 무인도의 사는 특별한 닭의 다리는 1개라고 한다. @Override public int getLegs() { return 1; } // AnimalInterface 인터페이스에 선언된 callSound 내용 구현 @Override public void callSound() { System.out.println("꼬꼬댁"); } // AnimalInterface 인터페이스에 선언된 runSpeed 내용 구현 @Override public int runSpeed(int number) { return number; } // LandAnimalInterface 인터페이스에 선언된 specialty 내용 구현 @Override public void specialty() { System.out.println("발로 땅을 팔수 있음"); } // LandAnimalInterface 인터페이스에 선언된 bodyLength 내용 구현 @Override public int bodyLength(int number) { return number; } // LandAnimalInterface 인터페이스에 선언된 getFur 내용 구현 @Override public String getFur() { return "털을 가지고 있다."; } public static void main(String[] args) { // IslandChicken 생성자 만듬 IslandChicken islandChicken = new IslandChicken(); // 동물은 다리 4개, 꼬리1개, 조류(extends 동물)는 다리 2개 꼬리 0개, 무인도닭(extends 조류) 다리 1개 // 클래스는 다중상속이 안되니깐 상속의 상속으로 부르고 있는 구조 islandChicken.getTail(); //returns 0 동물의 꼬리는 1개인데 조류에서 꼬리 0개로 메소드 재정의해서 0 islandChicken.getLegs(); //returns 1 조류에서 다리 2개로 상속받았는데도 불구하고 무인도닭에서 메소드 재정의시 1 islandChicken.getWings(); // returns 2 조류에서 상속받은 날개 2개 // Bird 생성자 만듬 Bird bird = new Bird(); bird.getTail(); //returns 1 bird.getLegs(); //returns 2 // Animal 클래스의 메소드 호출 bird.getFightingPower(); //returns 300 bird.getWeight(); //returns 400 // AnimalInterface, LandAnimalInterface 메소드 호출 islandChicken.callSound(); // 꼬꼬댁 islandChicken.runSpeed(islandChicken.averageSpeed); // 50 islandChicken.specialty(); // 발로 땅을 팔수 있음 islandChicken.bodyLength(islandChicken.averageLength); // 60 } } | cs |
여기서 보면 getLegs()메서드는 Animal부터 Bird , IslandChicken 클래스까지 재정의하고 있다.
메소드 이름을 같게 하여 서로 상속받게 하여 어떤 결과가 나오는지 확인해보았는데
IslandChicken에서 getLegs() 오버라이드 어노테이션을 붙이니 must override or implement a supertype method 경고가 떴다.
재정의시 값은 가장 위쪽에서 새로 재정의한 값으로 나왔다.
3. include, extends, implements difference
이 공부를 하면서 자바는 왜 extends와 implements를 구별해서 쓰는가라는 의문이 들었다.
복잡하게 그냥 다 extends 하면 안되나?, implements 다 하면 안되나?
자식클래스의 extends 부모클래스 implements 인터페이스1, 인터페이스2 ...
부모클래스 들어가면 extends 부모의부모클래스 등... 상속의 상속을 거듭하고
구조가 복잡해지는데 적절하게 언제 extends를 하고 언제 implements를 하고 언제 include를 하는지 알아보았다.
그래서 include, extends , implements에 대해 정리해보았다.
3.1 include와 extends 차이
include는 프로젝트의 필수(must) 기능을 나타내지만
extends는 선택적(should / could / want) 동작을 의미한다.
use case -> 나 도시에 갈 예정이야
include -> 차 타고 간다.
extends -> 가솔린을 채워라
가솔린을 채우는 건 항상 필요한 일이 아니다.
가솔린이 있어야 차가 동작하는데 가솔린이 있다면 안채워도 되는 것이다.
가솔린이 떨어졌을때 선택적(optionally)으로 필요한 것이다.
하지만 차타고 가는 건 꼭 필요한(prerequisite) 것이다.
3.2 extends와 implements 차이
언제 extends를 써야하고 implements를 써야하나?
일단 extends의 용도와 의미부터 생각해보면
3.2.1 주용도와 형태가 다름
extends
클래스를 확장하기 위한 것이고( 클래스는 선언과 내용이 들어가 있는 것 )
implements
인터페이스를 구현하기 위해 생긴 것이다. ( 인터페이스는 선언만 되어 있는 것 )
3.2.2 단일상속 문제해결을 위해
자바에서 클래스 단일상속만 가능함(java doesn't support multiple inheritance for classes)
하지만 인터페이스 다중상속을 통해 해결가능함.(but this is solved by using multiple interfaces.)
이러한 것들로 인해 include, extends, implements를 적절히 구분하여사용해야 할 것이다.
마지막으로 소스와 작업한 파일을 올린다.