Java - Class

BK·2024년 4월 24일
0

Java-Basics

목록 보기
4/6

Java에서는 모든게 다 class다.

Java의 모든 것은 class다. IDE에서 파일 생성만 해도 .java file에는 빈 class가 작성되어 있다. Java 프로젝트를 실행하는 방법도 프로젝트 내 어떤 class에 있는 main 함수 public static vodi main(String[] args)를 실행하는 것이다.
class에 대해 이야기 하자면 기본 문법, inner class, 상속, Object, interface, abstract class, static class 등 할 이야기가 많지만 생각나는대로 간략히 써보고자 한다.

class 작성 방법

class를 작성하는 방법은 간단하다

public class MyClass { }

끝이다.
조금 더 자세히 작성하자면 아래와 같이 작성할 수 있을 것이다.

<access-modifier> [abstract | static] class <class-name> { }
  • access modifier : 접근 제어자 이다. 변수, field, method에서와 같이 private | package(default) | protected | public 등으로 접근을 제한할 수 있다.

변수와 field의 차이는, class의 member로 존재하는 변수는 field이며, method 내 지역 변수 와 같은 변수들은 변수라고 지칭하는 것이 맞지 않을까 싶다.

  • abstract : 추상 클래스(abstract class)를 작성시 사용하는 키워드이다.
  • static : static class를 작성시 사용하는 키워드이다. 추상 클래스와 static 클래스에 대해서는 후에 기술하도록 하겠다.

위와 같이 class를 선언하고, body 부분( { } 내부 )에 필요한 내용을 작성하면 된다. 말은 간단하지만, 사실 그렇게 간단하지 않다. class의 body에는 field, method 그리고 constructor가 있다. 사실 class도 있다

필드(field)

class 내에 존재하는 변수라고 생각하면 편하다. (사실 그게 그거 아닌가)

public class MyClass {
	public var1 = "sth";
	public int id;
    private final String name;
    private List<String> courses;
}

위와 같이 field를 선언할 수 있고, 값을 직접 지정할 수도 있고, 생성자를 통해 인스턴스 생성 시 값을 할당할 수도 있다. 또한, final, static 키워드도 사용 가능하다.
변수와 필드가 무슨 차이인가 싶을 수 있지만, 객체지향 관점에서 class에 선언된 변수들은 해당 클래스의 속성(attribute)들이다. 반면 메소드 내 사용되는 지역 변수들은 객체의 속성이라 보기 어렵다. 이러한 관점에서 field와 variable을 구별하면 되지 않을까 싶다.

생성자(constructor)

보통 class를 붕어빵 틀에 비유하고, 객체를 붕어빵에 비유하곤 한다. 개인적으로 좋아하는 비유는 아니지만, 무튼 class에서 작성한 내용을 사용하기 위해서는 객체(인스턴스)를 생성해야 한다. (사실 static은 그냥 쓸 수 있다) class를 인스턴스로 생성할 수 있게 하는 것이 바로 생성자이다.
생성자를 작성하는 방법은 아래와 같다.

public class MyClass {
	...
    
    public MyClass() {
    	...
    }
}

class 이름과 같은 이름으로 작성하고, method와 유사하지만, return type은 존재하지 않는다.
접근 제어자가 존재하는 이유에 대해서 의아할 수도 있을 것 같다. 접근 제어자를 private으로 지정한다면 객체를 생성하지 못하는 것 아닌가?
반 정도는 맞는 말이다. 생성자를 private으로 지정하면 외부 객체에서 해당 class의 객체를 생성할 수 없게 된다. (그니까 안되는거 아니냐고) 하지만 디자인 패턴의 생성 패턴 중 singleton pattern을 구현하기 위해서 생성자를 private으로 지정하기도 한다. 즉, 외부 객체에서는 생성자를 호출할 수 없지만, 객체자 스스로 객체를 생성해서, class가 직접 해당 인스턴스를 제공하는 method를 구현하는 방법으로 singleton pattern을 구현할 수 있다.
생성자는 또한 parameter를 받을 수 있다.

public class MyClass {
	private String name;
    
    public MyClass(String name) {
    	this.name = name;
    }
}

위와 같이 String type의 name을 매개변수로 받아, class의 name field를 해당 값으로 초기화 하는 생성자를 작성할 수 있다.
this 키워드는 해당 class를 나타내는 것으로, 위 코드에서는 생성자 내 매개변수로 받은name과 class field name을 구분하기 위해서 사용되었다.
또한, 한 class 내에서 여러 생성자를 작성할 수 있으며, 어떤 생성자에서 this()를 통해 다른 생성자를 호출할 수도 있다.

public class MyClass {
	private int id;
    private String name;
    
    public MyClass(int id) {
    	this.id = id;
        this("unnamed");
     }
     
     public MyClass(String name) {
     	this.name = name;
     }
     
     public MyClass(int id, String name) {
     	this.id = id;
        this.name = name;
     }
}

위와 같이 생성자를 작성하면 id만으로 객체를 생성할 때, 객체의 name field를 "unnamed"로 초기화 할 수있다.

default constructor

그렇다면, 생성자를 작성하지 않으면 해당 class의 객체를 생성할 수 없을까? 그럴리가
Java의 class는 생성자를 작성하지 않으면 default constructor를 자동으로 생성해준다. 즉, 생성자를 직접 작성하지 않아도 객체를 생성할 수 있다. 기본 생성자(default constructor)는 아래와 같다.

public class MyClass {
	private int id;
    
    // default constructor
    public MyClass() { }
}

기본 생성자는 field의 값을 초기화 하거나 하지 않는다. Constructor의 body에도 어떠한 내용도 없다.(사실 있다)
class를 작성하고, field 값들을 초기화 하기 위해서 다른 생성자들을 작성하게 되는데, java는 하나의 생성자라도 개발자가 직접 작성한 경우 기본 생성자를 만들어주지 않는다. 그러니 아무 동작이 없는(사실 없는것 처럼 보이는) 생성자가 필요한 경우 직접 위 코드와 같이 작성해 주어야 한다.

super()

기본 생성자도 사실 내용이 있고, 하는일이 있다고 위에서 작성했는데, 그게 바로 super()이다.
super()은 상위 클래스의 생성자를 호출하는 것이다. 물론, super(1, "jack")같이 매개변수를 전달할 수 도 있으며, 직접 작성하여 상위 클래스의 생성자를 호출할 때에도 사용할 수 있다.
위 코드에서 생성자의 body에 아무런 코드도 없었는데, 어떻게 상위 클래스의 생성자를 호출할까? 이것도 기본 생성자와 같이 java에서 알아서 해주는거다. 생성자의 가장 첫 줄에는 super()라는 code가 생략 되어있다고 생각하면 된다.
이는 Java 메모리에서 instance가 존재하는 방식 때문인데, 상위 class의 instance가 먼저 생성되고 하위 class의 instance가 생성되어야 하기 때문이다.(당연한 이야기 같기도하다) 위 코드에서는 상위 클래스가 없는 것처럼 보이지만, 사실 java의 모든 class는 Object라는 class를 상속받는다.
즉, 위 코드는 사실 아래와 같다.

public class MyClass extends Object {
	private int id;
    
    // default constructor
    public MyClass() {
    	super()
    }
}

메소드(method)

함수다. 변수와 field의 차이처럼, class의 어떠한 기능을 하는 것을 메소드라고 생각하면 될 것 같다.

public class MyClass {
	private int id;
    
    public void setId(int id) {
    	this.id = id;
    }
    
    public int getId(int id) {
    	return id;
    }
}

위와 같이 작성해 private field인 id의 값을 set/get 하는 setter-getter를 구현할 수 있다.
또한 class의 method 또한 static일 수 있으며, 아래와 같이 객체를 생성하지 않고 method를 사용할 수 있다.

public class MyClass {
	private static instance = new MyClass();
    
    private MyClass() { }
	
    public static MyClass getInstance() {
    	return this.instance;
    }
}

위와 같이 singleton pattern을 구현하고, 다른 객체에서 MyClass.getInstance()를 통해 객체를 참조할 수 있다.

서두에서 interface, abstract class, static class 등 다양한 말을 썼는데, 글을 쓰다보니 두서없이 글이 길어졌다. 이 글에 수정하여 추가할지, 새로운 글을 작성할지는 모르겠지만 생각나는데로 해당 내용들에 대해 작성해봐야겠다.

0개의 댓글