- 백기선 님이 유튭에서 진행하는 JAVA Live-study 과정을 기록한다.
- 매 주 이슈에 올라온 질문들에 대해 공부하고 답을 남기고, 이슈에 링크를 공유하는 방식으로 진행된다. 추후 백기선 님의 유튜브 라이브를 통해 피드백을 받게 된다.
- 조금 늦더라도 과제를 수행하면 출석 인정을 해주시기로 했다!(늦더라도 꼭 공부하는게 중요!)
즉, Java 공부를 기록하는 과정이다 🌱
📌 목표
자바의 Class에 대해 학습하세요.
📌 학습할 것 (필수)
- 클래스 정의하는 방법
- 객체 만드는 방법 (new 키워드 이해하기)
- 메소드 정의하는 방법
- 생성자 정의하는 방법
- this 키워드 이해하기
1. 구조체 vs 클래스
[Java에는 클래스만 존재한다.]
구조체와 클래스는 상당히 유사한 부분들이 있지만, 분명 다르다.
C 언어의 경우 클래스와 구조체는 확실하게 다르다.
- 클래스에는 메소드(함수)도 포함될 수 있다.
- 멤버 변수와 메소드는 public 이 아니라면 숨겨져 있다.
- 생성자와 소멸자가 존재한다.
- 멤버 함수로서 연산자 재정의(overloading)가 가능하다.
- 상속 관계가 존재한다.
- 구조체의 경우 객체를 생성할 때,
struct Hello hello;
와 같은 struct 키워드가 필요하지만, 클래스의 경우 class 키워드를 생략할 수 있다.
BUT!!!
C++ 의 경우 클래스와 구조체는 몇 가지의 차이점만 존재한다.
1) 클래스의 기본 접근성은 private 이고, 구조체는 public 이다. |
2) class/struct를 상속받는 struct는 부모 class/struct에 대해 public 하다. class/struct를 상속받는 class는 부모 class/struct에 대해 private 하다. |
1) 클래스의 기본 접근성은 private 이고, 구조체는 public 이다.
// Program 1
#include <stdio.h>
class Test {
int x; // x is private
};
int main()
{
Test t;
t.x = 20; // compiler error because x is private
getchar();
return 0;
}
Test 클래스의 멤버 변수 x는 private이므로 메인 함수에서 직접 접근하는 t.x = 20;
에서 컴파일 에러가 발생한다.
// Program 2
#include <stdio.h>
struct Test {
int x; // x is public
};
int main()
{
Test t;
t.x = 20; // works fine because x is public
getchar();
return 0;
}
Test 구조체의 멤버 변수 x는 public이므로 메인 함수에서 직접 접근하는 t.x = 20;
이 정상적으로 실행된다.
2) class/struct를 상속받는 **struct**는 부모 class/struct에 대해 **public** 하다. class/struct를 상속받는 **class**는 부모 class/struct에 대해 **private** 하다.
// Program 3
#include <stdio.h>
class Base {
public:
int x;
};
class Derived : Base { }; // is equilalent to class Derived : private Base {}
int main()
{
Derived d;
d.x = 20; // compiler error becuase inheritance is private
getchar();
return 0;
}
상속받은 클래스는 부모 클래스에 private이므로 멤버 변수에 직접 접근이 불가하다.
// Program 4
#include <stdio.h>
class Base {
public:
int x;
};
struct Derived : Base { }; // is equilalent to struct Derived : public Base {}
int main()
{
Derived d;
d.x = 20; // works fine becuase inheritance is public
getchar();
return 0;
}
상속받은 구조체는 부모 클래스에 public이므로 멤버 변수에 직접 접근이 가능하다.
(출처: https://www.geeksforgeeks.org/structure-vs-class-in-cpp/)
2. Java 클래스
Oracle Java Tutorial 에 따라 학습을 진행함.
1) What Is an Object?
이 글의 서두가 상당히 재미있었다.
주변을 둘러보며 사물(객체)의 state(상태)와 behavior(행동)을 식별해보는 것이 객체지향이라는 용어를 생각해보는 좋은 방법이라고 제안한다.
탁상 램프는 켜짐, 꺼짐라는 두 가지의 상태와 켜기, 끄기라는 두 가지의 행동이 존재한다.
라디오는 커짐, 꺼짐, 현재 볼륨, 현재 방송국이라는 상태와 켜기, 끄기, 볼륨 올리기, 볼륨 줄이기, seek, scan, tune이라는 행동이 존재한다.
객체마다 상태와 행동의 수도 다르고, 심지어 어떤 객체는 다른 객체를 포함하고 있다는 것을 알아챌 수도 있다는 것이다.(상속)
객체의 state는 필드(다른 언어에서는 변수라고 부르는)에 저장되고 behavior는 메소드(다른 언어에서는 함수라고 부른다)에 구현된다.
메소드는 개체 대 개체 통신을 위한 기본 메커니즘 역할을 한다.
내부 상태를 숨기고 오로지 모든 상호작용이 객체의 메소드를 통해서 수행되도록 요구하는 것이 데이터 캡슐화(Data encapsulation)이라고 한다.
2) 클래스의 정의
위에서 설명한 자전거를 Class로 구현하면 다음과 같다.
class Bicycle {
int cadence = 0;
int speed = 0;
int gear = 1;
void changeCadence(int newValue) {
cadence = newValue;
}
void changeGear(int newValue) {
gear = newValue;
}
void speedUp(int increment) {
speed = speed + increment;
}
void applyBrakes(int decrement) {
speed = speed - decrement;
}
void printStates() {
System.out.println("cadence:" +
cadence + " speed:" +
speed + " gear:" + gear);
}
}
-
클래스의 멤버 변수를 필드라고 부른다.
-
필드의 선언은 다음과 같은 형식을 가진다.
modifier
type
name
=>public
int
speed
-
접근 제어자(Access Modifiers)란?
- 접근 제어자는 다른 클래스가 필드에 접근하는 것을 제어할 수 있습니다.
1) public: 어떤 클래스에서라도 접근이 가능하다.
2) private: 메소드는 해당 클래스에서만 접근이 가능하다.
3) default: 접근제어자가 없는 변수, 메소드는 default 접근제어자가 되어 해당 패키지 내에서만 접근이 가능하다.
4) protected: 동일 패키지내의 클래스 또는 해당 클래스를 상속받은 외부 패키지의 클래스에서 접근이 가능하다.
- 접근 제어자는 다른 클래스가 필드에 접근하는 것을 제어할 수 있습니다.
-
3) 메소드의 정의
메소드의 선언은 다음의 항목들을 포함한다.
1) 접근 제어자
2) 리턴 타입
3) 메소드 이름 - 네이밍 컨벤션을 따른다. camelCase.
4) 파라미터
5) 예외 처리 - 이후 다룰 내용
6) brace로 닫힌 메소드의 내용
void changeCadence(int newValue) {
cadence = newValue;
}
4) 생성자의 정의
생성자는 blueprint로만 존재했던 클래스의 실제 object를 생성할 때 호출된다.
메소드의 정의와 비슷하게 생겼지만, 생성자의 이름으로 클래스의 이름을 사용한다는 점이 다르다.
위에서 정의한 자전거 클래스의 생성자이다.
public Bicycle(int startCadence, int startSpeed, int startGear) {
gear = startGear;
cadence = startCadence;
speed = startSpeed;
}
이제 객체를 생성하기 위한 생성자를 정의했으니, 실제 자전거 객체를 myBike라는 이름으로 생성해보자.
Bicycle myBike = new Bicycle(30, 0, 8);
여기서 객체를 생성하기 위해 new 라는 연산자를 사용했다.new Bicycle(30, 0, 8)
은 myBike라는 변수의 실제 공간을 Heap 영역에 할당하고, 그 주소값을 메모리의 Stack 영역에 저장한다.
생성자는 파라미터의 개수에 따라 여러 개 만들 수 있다.
public Bicycle(int startCadence, int startSpeed, int startGear) {
this.cadence = startCadence;
this.speed = startSpeed;
this.gear = startGear;
}
public Bicycle(int startCadence, int startSpeed) {
this.cadence = startCadence;
this.speed = startSpeed;
}
public Bicycle(int startCadence) {
this.cadence = startCadence;
}
public Bicycle() {
this.cadence = 10;
this.speed = 0;
this.gear = 1;
}
- 파라미터 수가 같은 생성자를 여러 개 만들 수 없다.
- 클래스 내부에 생성자 선언을 생략했다면, 컴파일러는 기본 생성자를 추가해준다.
- 생성자를 하나라도 직접 선언했다면, 모든 필요한 생성자를 직접 선언해야 한다.
'Languages > Java ☕️' 카테고리의 다른 글
You can not write Java code without defining a class. (0) | 2021.01.04 |
---|---|
[java-live-study] 🔥 4주차 과제: 제어문 (0) | 2021.01.04 |