JAVA 기초

Xonic·2021년 8월 2일
0
post-thumbnail

안녕하세요. 오늘은 JAVA라는 언어의 틀이 되는 객체지향에 대해서 살펴보고,

그 객체지향이라는 것을 실현시켜 주는 여러가지 키워드들에 대해서 살펴보도록 하겠습니다.

객체지향 프로그래밍

  • 현실세계는 모두 객체로 이루어져 있다고 보고 컴퓨터에 적용시켜 객체에 속성, 행위등을 부여하는 것입니다.
  • 여기서 속성은 해당 클래스의 고유값, 또는 변수등입니다.
  • 여기서 행위는 해당 클래스의 메서드등이라 볼 수 있습니다.

객체지향언어의 장점

  1. 코드의 재사용성이 높습니다.
    • 새로운 코드를 작성할 때 기존의 코드를 이용하여 쉽게 작성할 수 있습니다.
  2. 코드의 관리가 용이합니다.
    • 코드간의 관계를 이용해서 적은 노력으로 쉽게 코드를 변경할 수 있습니다.
  3. 신뢰성이 높은 프로그래밍을 가능하게 합니다.
    • 제어자와 메서드를 이용해서 데이터를 보호, 올바른 값을 유지하도록 하며 코드의 중복을 제거하고 코드의 불일치로 인한 오동작을 방지.

클래스와 객체

클래스

  • 클래스의 정의 : 객체를 정의 해놓은 것
  • 클래스의 용도 : 객체를 생성하는데 사용.

객체

  • 객체의 정의 : 실제로 존재하는 것. 사물 또는 개념
  • 객체의 용도 : 객체가 가지고 있는 기능과 속성에 따라 다릅니다.
  • 유형의 객체 : 책상, 의자, 자동차, TV와 같은 사물
  • 무형의 객체 : 수학공식, 프로그램 에러와 같은 논리나 개념.

클래스 변수와 인스턴스 변수

1. 클래스 변수는 해당 클래스를 인스턴스 생성 (new 키워드) 를 이용하여 생성하지 않아도 사용 가능한 해당 클래스의 클래스 변수를 말합니다. (ex.static 변수)

2. 인스턴스 변수는 해당 클래스를 인스턴스 생성 (new키워드) 후 사용 가능한 변수 입니다. (ex. 참조변수.변수명)

  • 클래스 변수: 모든 인스턴스에 공통으로 적용돼야 하는 변수. 보통 생산된 물품의 serialNo 등이 있습니다.
  • 인스턴스 변수: 기본적으로 해당 인스턴스의 속성 (TV로 예를 들면 채널, 볼륨 등) , 보통 캡슐화합니다.

상속 (extends)

  1. 상속의 정의와 장점.

    1. 기존의 클래스를 재사용하여 새로운 클래스를 작성하는 것입니다.

    2. 상속을 통해서 클래스를 작성하면 적은 양의 코드로 새로운 클래스를 작성할 수 있고 코드를 공통적으로 관리가능합니다 왜나하면, 공통적인 메서드,변수 등을 조상클래스에서 바꿔만 주면 상속받은 클래스에 영향을 끼치기 때문입니다.

    3. 조상클래스에 코드가 추가되면 자손클래스에선 영향을 받지만 자손클래스는 상속받은 메서드 등을 바꾸더라도 조상 클래스에 영향을 주지 않습니다.

    4. 생성자 초기화 블럭은 상속되지 않습니다.맴버만 상속됩니다.

    5. 자손 클래스의 인스턴스를 생성하면 조상 클래스의 멤버와 자손 클래스의 멤버가 합쳐진 하나의 인스턴스로 생성됩니다. (super()를 통해 조상 클래스의 생성자를 호출하기 때문입니다. 자세한 부분은 JVM 포스팅 글에서 명세하도록 하겠습니다.)

  2. 상속관계와 포함관계

    • 상속관계 : '~는 ~이다'.
      ex) 나무는 식물이다. 그러므로 나무는 식물의 자손이다.
    • 포함관계 : '~는 ~를 가지고 있다' ex) 티비는 채널을 가지고 있다. 그러므로 채널은 티비의 포함관계이다.
  3. 오버라이딩

    1. 오버라이딩이란 method declare(선언) 시 @Override라는 어노테이션 (annotation)을 붙여도 컴파일시 오류가 나지 않는 메서드 정의 방법입니다. (혹은 IDE에서 캐치하거나)
    2. 더 자세한 표현으로는 조상클래스를 자손이 상속받을때, 조상클래스에 있는 메서드와 이름이 같다면 오버라이딩입니다. (또한 매개변수,반환타입 등의 조건이 있습니다.)
    3. 오버라이딩의 가장 중요한 점은 다형성이라는 점입니다. 조상클래스 타입의 참조변수를 대입연산자를 통해서 자손클래스의 인스턴스를 생성하면, 조상클래스 타입의 참조변수를 통해 오버라이딩된 자손클래스의 메서드를 호출하게 됩니다. 다형성은 다음 포스팅글에서 명세하겠습니다.
      1. ex) Machine machine = new Computer(); -> Machine 이라는 조상클래스를 상속받은 Computer 인스턴스 생성.
      2. 참조변수를 통한 메서드 호출시 (machine.메서드명) 오버라이딩 된 메서드 호출됨.

오버라이딩의 조건

  • 이름이 같아야 합니다.
  • 매개변수가 같아야 합니다.
  • 반환타입이 같아야 합니다. (자손 타입으론 반환가능)
  • 접근 제한자와 예외는
    1. 조상 클래스메서드보다 좁은 범위로 변경할 수 없습니다.
      • 접근 제한자 범위는 public > protected > default > private
    2. 조상 클래스의 메서드보다 많은 수의 예외를 선언할 수 없습니다.

static 참고

  • static은 그냥 해당 클래스에만 정의하고, 묶여있다고 생각할 것 !!

자세한 사항은 staticnon-static 차이점을 따로 포스팅 하도록 하겠습니다.

this, super

들어가기 앞서 인스턴스란?
인스턴스란.
classnew 키워드로 해당 class의 생성자를 호출했을 때,
JVM Runtime Data Area에 할당됩니다. 이를 인스턴스라 부릅니다.
좀 더 쉽게 설명하자면, class는 설계도, 인스턴스는 제품 그 자체라 보면 될 것 같네요.

  • this는 현 클래스를 통해 생성된 인스턴스 주소값(포인터)입니다.
  • super는 현 클래스의 조상 클래스의 인스턴스 주소값(포인터)입니다.
  • 그러므로 자손 클래스로 인스턴스를 생성하면 동시에 부모 클래스의 인스턴스도 생성하므로 당연히 super, this를 통하여 인스턴스 주소를 구분할 수 있습니다.
  • ex) 자손클래스에서 super를 통한 부모의 메서드 혹은 멤버필드를 참조할 수 있습니다.
  • 자손 클래스에선 조상 클래스의 생성자가 반드시 호출이 되어야 합니다.
    • 그러므로 생성자를 호출할때 조상클래스의 default constructor (super()) 가 없다면 없다면 다른 생성자를 호출해야합니다. ex) super(x,y) 등과 같은
    • 만약 조상클래스의 생성자가 없다면 당연히 기본 생성자를 컴파일러가 자동으로 추가해주기 때문에 컴파일러가 자동으로 super()를 호출해줍니다.

또한 언급했듯 캡슐화란. 

캡슐화(영어: encapsulation)는 객체 지향 프로그래밍에서 다음 2가지 측면이 있다

객체의 속성(data fields)과 행위(메서드, methods)를 하나로 묶고, 실제 구현 내용 일부를 외부에 감추어 은닉한다.
참고 : https://ko.wikipedia.org/wiki/%EC%BA%A1%EC%8A%90%ED%99%94

이며, 보통 외부에서 접근하지 못하게 막는 것을 말합니다.

보통 private을 쓰며 private는 제어자라 합니다.

JAVA에서의 제어자를 설명하도록 하겠습니다.

제어자(modifier)

  1. 제어자란?
    • 접근 제어자 :
    public, protected, default, private
    • 그외 :
    static, final, abstract, native, transient, synchronized, volatile, strictfp
  2. static - 클래스의, 공통적인
    • static 멤버 변수는 인스턴스에 관계없이 같은 값을 갖습니다. 하나의 변수를 모든 인스턴스가 공유합니다.
  3. final - 마지막의, 변경될 수 없는
    • 변수에 사용하면 값을 변경할 수 없는 상수가 됩니다.
    • 메서드에 사용되면 오버라이딩을 할 수 없게 됩니다.
    • 클래스에 사용되면 자신을 확장하는 자손클래스를 정의하지 못합니다.

상수(常數, constant)란 수식에서 변하지 않는 값을 뜻한다. 이것은 변하는 값 변수와 반대이다.
참조 : https://ko.wikipedia.org/wiki/%EC%83%81%EC%88%98

  1. abstract - 추상의, 미완성의
    • 클래스에 사용하면 내부에 추상메서드가 존재하는 것을 알립니다.
    • 추상 메서드란 말 그대로 추상적인 상태로써 선언부만 있고 구현부는 없는 메서드를 말합니다.
    • 메서드에 사용하면 구현부가 작성되지 않음을 알립니다.
  2. 접근 제어자 (access modifier)
    • private : 같은 클래스내에서만 접근 가능합니다.
    • default : 같은 패키지내에서만 접근 가능합니다.
    • protected : 같은 패키지 내에서, 그리고 다른 패키지의 자손 클래스에서 접근 가능합니다.
    • public : 접근 제한이 없습니다.
  • 접근 제어자를 이용한 캡슐화
    1. 클래스나 멤버, 주로 멤버에 접근 제어자를 사용합니다.
      • 해당 이유는 내부에 선언된 데이터를 보호하기 위해서입니다.
      • 이를 데이터 감추기 , 객체지향개념의 캡슐화라 합니다.
    2. 클래스내에서만 사용되는 멤버변수 또는 메서드를 클래스 내부에 감추기 위함입니다.

다형성

  • 객체지향개념에서 다형성이란 '여러 가지 형태를 가질 수 있는 능력'이라 합니다.
  • 한 타입의 참조변수로 여러 타입의 객체를 참조할 수 있도록 프로그램적으로 구현하였습니다.
  • 참조변수가 사용할 수 있는 멤버의 개수는 인스턴스의 멤버 개수보다 같거나 적어야 합니다.
    • 조상 인스턴스 멤버 개수는 자손 인스턴스 멤버 개수보다 항상 적거나 같습니다.
  • 서로 형변환 ( 캐스팅 ) 이 가능합니다.
  • 업 캐스팅 ( 자손 인스턴스 → 조상 인스턴스 ) 만 생략 가능합니다.
  • 참조변수가 가리키는 인스턴스의 자손타입으로 형변환은 허용되지 않습니다.
    • 그래서 참조변수가 가리키는 인스턴스의 타입이 무엇인지 확인하는 것이 중요합니다.

instanceof 연산자

  • 어떤 타입에 대한 instanceof 연산의 결과가 true라는 것은 검사한 타입으로 형변환이 가능하다는 것을 뜻합니다.

참조변수와 인스턴스의 연결

  • 조상 클래스의 멤버변수와 자손 클래스의 멤버변수가 같을시
  • 인스턴스의 참조변수의 타입에 따라 달라집니다.

추상화와 구체화

  • 추상화 : 클래스간의 공통점을 찾아내서 공통의 조상을 만드는 작업
  • 구체화 : 상속을 통해 클래스를 구현, 확장하는 작업

추상클래스

  • 자손 클래스에서 추상메서드를 반드시 구현하도록 강요하는 것이라 볼 수 있습니다.

인터페이스

  • 일종의 추상클래스입니다.
  • 추상화 정도가 높아서 오직 추상메서드상수만을 멤버로 가질 수 있습니다.
  • 다른 클래스를 작성하는데 도움 줄 목적으로 작성.
  • 모든 멤버변수는 public static final 를 붙여야 하며, 생략 가능합니다.
  • 모든 메서드는 public abstract 를 붙여야하며 생략 가능합니다.

리턴타입이 인터페이스라는 것은 메서드가 해당 인터페이스를 구현한 클래스의 인스턴스를 반환한다는 것을 의미한다!!

인터페이스의 장점

  • 개발시간을 단축시킬 수 있습니다.
    • 일단 인터페이스가 작성되면 이를 사용해서 프로그램을 작성하는 것이 가능합니다. 메서드를 호출하는 쪽에서는 선언부만 알면 되기 때문입니다. 다른 쪽에서는 인터페이스를 구현하는 클래스를 작성하게 되면 양쪽에서 동시에 개발 진행이 가능.
  • 표준화가 가능합니다.
    • 기본 틀을 인터페이스로 작성한 다음, 개발자들에게 인터페이스를 구현하여 프로그램을 작성하도록 함으로써 일관되고 정형화된 프로그램 개발 가능
  • 서로 관계없는 클래스들에게 관계를 맺어줄 수 있습니다.
    • 아무런 관계도 없는 클래스에게 인터페이스를 공통적으로 구현하게 함으로써 관계를 맺어 줄 수 있습니다.
  • 독립적인 프로그래밍이 가능합니다.
    • 클래스의 선언과 구현을 분리시킬 수 있기 때문에 실제 구현에 독립적인 프로그램을 작성하는 것이 가능하다. 클래스와 클래스간의 직접적인 관계를 인터페이스를 이용해서 간접적인 관계로 변경하면, 한 클래스의 변경이 관련된 다른 클래스에 영향을 미치지 않는 독립적인 프로그래밍이 가능합니다.

인터페이스의 이해

  • 클래스를 사용하는 쪽(User)과 클래스를 제공하는 쪽(Provider)이 있다면,
  • 메서드를 사용(호출)하는 쪽(User)에서는 사용하려는 메서드(Provider)의 선언부만 알면 됩니다.(내용은 몰라도됨)

인터페이스의 디폴트 메서드

  • 인터페이스의 다수의 구현체 클래스들이 있다면, 인터페이스에 메서드를 추가하게 되면 많은 구현체 클래스에서 모두 메서드를 구현해야만 한다.
  • 그래서 디폴트메서드 (default method) 가 나왔는데, 디폴트메서드는 인터페이스의 기본 제공 메서드 이므로, 구현하지 않아도 됩니다.
  • 하지만 만약 인터페이스 ← 부모 ← 자식 (상속도를 표현) 이라는 개념이 있을때, 만약 디폴트메서드와 이름이 중복된다면 부모클래스 메서드를 따릅니다.

내부클래스

  • 장점 : 내부 클래스에서 외부 클래스의 멤버들을 쉽게 접근가능하다.
  • 코드의 복잡성을 줄일 수 있다 (캡슐화)
  • 외부 클래스의 멤버변수를 그냥 접근가능하다.
  • 당연히 static 과 인스턴스 멤버의 성질에 대해 똑같이 성립한다 예를 들면 static이 붙은 멤버는 인스턴스가 생성되지 않아도 존재할 수 있기 때문에 인스턴스를 생성하고 접근해야하고, 인스턴스 멤버에선 static 멤버를 그냥 접근가능하다.

여기까지 OOP, JAVA기초에 대해서 조금이나마 살펴봤습니다.

객체지향에 대해서 자바에선 클래스, 변수, 메서드, 추상화 등 개념들이 있으며

그에 대한 기본 개념에 대해서 알아봤습니다.

아직 자바에 대해 깊게 알지는 못하지만, 다음 포스팅 예정 글은 

non-static, static

lambda, stream

Generics, enums, annotation

jdk 버전별 api 추가사항, 수정사항 

으로 계획하고 있습니다!

제 글이 누군가에게 도움이 된다면 좋겠네요~ 감사합니다.

참조 : 자바의 정석

profile
공부 한 것을 공유하는 블로그입니다.

0개의 댓글