코딩 기록들
[Java Programming] 9.1 추상화, 인터페이스 본문
추상화
- 추상의 사전적 의미 : 여러가지 사물이나 개념에서 공통되는 특성이나 속성따위를 추출하여 파악하는 작용
+ 사물을 어떤 성질, 공통성, 본질에 착안하여 그것을 추출 & 파악하는것 (=클래스), 그 때 다른 성질을 배제하는 작용인 사상을 수반하므로 추상과 사상은 동일작용의 두 측면을 형성함
ex) 여러것들을 가져와서 다른것, 같은것을 뽑아내어 따로 정리해서 빼놓음
-> 공통된것들은 써두고(추상클래스), 다른것들은 어떻게 쓰일지 모르니 비워둠
(실무에서는 추상클래스 잘 쓰지 않는다)
추상클래스
- 어떤기능의 공통부분은 모두 구현해놓고(추상), 다른부분들만 구현하지 않은 (사상)메소드가 있는 클래스
구현하지 않은 메소드= abstract method
구현하지 않은 클래스 = abstract class
환불기능이 있는 자판기 & 일반 자판기
(공통된 기능 = 추상) : 돈넣고 -> 버튼누르고 -> 출력한다
돈통(멤버변수)을 만들고 -> 돈넣고 -> 버튼누르고 -> 출력하고 -> 환불기능(-> 사상, private로 만든다)을 만든다
(환불 = 버튼을 누를때 재고가 없다면 환불해주는것 즉, 버튼누르는 기능에서 환불기능 호출)
자판기의 추상 클래스
- abstract method가 있을경우 : 클래스의 타입도 abstract class가 되어야한다.
- abstract class는 인스턴스로 만들수가 없다. (new Seller => 식의 이용이 안된다)
- {}부분이 없으므로 어떻게 행동해야될지 모름 -> abstract class 상속받은 곳에서 overriding 해서 사용해야됨
- 추상메소드 : 기능구현이 되어있든, 되어있지않든 호출가능함
(추상화내용 피피티 교재에있는거 보지말기)
추상화의 이점
- 인터페이스나 추상클래스만으로 코드작성이 가능
- 다형성 : 하나의 인터페이스나 추상클래스로 여러개의 구현클래스 만들수있고
- 여러개의 구현클래스를 이용해 유연한 상황대처가 가능함
--> 껍데기만 추상화시키는 '완전 추상화' 방법을 더 많이 이용한다 : 인터페이스!
추상화 vs 인터페이스
- 추상클래스와 인터페이스는 :추상메소드를 만든다는 점에서 동일 (일반적으로, 추상메소드의 비율로 추상화정도 나타냄)
- 추상클래스 : class - 비완전 추상화(추상메소드와 일반메소드가 혼재할 가능성 매우높음)
- 인터페이스 : interface - 완전추상화, 추상메소드만 존재함
(인터페이스가 추상클래스보다 추상화의 정도가(유연함의 정도가) 높음 = side effect가 발생하지 않을 확률이 높다)
추상클래스의 활용
- 기존코드를 확장하려 할 때 : 기존코드는 수정하지않고, 추상클래스를 활용해 코드 전후에 해야할일 작성
인터페이스의 활용
- 제공되는 기능에대해서는 알고있지만, 환경(OS, DB,사용자 입력값 등 )별로 기능의 구현이 변경되어야 할 때
인터페이스
개발자의 약속 : '이형태(인터페이스)로 만들고 이형태로 호출해주세요 !!'
- 추상(유연함)의 정도가 높다 = side effect가 낮다 = 사상의 정도 즉, 구현시키지않은것들이 얼마나많이 있는가
1. 추상클래스 : 추상된(이미 구현된) 메소드가 존재함 -> 그 중 일부가 사상된 메소드(구현안된것들) => 100%의 사상된 클래스가 존재하지 않음 (실무에서는 사이드이펙트가 높기때문에 사용하지 않음)
2. 인터페이스 : 100% 사상의 정도를 보장함 = 전부다 구현이 안되어있고, 오직 '기능의 껍데기'만 제공함
- windows 운영체제, 키보드, 모니터, 마우스 등등의 정해진 '규격' : 인터페이스
- 인터페이스가 제공해주는걸 우리가 쓸 수 있다 (= 인터페이스가 제공하지않는것들은 우리가 쓸 수 없다)
- 개발 코드와 객체가 서로 통신하는 접점 역할을 함
--> 개발코드 : 인터페이스의 메소드 호출 -> 메소드 : 객체의 메소드 호출 => 개발코드는 인터페이스의 메소드만 알고있어도 됨
사용자 인터페이스 User Interface
UI란, 사람과 컴퓨터 시스템&프로그램 간 상호작용을 의미한다.
API Application Programming Interface
- 운영체제와 응용프로그램 사이의 통신에 사용되는 언어나 메시지 형식 ex) 자바, C++, Pascal등
- API는 프로그래머를 위한 운영체제나 프로그램의 인터페이스
인터페이스 정의에서 공통으로 나오는 주제
- 우리가 사용할 인터페이스는 : 1. 연결, 2.상호작용ex)파라미터, 3.메시지 를 모두 만들어줘야한다
자바 인터페이스의 의미
1. 클래스와 클래스가 상호작용할수 있도록 '표준'을 제공
2. 개발자간 커뮤니케이션을위한 표준 제공
인터페이스는 '다형성' 제공
- IS A 관계가 제공이 됨 ex)모니터, 키보드, 마우스 등등의 예시와 비슷한 맥락
- 하나의 인터페이스를 이용해 여러개의 클래스를 생성할수있다
* 다형성 : TV, 리모콘이 통신하는 표준규격을 통해 여러형태의 리모콘이 TV와 연결될수 있다 (TV가 제공하지않는 기능은 리모콘도 못한다!)
인터페이스 이름 작성법
- 정석) 형용사로
- 보통은) 명사로 많이 만든다
- 영어대소문자 구분, 첫글자대문자, 나머지는 소문자로 작성
- 인터페이스는 오로지 추상메소드와 상수의 정의를 위해 사용 (=상수필드와 추상메소드만을 구성멤버로 가짐)
- 인터페이스는 객체로 생성할 수 없기 때문에 생성자를 가질 수 없음 (단, 자바1.8부터는 Default Abstract Method 쓸수있지만, 많이 안씀)
상수필드 선언
- 인터페이스에는 객체사용방법을 정의한것이므로 실행시 데이터 저장을 할수있는 인스턴스, 정적필드는 선언불가능.
하지만, '상수필드' 는 선언이 가능
[public static final] 타입 상수이름 = 값;
추상메소드 선언
- 인터페이스를 통해 호출된 메소드는 최종적으로 객체에서 실행됨 -> 인터페이스의 메소드는 실행블록이 필요없는 추상메소드로 선언함
- 인터페이스에 선언된 추상메소드는 모두 public abstract의 특성을 갖기때문에, 생략하더라도 컴파일과정에서 자동으로 붙게됨
[public abstract] 리턴타입 메소드이름(매개변수, ...);
인터페이스 구현 (순서)
- 1) 개발코드 : 인터페이스 메소드 호출
-> 2) 인터페이스 : 객체의 메소드 호출
-> 3) 객체 : 인터페이스에서 정의된 추상메소드와 동일한 메소드이름, 매개타입, 리턴타입을가진 실체 메소드를 가지고있어야함 (= 인터페이스 구현객체)
-> 4) 구현객체를 생성하는 클래스 = 구현클래스 라고 함
0.인터페이스 선언은 class 키워드 대신, interface키워드를 사용
인터페이스의 메소드는 실행블록이 필요없는 추상에소드(리턴타입, 메소드명, 매개변수만 기술 & {} 중괄호 없음)로 선언
[public] interface SomeInterface {
[public abstract] void(리턴타입) doSomething1(); //abstract 생략가능
}
1.인터페이스에 상수 선언가능 _(상수명은 대문자로 작성. 선언과 동시에 초기화 반드시 해야됨)
[public static final ] 타입 상수명 = 값;
2. 인터페이스를 만든 후 구현클래스를 만들어줌 (인터페이스는 직접 인스턴스화(객체화) 할 수 없으므로 '구현클래스'가 반드시 필요함) --> 인터페이스 구현할때 : implements 키워드 사용함
public class SomeClass implements SomeInterface {
}
(참고) 클래스와 인터페이스를 함께 상속 할 때
클래스명 extends 클래스명 implements 인터페이스명, ... 인터페이스명
( extends, implements 순서 헷갈리지 말것 )
(참고) 구현클래스
public class 구현클래스이름 implements 인터페이스이름{
//인터페이스에 선언된 추상메소드의 실체메소드 선언
}
-> 구현클래스가 작성되면, new연산자로 객체 생성할 수 있음 (구현 객체를 인터페이스 변수에 '대입' 해서 사용)
3.인터페이스의 메소드는 SomeClass에서 반드시 구현해줘야됨 - SomeClass에 SomeInterface 구현
public class SomeClass implements SomeInterface {
@Override
public void doSomething1() { … }
}
-> SomeInterface와 SomeClass가 완성됨. 인터페이스와 구현클래스 사이도 IS A 관계(SomeClass is a SomeInterface)가 성립함. 따라서 아래와 같은 인스턴스 정의가 가능해짐
public static void main(String[] args) {
SomeInterface some = new SomeClass(); //SomeInterface에서 제공하는 기능만 쓸수있음
some.doSomething1();
int something = some.getSomething();
System.out.println(something);
}
클래스와 인터페이스 간 상속 조합
클래스 extends 클래스{...} | 인터페이스 extends 인터페이스 [...] |
클래스 implements 인터페이스 {...} |
- 같은 타입끼리는 extends, 다른타입끼리는 implements 사용 (단, 인터페이스는 클래스 상속 불가능)
표현주의) 클래스 A가 인터페이스 B를 상속했다 = 클래스 A가 인터페이스 B를 구현했다
다중 인터페이스 구현 클래스
- 객체는 다수의 인터페이스 타입으로 사용할 수 있음
- 인터페이스 A, 인터페이스 B가 객체의 메소드를 호출할 수 있으려면, 객체는 A, B두 인터페이스를 모두 구현해야함
public class 구현클래스이름 implements 인터페이스 A, 인터페이스 B {
//인터페이스 A에 선언된 추상메소드와 실체메소드 선언
//인터페이스 B에 선언된 추상메소드와 실체메소드 선언
}
* 다중 인터페이스를 구현할 경우, 구현클래스는 모든 인터페이스의 추상메소드에 대해 실체 메소드를 작성해야함 *
예제
1. Unit 인터페이스
public interface Unit { //인터페이스에 존재하는 모든 메소드는 추상메소드이므로 abstract 생략할수있다
//기본커맨드 : 이동, 정지, 홀드, 정찰
/**
* 이동
*/
public void move();
/**
* 정지
*/
public void stop();
/**
* 홀드
*/
public void hold();
/**
* 정찰
*/
public void patrol();
}
2. Attackable 인터페이스
//인터페이스도 상속 할 수 있다 : extends
/**
* 공격가능한 유닛 인터페이스.
* *****인터페이스는 인터페이스만 상속할수있다.******
*/
public interface Attackable extends Unit {
public void attack();
}
3. SpecialCommand 인터페이스
public interface SpecialCommand extends Attackable{
//마린, 파이어백 이라는 스팀팩? 이 있음
public void steampack(); //공격가능한 유닛만 쓸수있음
}
4. SpecialCommand 인터페이스
public class Marine implements SpecialCommand {
@Override
public void attack() {
// TODO Auto-generated method stub
System.out.println("공격");
}
@Override
public void move() {
System.out.println("Move! Move! Move!");
}
@Override
public void stop() {
System.out.println("정지");
}
@Override
public void hold() {
System.out.println("움직이지 않아요");
}
@Override
public void patrol() {
System.out.println("정찰하세요");
}
@Override
public void steampack() {
System.out.println("더 빠르게 공격~!");
}
public static void main(String[] args) {
// 인터페이스를 구현한 클래스라면, 클래스의 타입은 인터페이스여야 함 -> 그래야 인터페이스의 타입?역할을? 제한시킬수있음
// 아래 3줄은 모두 IS A 관계 성립함
SpecialCommand marine1 = new Marine(); //specialCommand를 쓸수있는 marine 객체 만들기
Unit marine2 = new Marine();
Attackable marine3 = new Marine(); //marine3은 steampack을 제외한 모든것 쓸수있음
marine1.steampack();
marine2.move();
marine3.attack();
}
}
5. Minable 인터페이스
//Scv를 위한 인터페이스
public interface Mineable {
/**
* 채굴
*/
public void mining();
}
6. Scv 인터페이스
public class Scv extends Marine
implements Attackable, Unit, Mineable{
// /// 이건 인터페이스와는 아무런 관련이 없는 기능
// -> 이렇게 따로 작성하는것이 아닌, 별도의 인터페이스를 만들어야 됨
// public void mining() {
// System.out.println("자원을 캡니다.");
// }
//인터페이스(Attackable, Unit)가 상속받는 관계가 아닐때,
// 여러개의 인터페이스를 컴마(,)로 이어붙여 구현 가능
@Override
public void mining() {
System.out.println("자원을 캡니다.");
}
@Override
public void attack() {
System.out.println("공격");
}
@Override
public void move() {
System.out.println("이동");
}
@Override
public void stop() {
System.out.println("정지");
}
@Override
public void hold() {
System.out.println("홀드");
}
@Override
public void patrol() {
System.out.println("정찰");
}
}
public class Game {
public static void move(Attackable unit) {
unit.attack();
unit.move();
unit.stop();
unit.hold();
unit.patrol();
// unit.mining(); //불가능. Attackable에는 mining이 없기 때문
// 잘못된 호출방법.
// 이렇게 하면 mining 사용할수 있기는 하지만,
// 인터페이스가 제공하지않는 기능을 억지로 제공하려고 하는
// 코드이기 때문에 아래와 같은 형태로 사용하지말것
// if (unit instanceof Scv) {
// Scv scv = (Scv) unit;
// scv.mining();
// }
if (unit instanceof Mineable) { // 좌향unit의 객체가 우향 Mineable의 인스턴스라면, true 리턴
Mineable worker = (Mineable) unit;
worker.mining();
}
}
public static void main(String[] args) {
//익명클래스 만들기 (한번쓰고 안쓸 클래스 쉽게 만드는 방법)
// Stream API(함수형 자바) 사용할 때 주로 사용되는 방법
Mineable drone = new Mineable() {
@Override
public void mining() { //인터페이스를 가지고 한번쓰고 안쓸 익명클래스 만드는것
System.out.println("드론이 미네랄을 채굴합니다.");
}
};
drone.mining();
// 추상화가 되어있는 인터페이스 = 구현되어있는 클래스 형태!
SpecialCommand marine = new Marine();
Attackable scv = new Scv();
marine.attack();
marine.steampack();
marine.move();
marine.steampack(); //가능
scv.attack();
scv.patrol();
scv.hold();
//scv.mining();//은 쓸 수 없다 -> 인터페이스는 인터페이스가 제공하는 기능만을 쓸 수 있음.
//즉, Attackable은 mining 이라는 기능을 만들어놓지 않았기 때문에 불가능함
//scv.steampack(); // 불가능
move(scv);
move(marine);
}
}
Github 관련
- github (원격)
- branch : 원본이나 복사본 관리하는것
- master : 최신상태의 원본만 관리하는것
- commit = 코드를 stage 로 올리겠다 (이과정에서 틀린코드 발견하면 올리고 내리면서 관리할수있음)
- push : stage에 있는것을 master로 올리는것
- pull :깃헙에있는 코드를 나에게 가져오는것 (stage로 가져옴)
'Java' 카테고리의 다른 글
[Java Programming] 10.1 예외처리 (0) | 2024.01.30 |
---|---|
[Java Programming] 9.2 익명 클래스 (0) | 2024.01.29 |
[Java Programming] 8.2 다형성 (메소드 오버라이딩) (0) | 2024.01.26 |
[Java Programming] 8.1 상속 (2) | 2024.01.26 |
[Java Programming] 7.1 메소드 오버로딩 (1) | 2024.01.26 |