오늘은 어제보다 나아지길
[Java] 클래스 정리 본문
객체 지향 프로그래밍(OOP)
현실에선 제품을 만들 때 부품들을 만들고, 그 부품들을 조립해서 만들 듯이 소프트웨어에서도 부품에 해당하는 객체를 만들고 이것들을 조립해서 완성된 프로그램으로 만드는 기법을 말한다.
객체(Object)
물리적으로 존재하거나 추상적으로 생각할 수 있는 것 중에서 자신의 속성을 가지고 있고 다른 것과 식별 가능한 것
객체는 속성과 동작으로 구성되며 속성은 필드(field), 동작은 메소드(method) 라고 부른다.
객체들은 독립적으로 존재하고, 다른 객체와 상호작용 시 메소드를 호출한다.
객체 지향 프로그래밍의 특징
-
캡슐화(Encapsulation)
객체의 필드, 메소드를 하나로 묶고, 구현 내용을 감추는 것
필드와 메소드를 캡슐화하여 보호하는 이유는 외부의 잘못된 사용으로 인해 객체가 손상되지 않도록 하기 위함이다
그래서 자바는 캡슐화된 멤버를 노출시킬지, 숨길 것 인지 결정하기 위해 접근 제한자(Access Modifier)를 사용한다.
-
상속(Inheritance)
상속이란 단어는 부모가 가지고 있는 재산을 자식에게 물려주는 것을 말한다.
객체 지향 프로그래밍에서도 상위 객체는 자기가 가지고 있는 필드, 메소드를 하위 객체에게 물려주어 하위 객체가 사용할 수 있도록 해준다.
상속은 효율적이고 개발 시간을 절약시킬 수 있으며 코드의 중복을 줄여준다.
-
다형성(Polymorphism)
같은 타입이지만 실행 결과가 다양한 객체를 이용할 수 있는 성질을 말한다.
객체와 클래스
클래스는 설계도라고 보면 된다.
클래스에는 객체를 생성하기 위한 필드와 메소드가 정의되어 있고,
클래스로부터 만들어진 객체를 해당 클래스의 인스턴스(instance)라고 한다
클래스로부터 객체를 만드는 과정을 인스턴스화라고 한다.
클래스 선언
public class 클래스 이름 {
}
new는 클래스로부터 객체를 생성시키는 연산자이다.
public class Car {
int speed; // 필드
String color;
int cc;
car() { // 생성자 생성
}
Car(String color, int cc) { // 생성자 오버로딩
this.color = color;
this.cc = cc;
}
void powerOn() { // 메소드
System.out.println("시동을 끕니다.");
}
int plus(int x, int y) { // 메소드
int result = x + y;
return result;
}
double plus(int x, int y) { // 메소드 오버로딩
int result = x + y;
return result;
}
}
public class CarExample {
public static void main(String[] args) {
Car car = new Car("흰색", 3000);
System.out.println("car 변수가 Car 객체를 참조");
System.out.println("차의 색상은 : " + car.color);
car.speed = 60;
System.out.println("차의 속도는 :" + car.speed);
car.powerOn(); // 시동을 끕니다.
}
}
new를 통해 객체를 생성시켰고 이런 객체들은 Car 클래스의 인스턴스이다.
클래스는 필드, 생성자, 메소드로 구성되어 있다.
필드는 객체의 고유 데이터, 상태 정보를 저장한다.
생성자는 new 연산자로 호출되는 블록이며, 객체 생성 시 초기화를 담당한다.
하나 이상의 생성자를 가질 수 있으며 여러 개 선언 시를 생성자 오버 로딩(Overloading)이라 한다.
메소드는 객체의 동작에 해당하는 블록이다.
하나 이상의 메소드를 가질 수 있으며 여러 개 선언 시를 메소드 오버 로딩(Overloading)이라 한다.
정적 멤버와 static
정적 멤버는 클래스에 고정된 멤버로서 객체를 생성하지 않고 사용할 수 있는 필드와 메소드를 말한다.
클래스에 속한 멤버이기에 클래스 멤버라고도 한다.
public class Calculator {
int one;
static int two;
void three() {
}
static double pi = 3.141592;
static int plus(int x, int y) {
}
static int minus(int x, int y) {
}
static {
one = 1; // 에러
two = 2;
three(); // 에러
Calculator cal = new Calculator();
cal.one = 3;
}
}
public class CalculatorExample {
public static void main(String[] args) {
double result = 10 * 10 * pi;
System.out.println("result :" + result); // result:314.1592
}
}
정적 요소는 클래스 이름으로 접근하는 것이 좋다.(권장 사항)
정적 메소드와 정적 블록의 내부에서는 인스턴스 필드나 인스턴스를 사용할 수 없고, 사용하기 위해선 객체를 생성 후 사용해야 한다.
싱글톤(Singleton)
프로그램에서 단 하나의 객체만 만들도록 보장해야 하는 경우가 있는데 , 이때 싱글톤을 사용한다.
생정자를 호출한 만큼 객체가 생성되기에 싱글톤을 만들려면 클래스 외부에서 new 연산자로 생성자 호출할 수 없도록 막아야 한다.
public class Singleton {
private staic Singleton sigleton = new Singleton();
private Singleton(){
}
static Singleton getInstance() {
return singleton
}
}
public classs SingletonExample {
public static void main (String[] args) {
Singleton obj1 = new Singleton(); // 에라
Singleton obj2 = new Singleton(); // 에러
Singleton obj1 = Singleton.getInstance();
Singleton obj2 = Singleton.getInstance();
// obj1 과 obj2는 같은 singleton 객체이다.
}
}
final필드와 상수
final 필드는 초기값이 한번 저장되면 수정할 수 없다.
final String nation = "korea";
상수는 일반적으로 불변의 값을 말한다.
final필드가 상수가 될 수 없는 것은, 불변의 값은 객체마다 저장할 필요가 없으며, 여러 가지 값으로 초기화될 수 없기 때문이다.
(final 필드는 객체마다 생성되고, 생성자를 통해 여러 가지 값을 가질 수 있다.)
상수는 static 이면서 final 이어야 한다.
static final 필드는 객체마다 저장되지 않고, 클래스에만 포함되며, 한번 초기값이 저장되면 변경할 수 없다.
상수는 대문자로 작성하며, 단어 혼용 시 _(언더바)로 연결한다.
public class Earth {
static final double EARTH_RADIUS = 6400;
static final double EARTH_SURFACE_AREA;
static {
EARTH_SURFACE_AREA = 4 * MATH.PI * EARTH_RADIUS * EARTH_RADIUS;
}
}
public classs EarthExample {
public static void main (String[] args) {
System.out.println("지구의 반지름: " + EARTH_RADIUS + " km"); // 6400.0km
System.out.println("지구의 표면적: " + EARTH_SURFACE_AREA + " km^2");
// 5.147185403641517E8 km^2
}
}
접근 제한자
접근제한 |
적용 대상 |
접근할 수 없는 클래스 |
public |
클래스, 필드, 생성자, 메소드 |
없음 |
protected |
필드, 생성자, 메소드 |
자식 클래스가 아닌 다른 패키지에 소속된 클래스 |
default |
클래스, 필드, 생성자, 메소드 |
다른 패키지에 소속된 클래스 |
private |
필드, 생성자, 메소드 |
모든 외부 클래스 |
Getter, Setter
객체 지향 프로그래밍에서는 무결성을 지기키 위해 메소드를 통해서 데이터를 변경하는 방법을 선호한다.
public class Car {
// 필드
private int speed;
provate boolean stop;
// 생성자
// 메소드
public int getSpeed() {
return speed;
}
public void setSpeed(int speed) {
if(speed < 0) {
this.speed = 0;
return;
} else {
this.speed = speed;
}
}
public boolean isStop(){
return stop;
}
public void setStop(boolean stop) {
this.stop = stop;
this.speed = 0;
}
}
public class CalculatorExample {
public static void main(String[] args) {
Car myCar = new Car();
// 잘못된 속도 변경
myCar.setSpeed(-50);
System.out.println("현재 속도:" + myCar.speed());
// 올바른 속도 변경
myCar.setSpeed(60);
// 멈춤
if(!myCar.isStop()) {
myCar.setStop(true);
}
System.out.println("현재 속도:" + myCar.speed());
}
}
객체의 데이터를 읽을 때는 Getter를 사용
객체의 데이터를 쓰거나 변경 시 에는 Setter를 사용한다.
어노테이션(Annotion)
어노테이션은 메타데이터라고 볼 수 있다.
( 메타데이터 = 컴파일 과정과 실행 과정에서 코드를 어떻게 컴파일하고 처리할 것인지를 알려주는 정보 )
-
컴파일러에게 코드 문법 에러를 체크하도록 정보를 제공
-
소프트웨어 개발 툴이 빌드나 배치 시 코드를 자동으로 생성할 수 있도록 정보를 제공
-
실행 시 특정 기능을 실행하도록 정보를 제공
@AnnotationName
// 자바에서 기본 제공되는 어노테이션
@Deprecated
@Override
@SuppressWarnings
스프링에선 많이 쓰이는 거 같기에 좀 더 공부해야겠다.
일단 컴파일러에게 어떻게 쓰인다는 걸 명시해준다 라고 생각을 하자.
출처 : 이것이 자바다
'[Java]' 카테고리의 다른 글
[Java] 상속 (0) | 2021.01.04 |
---|---|
[Java] 컬렉션 프레임워크 (0) | 2020.12.15 |
[Java] 자바 다시 시작하기 (0) | 2020.11.12 |