클래스

클래스는 자주 쓰이는 요소들을 미리 선언해둔다라는 개념이다.
광의의 개념으로 Properties(props) 와 Functions(func) 부분으로 나눌 수 있다.


특성

소스코드 단위로 관리할 수 있는 가장 큰 단위

  1. 주어이다.
    모든 문장 앞에는 클래스가 나오고 영어는 맨 앞을 항상 대문자로 적는다.
    따라서 클래스는 주어이고 항상 대문자로 시작한다.
    ```java
    String food="banana";
    Monkey.eat(food);
    [클래스].[메소드]([변수]);
    [주어].[동사]([명사]):
    ```
  2. 타입이다.
    클래스는 추상화 개념으로서,
    클래스의 각 항목을 사용하기 위해서는 인스턴스화 (객체화) 가 필요하다.
    여기서 인스턴스는 예, 예시 라는 뜻이고 실제로 존재한다 라는 의미를 품고 있다.
    따라서 클래스는 추상화 개념임과 동시에 수많은 예시들의 타입으로서 존재하게 된다.
    그래서 우리는 클래스를 타입이라고 정의할 수 있다.
  3. 가장 구체적인 추상화이다.
    선언 후 할당되지 않은 변수,
    작성되지 않은 메소드가 있으면 추상화 정도를 가진다.

속성(props)

클래스의 속성이란,
클래스 내부에 선언되어 있는 함수이다.
이 속성값들은 클래스 내부에서만 참조할 수 있다.

예를 들어,
서로 독립된 클래스 A,B는 서로의 내부 변수를 참조할 수 없다.
후술할 상속개념을 적용해도 동일하다.
B를 상속하고 있는 A클래스의 내부 함수는 B클래스의 변수를 참조할 수 없다.
별도의 방법이 있는지는 아직 모르겠다.


함수(method)

클래스의 함수란,
메서드와 생성자로 나뉘어져있다.
여기서 생성자란 별도로 작성하지 않아도 기본 생성자가 클래스 안에 선언되어 있다.
여기서 메서드란 선언한 클래스가 할 기능들을 미리 선언해둔 것이라고 생각하면 좋다.

참고로 함수라고 표현한 이유는
클래스의 내부에 생성자와 메소드가 존재하기 뿐이고 정확한 명칭은 이 둘이다.

Overloading

메서드는 클래스 내부 함수의 일종으로,
미리 선언해둔 기능들을 실행하는 함수이다.

하지만 받아들이는 변수의 수나 타입의 변화에 따라서,
동일 이름의 메서드가 해당 변화에 대응할 필요가 있다.
이런 이슈를 Overloading 을 통해서 해결할 수 있다.

Overriding

클래스 간의 Inheritance 이후에,
자식 클래스에서 부모 클래스의 속성값을 변경해야 할 상황이 있다.

그러한 경우에 필요한 타입의 변수를 매번 선언하여 사용하는 것은 비효율적이다.
이러한 경우 우리는 부모 클래스의 변수를 참조하여 변경, 사용할 수 있다.

Overloading 과의 차이점은
Overloading 은 부모 클래스에 작성된 메서드이고
Overriding 은 자식 클래스에서 작성된 메서드라는 것이다.

super

클래스 간의 Inheritance 이후에,
자식 클래스와 부모 클래스에 이름이 같은 변수가 있을 수 있다.

그러한 경우에 두 클래스의 변수를 구분 할 방법이 필요하다.
기본 값으로는 본인의 변수를 참조하기 때문에, 부모 클래스를 참조할 키워드가 있다.

변수의 이름이 sum 이라고 할 때,
super(sum) 이라고 작성하면 부모 클래스의 변수가 참조 된다.

this

클래스 내부 함수에,
메서드 내 외부에 이름이 같은 변수가 있을 수 있다.

그러한 경우에 두 변수를 구분할 방법이 필요하다.
기본 값으로는 메서드의 변수를 참조하기 때문에, 메서드 외부의 변수를 참조할 키워드가 있다.

변수의 이름이 sub 이라고 할 때,
this.sub 이라고 작성하면 메서드 외부(클래스 내부) 변수가 참조 된다.

Constructor

생성자는 클래스 내부 함수의 일종으로,
클래스의 인스턴스화 중에 무조건 한 번은 실행되는 함수이다

Initialization

변수를 선언하고 처음으로 값을 저장하는 것을 변수의 초기화 라고 한다.
Unexpectation Error 을 피하기 위해서, 이 과정은 필수적으로 이루져야 한다.

자동으로 자료형의 default 로 초기화 되는 멤버변수 와는 달리,
지역변수 는 별도로 지역변수를 초기화해야한다.

아래처럼 명시적 초기화:Explicit Initialization 을 할 수도 있지만,
초기화 블럭:Initialization Block을 별도로 작성할 수도 있다.

초기화의 구조가 복잡하거나,
일괄적인 변수의 초기화가 필요한 경우에 작성하도록 하자.

  • Explicit Initialization
class InitTest{
  int x;
  int y=x;
  void method1(){
    int i=0;
    int j=i;
  }
}
  • Initialization Block
class InitTest{
  //초기화 블럭
  {
    count++;
    serialNo=count;
  }
  // 기본 생성자
  Car() { 
    color="white";
    gearType="Auto";
  }
  // 오버로딩
  Car(String color, String gearType){
    this.color=color;
    this.gearType=gearType;
}
}

Inheritance

상속이란,
한 클래스가 다른 클래스를 부모로 받아들임으로써,
부모 클래스의 모든 Properties 와 Functions 을 가져온다라는 개념이다.

이에 따라 관련성 및 종속성 의 특징을 가지게 된다.

기본적으로는 단일상속의 원칙을 따르지만 특정한 방법으로 다중상속을 시킬 수 있다.
하지만 이에 따라, 구조 및 추상화 정도의 모호함으로 추천하는 방법은 아니다.
따라서, 꼭 필요한 경우에만 다중 상속의 구조를 하는 것이 좋다.

class Point {
  int x;
  int y;
}
class Circle extends Point {
  int r;
}

Conatins

구조적인 개념은 상속과는 동일하다.
하지만 포함 관계의 하위 객체는 관련성을 제외하고 종속성이 강화된 형태를 지니게 되는데,
이를 확인할 수 있는 몇 가지 결과가 존재한다.
0. import 안할 시 사용불가
1. 외부 클래스의 타입으로 선언된 영역에 할당 불가
2. 내부 클래스를 사용하려면 외부 클래스를 지나야 함
자세한 내용은 아래 내부 클래스 탭 을 확인하자


추상 클래스

Abatract Class 는 구문 앞에 제어자 abstract 를 붙이는 것이 전부이다.
일반적인 Class 처럼 Properties, Method, Constructor 를 다 가질 수 있다.
그렇다면 어떠한 경우에 Abastract Class를 작성하는 것일까?

그것은 Abstract 에 따라서 딸려오는 강제성에서 찾을 수 있다.

abstract class Action {
  abstract void attack();
}
class Player extends Action {
  void attack() {
    System.out.println("공격");
  }
}
public class Main {
    public static void main(String[] args) {
        Player player=new Player();       
        player.attack();
    }
}

위 코드에서 attack 메서드를 오버라이딩 하지 않으면 에러가 생긴다.
추상화 메서드는 { // 구문 } 을 작성하지 않아도 되지만,
일반 메서드는 { // 구문 } 을 작성해야만 하기 때문이다.

이렇듯 우리는,
자식 클래스에게 오버라이딩을 강요 하기 위해서,
Abtract Class 를 사용할 수 있다.


인터페이스

인터페이스는 일종의 Abstract Class 이지만,
Abstract Level이 훨씬 높아서 멤버변수와 몸통을 갖춘 일반 메서드를 가질 수 없다.

이러한 Interface 에는 몇 가지 제약사항이 있다.
1. 모든 멤버변수는 public static final 이여야 하며, 이를 생략 할 수 있다.
2. 모든 메서드는 public abstract 이여야 하며, 이를 생략 할 수 있다.

interface PlayingCard {
  public static final int SPADE=4;
  final int DIAMOND=3;
  static int HEART=2;
  int CLOVER=1;
  public abstract String getCardNumber();
  String getCardSort();
}

위에 선언된 모든 Variables 는 public static final 이 되며,
역시 모든 Method 는 public abstract 가 된다.


내부 클래스

정의

클래스 내부에 선언된 클래스이다.
중첩 클래스의 종류 중 하나인데 다른 포스트를 참고하자.
1. 4대 중첩클래스
2. 중첩클래스를 알아보자!

코드

public class Main{
  public static void main(String[] args){
  	OutClass out=new OutClass();
  	InClass in=out.new InClass();
    InClass.
  }
}
class OutClass {
  String nameOfOut="OutClass";
  Inclass returnInClass(){
  	return new InClass();
  }
  class InClass{
  	String nameOfIn="InClass";
    void printName(){
    	System.out.println(nameOfOut); // OutClass
        System.out.println(nameOfIn); // InClass
    }
  }
}

종속성 여부

부모-자식 클래스 보다 더욱 강한 종속성을 가지게 된다.

내부 클래스는 외부 클래스를 통하지 않고는 사용할 수 없는 특성을 가진다.
이를 통해, 개발자가 숨기고 싶은 데이터에 대한 접근을 제어할 수 있는 보조적인 특성이 생긴다.

=> 하지만 결국 코드 상에서 호출하면 불리는데, private 키워드 없이는 무의미한 것 아닌가?

동일한 Key 의 변수

외부 클래스와 내부 클래스의 전역변수 이름이 동일하면,
내부 클래스의 매서드에서 호출 시에 내부 클래스의 전역변수가 호출 된다.

중첩 클래스

REF : 4대 중첩클래스

종류

  1. member 클래스
    멤버변수 영역 안에 선언된 클래스
  2. local 클래스
    로컬 영역 안에 선언된 클래스
  3. static 클래스
    정적 영역 안에 선언된 클래스
  4. annonymouse 클래스

차이는?

  • 소멸 시기의 차이.
    마치 JS 에서 객체(클래스가 아닌 단순한 객체)를 사용했듯이,
    Java에서도 중첩 클래스를 통해서 매개변수로 넘겨줄 데이터들을 객체화 한 것일듯 하다.
    => 다만, 이 설명으로는 익명 클래스를 설명할 수 없는데..?

이슈

변수와 클래스의 미할당시 기본값 여부

  • 변수의 경우 할당하지 않으면 에러가 뜨는데,
    클래스의 경우 생성자를 설정하고 생성자 안에서 할당 절차를 걸치지 않아도 알아서 기본값을 가지게 되는 이유가 무엇인가?
profile
문제없는 기록

0개의 댓글