" async="async"> ', { cookie_domain: 'auto', cookie_flags: 'max-age=0;domain=.tistory.com', cookie_expires: 7 * 24 * 60 * 60 // 7 days, in seconds }); 'Java' 카테고리의 글 목록 :: 일단

interface란?

Java에서 abstract, final과 함께 대표적인 규제이며 Java가 추상화를 위해 제공하는 가장 유용한 도구이다.

어떤 클래스가 있고 그 클래스가 특정한 인터페이스를 사용한다면 그 클래스는 반드시 사용한 인터페이스의 메소드들을 구현해야 한다.

만약 인터페이스에서 강제하고 있는 메소드들을 구현하지 않으면 컴파일 조차 되지 않는다.

 

interface 규칙

- 인터페이스에 정의되는 멤버들의 접근제어자는 public이다.

- 하나의 클래스는 복수개의 인터페이스를 구현할 수 있다.

- 인터페이스 상속이 가능하다.

- 인터페이스는 어떤 일을 하겠다는 기능만 정의해 놓는다. 인터페이스에는 어떻게 하겠다는 구현 방법은 나타나 있지 않다. 그것은 인터페이스를 구현한 클래스들이 알아서 결정할 일이다.

 

클래스 A는 인터페이스 I를 구현한다.

클래스 A 뒤의 implements I는 이 클래스가 인터페이스 I를 구현하고 있다는 의미다. 그것은 3행의 interface I의 멤버인 public void z() 메소드를 클래스 A가 반드시 포함하고 있어야 한다는 뜻이다.

 

인터페이스와 상속은 다르다. 상속이 상위 클래스의 기능을 하위 클래스가 물려받는 것이라고 한다면, 인터페이스는 하위 클래스에 특정한 메소드가 반드시 존재하도록 강제한다.

 

interface와 abstract 차이

인터페이스와 추상 클래스는 서로 비슷한 듯 다른 기능이다. 인터페이스는 클래스가 아닌 인터페이스라는 고유한 형태를 가지고 있는 반면 추상 클래스는 일반적인 클래스다. 또 인터페이스는 구체적인 로직이나 상태를 가지고 있을 수 없고, 추상 클래스는 구체적인 로직이나 상태를 가지고 있을 수 있다.

 

interface 실질적인 쓰임 : https://opentutorials.org/course/1223/6063

위 내용은 생활코딩 강의와 토비의 스프링 내용을 정리한 것이다.

abstract = 추상

Java에서 abstract는 상속을 강제하는 일종의 규제이다.

abstract 클래스나 메서드를 사용하기 위해서는 반드시 상속해서 사용하도록 강제한다.

 

추상 클래스 사용방법

- 추상 클래스를 사용하기 위해서는 추상 클래스를 상속하는 다른 클래스를 정의하여 추상 메서드를 오버라이딩하여 사용한다.

- 추상 메소드에는 본체가 없다.(ex. public abstract int b();)

- 추상 클래스 내에는 추상 메서드가 아닌 메서드가 존재할 수 있다.

- 추상 메소드를 만들면 자동으로 그 클래스는 추상 클래스가 된다.

추상 클래스 사용하기

A 클래스는 b라는 추상 메서드를 가지고 있기 때문에 자동으로 추상 클래스가 된다.

추상 메소드인 b메서드에는 본체가 없다.(본체가 있으면 에러 발생)

추상 클래스는 추상 메서드(b)가 아닌 다른 메서드(d)를 가질 수 있다.

 

클래스 B는 추상 클래스 A를 상속하고 추상 메서드 b를 오버라이딩한다.

 

메인 메서드에서 B 클래스를 선언하여 사용할 수 있다. A클래스를 사용하면 에러가 발생한다. 꼭 A클래스를 상속하는 클래스를 사용해야 한다.(상속 강제)

 

추상 클래스를 사용하는 이유

상속을 강제하기 위한 것이다.

즉, 부모 클래스에는 메서드의 시그니처만 정의해 놓고 그 메서드의 실제 동작 방법은 이 메서드를 상속받은 하위 클래스의 책임으로 위임하고 있다.

 

공통적인 로직은 추상 클래스에 작성하고

하위 클래스에는 용도에 따라 달라지는 로직을 작성한다.

 

참고 : https://opentutorials.org/course/1223/6062

위 내용은 생활코딩 강의 내용을 정리한 것이다.

접근제어자란?

클래스 안에 소속되어 있는 멤버(변수, 메서드)에 접근할 수 있는 권한을 차등 부여하는 것이고 멤버 접근 제어자와 클래스 접근 제어자가 있다.

 

접근제어자를 왜 사용하는가?

접근 제어자를 사용하는 이유는 사용자에게 객체를 조작할 수 있는 수단만을 제공함으로써 결과적으로 객체의 사용에 집중할 수 있도록 돕기 위함이다.

 

프로그래밍은 기존에 작은 것에서 거대한 것으로, 단순한 것에서 복잡한 것으로, 단독 작업에서 협업으로 나아가게 되었다.

그러한 변화에 수용하기 위해서 다양한 규제가 필요하게 되었다.(법이 생긴 것)

그 규제들로는 데이터 타입, 리턴 타입, 접근제어자, 추상클래스, final, 인터페이스 등이 있다.

 

자유에 질서를 부여함으로서 자유를 촉진하는 것이다.

 

 

멤버 접근 제어자

 

클래스의 접근 제어자는 총 2개로 public과 default이다. default는 접근 제어자를 붙이지 않은 경우 default가 된다. 클래스의 접근 제어자는 패키지와 관련된 개념이다. 즉, 접근 제어자가 public인 클래스는 다른 패키지의 클래스에서도 사용할 수 있고, default인 경우는 같은 패키지에서만 사용 가능하다.

 

public 클래스가 포함된 소소코드는 public 클래스의 클래스 명과 소스코드의 파일명이 같아야 한다.

 

참고 : https://opentutorials.org/course/1223/6061

위 글은 생활코딩 강의 내용 정리한 것이다.

객체 지향 프로그래밍은 Object Oriented Programming의 약자이다.

Object를 번역하면 목적, 대상, 물건, 동작 따위의 대상, 감정 따위의 대상, 이상 야릇한 것? 이라고 번역된다. 제일 마지막이 맞는 것 같다. 뭔가 딱 하나로 표현하기 힘들다. 일단 자바 프로그래밍에서는 Object를 객체라고 한다. 그리고 OOP를 풀이하면 객체를 지향하는 프로그래밍이라는 것이다. 

 

말속에도 포함되어 있는데 핵심적인 키워드는 객체이다. Object!

객체가 무엇인지를 이해하는 것이 OOP를 이해하는 것이다.

 

객체란?

 

객체는 데이터(실체)와 동작(기능)을 포함한다고 한다. 위 사전에서는 기차역에서 승차권을 발매하는 경우에서 손님(실체)과 승차권 주문(동작)을 객체라고 하고 있고 현재 나의 상태인 블로그 글쓰기를 예를 들면 ildann(실체)과 글쓰기, 수정하기(동작)로 볼 수도 있다. 그리고 면접 상황을 예를 들면 면접관, 면접자, 면접장소 및 시간 등이 실체가 되고 면접 질문을 하는 것, 대답하는 것, 평가를 하는 것 등이 동작으로써 하나의 객체가 될 수도 있다. 

 

이러한 객체들을 레고 블럭처럼 조립해서 하나의 프로그램을 만드는 것을 객체 지향 프로그래밍이라고 할 수 있다.

 

하나의 소프트웨어를 만들기 위해서는 기능적인 구분을 하게 된다. 할 수 밖에 없다. 처음엔 한번에 만들려고 하겠지만 자연스럽게 기능을 구분짓고 그 기능들을 잘 모으는 것(조립)이 편하다는 것을 느끼게 된다. 이것이 그룹핑, 카테고라이징, 구획화 모두 비슷한 말들이다.

나누어진 기능들이 하나의 객체가 되고 결국 객체 지향 프로그램으로 나타나게 된 것이다.

 

설계와 추상화

현실에서 어떠한 특성과 관점을 소프트웨어화 해서 문제를 해결하는 것을 프로그래밍이라고 한다.

아주 복잡한 현실을 아주 단순하게 소프트웨어화 하는 것은 아주 어려운일이다.

 

아래 그림들은 런던의 위성사진, 단면도, 지하철 노선도이다.

첫번째 그림은 현실 그대로에 약간의 설명이 더해졌다.

두번째 그림은 조금더 단순하게 나타내고 지하철이 지나가는 길을 보여준다.

세번째 그림은 실제 단면도가 빠지고 지하철 노선도만을 나타내었다.

마지막 네번째 그림은 앞의 지하철 노선도를 더 단순하게 거의 직선으로만 나타내었다.

런던에서 이동을 할 때 마지막 지하철 노선도 보는 것이 가장 빠르고 쉽게 이해할 수 있을 것이다.

위 사진들 중 위성사진이 현실을 나타낸 것이고 마지막 지하철 노선도가 그 복잡한 현실을 아주 간단화한 것이다. 이것을 추상화(abstract)라고 한다.

 

즉, 설계라는 것은 복잡한 현실을 추상화하는 것이다. 앞서 설명했던 기차역에서 발매하는 것, 블로그에 글을 쓰는 것, 면접이라는 현실을 데이터(실체)와 동작(기능)으로 추상화하는 것이다.

 

 

부품화

초기의 컴퓨터는 지금의 데스크탑 PC와 다르게 하나의 완제품으로 이루어져있었다. 그래서 키보드가 고장나도 통째로 바꿔야하고 모니터가 고장나도 통째로 바꾸고 다른 부품이 고장나도 통째로 바꿔야했다. (물론 전문가들은 다 분해해서 고칠 수 있었겠지만)

이것들도 자연스러운 고민 끝에 기준을 만들어 기능을 나누게 된다. -> 추상화

출력 기능을 담당하는 모니터, 입력 기능을 담당하는 키보드, 연산기능을 담당하는 본체, 저장기능을 담당하는 하드로 나눈다.

이렇게 기능을 부품화 시킨 덕분에 사용자들은 더 좋은 부품들을 직접 사서 교체할 수도 있고 더 저렴한 부품으로 교체할 수도 있다. 또한 한 곳에서 문제가 발생했을 때 그 부품만 교체할 수 있고 어디서 문제가 발생하였는지도 빠르게 진단할 수 있다.

 

부품화의 정점에는 객체 지향이 있다. 연관된 메소드와 그 메소드가 사용하는 변수들을 분류하고 그룹핑하는 것이다. 그렇게 그룹핑한 대상이 객체(Object)이다.

 

 

은닉화 캡슐화

모니터가 어떻게 작동하는지 몰라도 켜고 끄고 연결하는 방법만 알면 모니터를 사용할 있다.

내부의 동작 방법을 단단한 케이스 안으로 숨기고 사용자에게는 부품의 사용방법만을 노출하고 있다.

이러한 컨셉을 정보의 은닉화와 캡슐화라고 부른다.

 

 

인터페이스

만들어진 부품이라면 부품과 부품을 서로 교환가능하다A모니터와 컴퓨터를 사용하다가 B모니터로 쉽게 바꿀 수 있다.

이유는 모니터와 컴퓨터를 연결하는 케이블 단자가 표준화가 되어있기 때문이다. 규격 사이즈가 정해져있고 몇개의 핀으로 이루어져있고 각 핀으로 어떤 데이터가 들어가는지 모두 정해져 있다. 모니터는 컴퓨터가 어떻게 동작하는지, 컴퓨터는 모니터가 어떻게 동작하는지 모르지만 정해진 약속에 따라 신호를 보내고 연결점(케이블)을 이어주면 된다. 그 모니터와 컴퓨터의 연결점을 인터페이스라고 한다.

 

 

객체 지향 프로그래밍(OOP)를 이해하기 위해서는 먼저 객체를 이해해야하고 객체 무엇인지 알아야한다.

객체는 복잡한 현실을 추상화하여 간단하게 변수와 메소드로 표현한 것이다. 그 추상화는 부품화와 같은 기능적 구분을 의미하고 부품화의 정점에 객체 지향이 있다.

객체 지향의 특징들로는 은닉화 캡슐화, 인터페이스가 있다.

 

위 내용이 전부가 아니고 생활코딩을 직접 보고 내가 이해할 수 있는 정도로 정리한 것이다.

https://opentutorials.org/course/1223/5399

 

내용 추가, 수정이 상당히 필요하다.

JVM(Java Virtual Machine)

JVM은 자바 가상 머신의 줄임말로 java 파일이 컴파일러에 의해 생성된 class 파일(바이너리 파일)을 실행하는 가상 머신이다.

JVM은 바이너리 코드를 읽고, 검증하고, 실행한다.

JVM은 플랫폼에 의존적이다. 즉, 리눅스의 JVM과 Windows의 JVM은 다르다.

각 운영체제별로 JVM이 다르지만 Java 개발자들은 JVM 위에 Java 프로그램을 올리게 되어 운영체제에 관계없이 프로그램을 개발할 수 있다. 반대로 Java 제조사에서 각 운영체제별로 JVM을 개발한다.

 

 

 

 

JRE(Java Runtime Environment)

JRE는 자바 실행 환경의 줄임말로 JVM에 Java 라이브러리와 기타 파일들이 결합된 Java 프로그램을 실행하기 위한 환경이다.

JRE는 JVM의 실행환경을 구현했다고 할 수 있다.

 

 

JDK(Java Development Kit)

JDK는 자바 개발 도구의 줄임말이다.

JDK는 JRE + 개발에 필요한 도구(javac, 디버거, 컴파일러 등)들을 포함한다.

JDK는 상업 코드 기반의 오라클 JDK와 오픈소스인 OpenJDK가 있다. OpenJDK는 오라클, Azul 등에서 제공하고 있다.

자바독을 보다 보면 Signature라는 단어가 자주 나온다. 내가 아는 시그니처는 맥도널드 시그니처, 엘지 시그니처, 유명인사들의 사인? 뿐인데...

 

아주 간단한 것이다. 아래 코드에서 메서드 시그니처는 Multiply(int a, int b) 이다.

public int Multiply(int a, int b) {
	return a * b;
}

 

자바 프로그래밍 언어에서 메서드 시그니처는 메서드 명과 파라미터의 순서, 타입, 개수를 의미한다. 리턴 타입과 exceptions는 메서드 시그니처가 아니다.

 

아래 두 메서드는 다른 시그니처를 가진다.

doSomething(String[] y);
doSomething(String y);

아래 메서드들은 모두 같은 시그니처를 가진다.

int doSomething(int y) 
String doSomething(int x)
int doSomething(int z) throws java.lang.Exception

 

출처 : https://en.wikipedia.org/wiki/Type_signature

자바의 메서드 오버로딩(Overloading)과 오버라이딩(Overriding)에 대해서 정리해보자.

 

대학교 주관식 시험문제로 나왔던 것이 기억나고 입사 교육 때도 차이점에 대해서 배웠고 입사 후 사수가 차이점을 아느냐고 물어보기도 했었다. 시간이 지날수록 대답은 짧아져갔던 것 같다.

 

두 용어는 메서드와 관련된 개념인데 실제 업무를 할 때 직접 만들어 써 본 적은 없다. (만들어져 있는 것은 보았어도 ex. println())

하지만 대학교 시험문제에 나왔던것 중에 중요하지 않았던 것은 없었다. 아니 대학교에서 배운 것들 전부.

 

0. 메서드 오버로딩 & 오버라이딩

두 개념은 자바의 핵심 개념이고 알아둘 필요가 있다.

개념을 정확하게 알고 손 코딩할 수 있을 정도의 예제도 알아두자!

 

1. 메서드 오버로딩(Method Overloading)

사전적 의미로 보면 메서드가 적재가 된다. 쌓인다. 여러 개다. 등으로 보인다.

Java Docs에서 검색해보았더니 아래와 같다.

메서드 네이밍에 대해서 설명하다 메서드 오버로딩이라는 단어가 나왔다.

메서드는 클래스 안에서 유니크한 이름을 가진다. 그

러나 다른 메서드와 같은 이름을가질 수도 있다.왜? 메서드 오버로딩 때문에!

즉, 같은 이름을 가진 메서드를 오버로딩된 메서드라고 한다.

 

자바 언어는 오버로딩 메서드를 지원하고 다른 메서드 시그니처를 가진 메서드를 구별할 수 있다.(메서드 시그니처는 메서드명과 파라미터를 말한다) 이 말은 한 클래스 내에 있는 메서드는 같은 이름을 가질 수 있는데 그 메서드가 다른 파라미터 리스트를 가졌을 경우라고 설명되어 있다. 그리고 인터페이스와 상속 부분에서 좀 더논의될 거라고 한다.

 

예제 코드를 두고 설명을 하고 있다. DataArtist라는 클래스에 같은 이름을 가진(draw) 메서드가 존재하는데존재하는데 그러기 위해서는 각메서드들은서로 다른 argument가 필요하다. (여기서 argument가아니라 parameter 일 것 같다는 생각이드는데... 자바독이 잘못되었을 리는 없을 것 같고같고 누가 좀 알려주세요.)

아래 예제에서 보듯이 같은 draw 메서드명을 사용하였지만 각각 String s, int i, double f, int i, double f와 같이 각기 다른 argument를 사용하기 때문에 에러가 발생하지 않고 구별할 수 있다. 만약 같은 argument를 사용한다면 에러가 발생한다. 왜냐하면 자바 컴파일러도 구분할 수 없기 때문이다.

public class DataArtist {
    ...
    public void draw(String s) {
        ...
    }
    public void draw(int i) {
        ...
    }
    public void draw(double f) {
        ...
    }
    public void draw(int i, double f) {
        ...
    }
}

컴파일러는 리턴 타입은 고려하지 않는다. 아래와 코드와 같이 리턴 타입이 다를지라도 같은 시그니처를 가진 메서드는 선언할 수 없다.

public class DataArtist {
    ...
    public int draw(int i) {
        ...
    }
    public double draw(int i) {
        ...
    }
}

 

정리하자면 메서드 오버로딩은 한 클래스 내에 같은 이름의 메서드를 사용할 수 있는데 그 조건으로 arguments로 작성된 데이터 타입이 다르거나 수가 달라야 한다. 그리고 리턴 타입은 상관이 없다.

 

오버로딩된 메서드는 가독성이 떨어질 수 있기에 남발하지 마라.

 

 

 

2. 메서드 오버라이딩(Method Overriding)

구글 번역기에서는 무시하는 이라고 되어있고 보통 재정의라고도 한다.

 

자바에서는 오버라이딩을 부모 클래스에서 정의한 메서드를 자식 클래스에서 변경하는 것이라고 한다. 그리고 변경하기 위해서는 자식 클래스가 부모 클래스를 상속해야 한다.

 

아래 Vehicle이라는 클래스가 있다.

public class Vehicle {

    public String accelerate(long km){
        return "The vehicle accelerate at : " + km + " km.";
    }

    public String stop(){
        return "The vehicle has stopped.";
    }

    public String run(){
        return "The vehicle is running.";
    }
}

그리고 Vehicle 클래스를 상속받는 Car 클래스가 있다.

public class Car extends Vehicle {
    public String accelerate(long km){
        return "The car accelerate at : " + km + " km.";
    }
}

메인 메서드에서 Car 클래스의 accelerate 메서드를 실행하면 결과는 "The car accelerate at : 100 km."가 나온다.

public class Main{
    public static void main(String arg[]){
        System.out.println("Test Overriding!");
        Car car = new Car();
        System.out.print(car.accelerate(100));
    }
}

 

부모 클래스(Vehicle)의 accelerate 메서드를 자식 클래스(Car)에서 재정의(오버로딩)한 것이다.

여기서도 조건이 있다.

메서드 명이 같아야 하고 파라미터와 리턴 타입이 같아야 한다는 것이다.

(위 오버라이딩 내용은 인스턴스 메서드의 경우이고 static 메서드의 경우는 조금 다르다.)

 

 

참고

https://docs.oracle.com/javase/tutorial/java/javaOO/methods.html (메서드 오버로딩)

https://docs.oracle.com/javase/tutorial/java/IandI/override.html (메서드 오버라이딩)

 

 

+ Recent posts