즐겁게!! 자신있게!! 살아보세!!

재밌는 인생을 위하여! 영촤!

Language_Study/JAVA

[JAVA, App] 9.추상메소드

Godwony 2020. 12. 23. 23:04
반응형

패키지 이름이나 클래스 이름을 변경하고자 할 때

  • 직접 클릭해서 변경하는 것은 권장하지 않습니다.

  • IDE에는 대부분 리팩토링 기능을 제공하는데 리팩토링 기능을 이용해서 변경을 하면 동일한 이름으로 만들어진 모든 것을 전부 변경해줍니다.

  • Eclipse에서는 변경하고자 하는 패키지 이름이나 클래스 이름을 선택하고 마우스 오른쪽 클릭하고 [Refactor] - [Rename]을 선택하고 변경하고자 하는 이름을 입력

abstract(추상)

1) 추상 메소드

  • 내용이 없는 메소드
  • 다형성 구현을 위해서 하위 클래스에 오버라이딩 구현을 위해서 만든 메소드
  • Starcraft 라는 클래스의 attack 이라는 메소드는 없어도 실행상에는 아무런 문제가 없었지만 상위 클래스 자료형으로 만들어진 변수에 하위 클래스 자료형의 인스턴스를 대입하는 경우 변수는 상위 클래스 자료형의 요소만 사용이 가능하기 때문에 하위 클래스에 있는 attack을 호출을 못합니다.
    • attack을 호출할 수 있도록 Starcraft 클래스에 attack을 만들어 준 것입니다.
    • Starcraft의 attack 메소드는 직접 호출하기 위해서 만든 것이 하위 클래스의 메소드를 호출할 수 있도록 하기 위해서 만든 메소드입니다.
    • 이런 메소드는 내용을 가질 필요가 없습니다.
  • 메소드의 자료형 앞에 abstract를 추가하면 추상 메소드가 되고 이 메소드는 내용이 없습니다.

public abstract 결과형 메소드이름();

  • 추상 메소드는 상속받은 곳에서 반드시 구현을 해야 합니다.

    • Overriding을 해주어야 합니다.
  • 자바에서는 추상 메소드는 반드시 추상 클래스나 인터페이스에 존재해야 합니다.

2) 추상 클래스

  • 인스턴스를 만들 수 없는 클래스
  • Starcraft 라는 클래스는 실제 게임을 위해서 만든 클래스가 아니고 다형성 구현을 만든 클래스이기 때문에 직접 사용할 필요가 없는 클래스
    • 이 클래스는 인스턴스를 만들 필요가 없는 클래스 입니다.
    • 이런 클래스는 개발자가 실수로 인스턴스 만드는 것을 방지해주는 것이 좋습니다.
    • 인스턴스를 만들지 못하도록 할 때는 class 라는 예약어 앞에 abstract 가 추가해주면 추상 클래스가 됩니다.
  • 이 클래스는 상속을 통해서만 사용할 수 있게 됩니다.

final

1.변수 앞에 final을 붙이면 이 변수는 읽기 전용이 됩니다.

  • 어떤 작업을 할 때 변수의 내용을 변경하지 않는다면 굳이 일반 변수를 사용하지 말고 final을 사용하는 것이 안정성 측면에서 뛰어남

2.메소드 앞에 final을 붙이면 이 메소드는 오버라이딩 할 수 없습니다.

  • 오버라이딩: 메소드를 다시 정의 하는 것, 기능확장 또는 기능변경 할 수 있다.
  • 이 메소드가 시스템을 핸들링하거나 이름이 중요한 메소드 인 경우

3.클래스 앞에 final을 붙이면 이 클래스는 상속할 수 없습니다.

  • 상속을 못한다는 것은 기능 확장이나 변경을 못하게 하는 것입니다.
  • 시스템 관련된 클래스이거나 다른 클래스들과 연관관계가 높은 클래스라서 상속을 못하게 합니다.

Interface

  • 추상 메소드와 final 상수 그리고 default method 만을 소유한 개체
  • 인터페이스에 만들어져 있는 메소드는 거의 추상 메소드이기 때문에 인터페이스를 구현한 클래스에서는 메소드를 반드시 재정의를 해야 합니다.

    1.클래스에 인터페이스 구현

class 클래스이름 extends 상위클래스이름 implements 인터페이스이름 나열{

}

2.인터페이스는 여러 개 구현할 수 있습니다.

  • 클래스는 반드시 1개만 상속할 수 있습니다.
  • 인터페이스를 구현하면 인터페이스에 있는 메소드가 반드시 존재한다고 보장할 수 있습니다.
  • 인터페이스 이름 대신에 프로토콜(규칙, 규약, 약속)이라고도 합니다.
  • 인터페이스는 GUI 이벤트 처리에 많이 이용합니다.

3.인터페이스 생성

interface 인터페이스이름{
    상수 선언
    메소드 선언
}
  • 상수는 final을 붙이지 않아도 상수화 됩니다.
    int N = 10; => final int N = 10; 으로 해석

  • 메소드는 abstract를 붙이지 않아도 추상 메소드가 됩니다.

public void attack(); => public abstract void attack();

  • 이름을 만들 때는 able 이나 listener 라는 단어를 뒤에 붙이는 경우가 많은데 listener는 이벤트 처리를 위한 인터페이스인 경우 붙입니다.

4.인터페이스 생성과 사용

1) 인터페이스를 생성하고 변수 1개와 메소드 1개를 선언

public interface ISample {
    //final 이 없어도 final : 변경 못함
    public String TODAY = "2020-01-10";

    //abstract 가 없어도 abstract
    //내용을 만들면 안되고 ISample을 implements 한 곳에서는 반드시 Overriding(재정의)을 해야 합니다.
    public void disp();
}

2) 앞에서 만든 인터페이스를 implements 하는 클래스를 생성

  • 하나의 인터페이스를 implements 하는 클래스의 경우 이름을 인터페이스이름Impl 로 많이 정하고 클래스를 상속받는 경우는 클래스이름Ex 로 많이 합니다.
//ISample 이라는 인터페이스를 구현한 클래스
public class ISampleImpl implements ISample{

    @Override
    public void disp() {
        //인터페이스에 있는 변수를 가지고 와서 출력
        System.out.println(TODAY);
        //수정은 안됨 - 인터페이스의 변수는 무조건 상수
        //TODAY = "2020-01-11";
    }
}

3) main 메소드를 소유한 실행 클래스를 만들어서 disp()를 호출

public class Main {

    public static void main(String[] args) {
        //ISampleImpl 클래스에 있는 disp 라는 메소드를 호출
        ISampleImpl sample = new ISampleImpl();
        sample.disp();
    }
}

5.인터페이스는 생성자가 없기 때문에 인스턴스 생성을 할 수 없습니다.

  • new 인터페이스이름() 을 하는 것은 에러

6.인터페이스를 자료형으로 해서 변수는 선언할 수 있습니다.

  • 변수를 만들면 인터페이스를 implements 한 클래스의 인스턴스의 참조를 대입할 수 있습니다.

ISampleImpl sample = new ISampleImpl();

  • 위의 문장을 아래처럼 변경해도 됩니다.

ISample sample = new ISampleImpl();

7.default method

  • 인터페이스에는 내용이 있는 메소드를 만들 수 없지만 예외적으로 default method는 내용을 가질 수 있습니다.
  • 추상 메소드가 아니라서 메소드를 오버라이딩 할 필요가 없습니다.
  • 접근 지정자를 default로 설정해야만 합니다.
//인터페이스에서 내용을 갖는 메소드를 만들고자 할 때는 접근지정자로 default를 사용해야 합니다.
    default void print() {
        //메소드 내용
    }

8.인터페이스는 여러 개 구현이 가능

9.인터페이스끼리 상속 가능

interface 인터페이스이름 extends 다른인터페이스이름{
}

10.인터페이스 활용

  • 템플릿 메소드 패턴을 구현할 때 많이 사용
  • 메소드의 모양은 인터페이스에 만들어 두고 실제 구현은 인터페이스를 implements 한 클래스에 하는 것
  • C언어에서 메소드의 원형은 header 파일에 하고 구현을 c 파일에서 하는 것도 템플릿 메소드 패턴이고 하나의 파일에서 메소드의 원형은 상단에 만들고 실제 내용은 하단에 구현하는 형태도 템플릿 메소드 패턴
  • 고객과 대화하는 분석가 나 설계를 담당하는 설계자 또는 고객은 메소드의 구현 내용은 의미가 없지만 고객의 요청이 제대로 구현되어 있는지는 중요합니다.
    • 고객 이나 분석가 또는 설계를 담당하는 사람과 개발자가 대화할 때는 인터페이스를 이용합니다.
    • 고객의 요청 1개마다 메소드는 1개씩만 만들어져야 합니다.

Inner Class

1.클래스 사이의 관계

1) is a: 상속관계

2) has a: 포함관계

  • 하나의 클래스가 다른 클래스 안에서 사용되는 경우

2.InnerClass(내포 클래스)

  • 클래스 안에 존재하는 클래스
  • 일반 inner class, static inner class, local inner class, anonymous class 4가지

3.일반 inner class

  • class 안에 만들어지는 클래스
  • 내부 클래스를 외부 클래스에서만 사용하기 위해서 생성
  • 안드로이드의 이벤트 처리 인터페이스 들이 내부 인터페이스 형태로 많이 만들어져 있습니다.
  • 클래스 안에 클래스를 만들었기 때문에 소스 파일은 1개이지만 컴파일을 해서 클래스를 만들 때는 내부 클래스도 별도의 클래스로 만들어집니다.
    • 외부클래스이름$내부클래스이름.class 형태로 만들어집니다.
  • 외부 클래스는 접근 지정자가 default 와 public 만 가능하지만 내부 클래스는 private 과 protected도 가능

4.static inner class

  • inner class 에 static 멤버가 있으면 에러가 발생합니다.
  • 이런 경우에는 inner class를 만들 때 static을 붙여주면 에러가 없어지게 됩니다.
  • static 은 인스턴스를 만들기 전에 생성이 되어야 하는데 inner class는 다른 클래스 내부에 있기 때문에 코드로만 존재하다가 처음 인스턴스를 만들 때 메모리 할당을 받기 때문에 static 멤버 생성이 안됩니다.
    • class 앞에 static을 붙여서 이 클래스 자체를 메모리에 바로 할당하도록 해주어야 합니다.

5.local inner class

  • local(지역): 메소드 내부에서 생성
  • 메소드 내에서 클래스를 만들어서 메소드 내부에서만 사용할 수 있도록 한 클래스
    • 지역에 무엇인가를 만들면 지역이 실행될 때 만들어지고 지역이 종료가 되면 자동 소멸

6.Anonymous Class(익명 객체)

  • 이름없는 클래스를 가지고 인스턴스를 만들어서 사용
  • 클래스에 이름이 있으면 static(method) 영역에 메모리 할당이 되서 사용이 종료되더라도 프로그램이 종료될 때 까지 메모리에 계속 남아있게 됩니다.
  • 이름없는 형태로 만들어서 필요할 때만 메모리 할당을 해서 사용하고 사용이 종료되면 소멸시키기 위해서 사용합니다.
    • 메모리가 부족한 모바일이나 임베디드 프로그래밍에서 많이 이용
    • 안드로이드의 이벤트 처리를 이 방법을 이용해서 많이 구현했고 최근의 android studio에서는 이 문법을 사용하면 코드 최적화를 통해서 람다식(자바의 함수형 프로그래밍)으로 변환합니다.
    • 람다는 프로그래밍 언어마다 의미가 다름(파이썬에서는 한 줄 짜리 이름없는 함수)
class A {
    메소드;
}
  • A 클래스를 상속받아서 메소드를 재정의한 후 메소드를 호출
class B extends A{
    메소드 재정의
}

B ob = new B();
ob.메소드();
//(new B()).메소드(); 로 작성해도 됩니다.
  • anonymous 클래스를 이용하는 방법
new A(){
    메소드 재정의

}.메소드();
  • 새로운 클래스를 만들지 않았으므로 static 영역에 적재되지 않아서 메모리 효율이 위보다 좋아집니다.

7.실습

1) 메소드 1개를 갖는 인터페이스를 생성

  • Anonymous 인터페이스
public interface Anonymous {
    //출력하는 메소드
    public void disp();
}

2) Anonymous 인터페이스를 구현한 클래스를 만들고 disp를 재정의

  • AnonymousImpl
public class AnonymousImpl implements Anonymous {

    @Override
    public void disp() {
        System.out.println("일반적인 방법의 상속과 구현");

    }

}

3) main 메소드에 위의 메소드를 호출하는 구문을 작성

public class Main {

    public static void main(String[] args) {
        /*

        //인스턴스의 참조를 obj에 저장했으므로 인스턴스 재사용 가능
        Anonymous obj = new AnonymousImpl();
        obj.disp();
        */

        //인스턴스의 참조를 저장하지 않았으므로 인스턴스 재사용 불가능
        new AnonymousImpl().disp();
        //클래스를 만들지 않고 Anonymous 인터페이스 사용하기
        new Anonymous() {
            @Override
            public void disp() {
                System.out.println("익명 객체를 이용한 인터페이스 사용");
            }
        }.disp();
    }
}

document 구성

  • api 디렉토리 안에 있는 index.html 이 도큐먼트 시작

  • 왼쪽에 2개의 창이 있고 오른쪽에 1개의 창

    • 왼쪽 위의 창은 패키지를 출력
  • 왼쪽 아래 창은 패키지 안에 속한 인터페이스와 클래스로 구성

  • 오른쪽 창은 선택한 인터페이스 또는 클래스의 구조와 설명 및 사용 가능한 멤버를 출력

1.class

  • abstract class : 인스턴스 생성을 할 수 없다.

    • new 다음에 사용할 수 없습니다.
    • 상속을 통해서만 사용
  • final class: 상속할 수 없다.

    • extends 뒤에 나올 수 없습니다.
  • extends 뒤에 나오는 이름은 상위 클래스

  • implements 뒤에 나오는 이름은 인터페이스

  • Direct Known Subclasses: 현재 클래스를 상속받은 클래스들

2.class 설명 뒤에 나오는 항목 중 Field Summary

  • static final 변수(상수): 이 클래스에 메소드들에서 사용하는 옵션
  • 클래스이름.상수이름 의 형태로 사용하면 됩니다.

3.class 설명 뒤에 나오는 항목 중 Constructor(생성자)

  • 인스턴스를 만들기 위한 특별한 용도의 메소드: new 생성자(매개변수) 의 형식으로 호출
  • 생성자가 없는 경우

1) interface 나 abstract class 가 아닌지 확인: 인스턴스 생성을 못하므로 생성자가 없습니다.

2) 모든 메소드가 static(클래스 이름이 호출이 가능) 이라서 인스턴스 생성이 필요없기 때문

  • java.lang.System, java.lang.Math 클래스 등

3) 모든 메소드가 static 이 아닌 경우

  • 디자인 패턴(사용하는 용도에 따라 클래스를 다르게 디자인 하는 것)을 적용해서 인스턴스를 별도의 방법으로 만들도록 한 클래스

  • Singleton Pattern: 인스턴스를 1개만 만들게 하는 디자인 패턴

    • 클래스 안에서 메소드들을 찾아보면 자기 자신의 자료형을 리턴하는 static 메소드가 있어서 이 메소드를 이용해서 인스턴스를 생성
    • java.lang.Runtime 클래스가 대표적인데 이 클래스에는
    • static Runtime getRuntime() 메소드가 있어서 이 메소드를 통해서 인스턴스를 생성합니다.
    • Runtime runtime = Runtime.getRuntime();
  • Factory Method Pattern: 인스턴스를 다른 클래스의 메소드를 이용해서 생성하는 패턴

    • 자신의 클래스이름 뒤에 Factory 나 Builder 라는 이름이 추가된 클래스가 있으면 이 클래스는 Factory 나 Builder를 이용해서 인스턴스를 생성

4.Method Summary

  • 호출 가능한 메소드 목록이 출력

  • 메소드를 볼 때는 오른쪽의 리턴 타입 부분에서 static이 있는지 없는지 확인

    • static 이 있으면 인스턴스 생성없이 클래스이름으로 바로 호출이 가능하고 static 이 없는 메소드는 인스턴스를 생성해서 인스턴스.메소드이름 의 형태로 호출
  • 메소드의 매개변수를 확인: 메소드를 호출할 때 넘겨주어야 하는 데이터

  • 메소드의 리턴 타입을 확인: 결과를 저장해서 다시 사용할 수 있는지 확인

    • void 이면 결과를 다른 곳에 재사용 할 수 없기 때문에 호출하는 것으로 끝
    • 그 이외의 자료형으로 나와있으면 그 데이터를 변수에 저장해서 다른 곳에 이용할 수 있습니다.
  • 메소드를 클릭해서 메소드의 상세내용보기를 한 후 예외처리를 해야하는지 확인해봐야 하는데 이클립스에서는 * 예외처리를 해야 하는 메소드를 호출할 때 예외처리를 하지 않으면 에러가 발생

    • 에러가 발생하면 예외처리 구문으로 묶어도 됩니다.

5.Method Summary 출력 가장 하단에 박스에 있는 메소드 이름 들

  • 상속받은 그대로 사용하는 메소드들의 이름입니다.
  • 이 메소드들의 자세한 설명은 상위 클래스에서 확인해야 합니다.

6.java.lang.System 클래스에 있는 exit 라는 메소드를 이용하면 프로그램을 종료할 수 있습니다.

System.exit(0);

7.java.lang.Math 클래스에 있는 round 라는 메소드를 이용하면 반올림을 할 수 있습니다.

long l = Math.round(5.4);

8.java.lang.String 클래스에 있는 chatAt 이라는 메소드를 이용하면 문자열에서 특정 위치에 있는 문자를 추출할 수 있습니다.

  • 이 메소드를 이용해서 "Hello Java" 의 세번째 글자를 출력
String str = new String("Hello Java");
char ch = str.charAt(2);
반응형

'Language_Study > JAVA' 카테고리의 다른 글

[JAVA, App] 11.Package  (0) 2020.12.25
[JAVA, App] 10.예외처리  (0) 2020.12.25
[JAVA, App] 8.상속  (0) 2020.12.23
[JAVA, App] 7.클래스  (0) 2020.12.23
[JAVA, App] 6.검색  (0) 2020.12.23