작성 맥락
이 글은 직접 학습하거나 구현하며 남긴 개인 기술 기록입니다. 참고 자료가 있는 경우 본문에 출처를 남기고, 틀린 부분을 발견하면 수정합니다.
객체지향 프로그래밍 (OOP)
출제빈도: 상
빈출태그: 클래스, 인스턴스, 상속, 추상 클래스, 인터페이스
클래스 설계
기본 특징
- main 메소드를 포함하는 클래스가 가장 먼저 실행됨
- 클래스의 구성요소에는 멤버 변수, 멤버 메소드가 있음
- 외부 접근이 불가능하도록 제한(캡슐화) 해야함
기본 출력 메소드
- 출력:
System.out.print() - 출력+줄바꿈:
System.out.println() - 서식에 의한 출력:
System.out.printf()
접근 제한자
클래스 내 멤버들의 접근 수준을 결정하는 토큰으로, 프로그램, 패키지, 하위 클래스, 자신의 클래스 순으로 접근수준을 결정함
| 제한자 | 설명 |
|---|---|
| public | 모든 객체에서 접근 가능 |
| default | 같은 패키지 내에서 접근 가능 |
| protected | 자신과 하위 클래스에서만 접근 가능 |
| private | 자신의 클래스에서만 접근 가능 |
인스턴스
인스턴스 생성 및 접근
// 인스턴스 생성
<클래스명> <변수명> = new <클래스명>();
// 인스턴스 멤버 접근
<객체변수>.<멤버이름>
변수 종류 예시
public class Variable {
int c; // 인스턴스변수(멤버변수)
static String d; // 클래스 변수(멤버변수)
void func(int c){ // 매개변수(지역변수)
this.c = c; // 멤버변수 c에 지역변수 c값 할당
}
public static void main(String args[]) {
int a = 30; // 정수형변수(지역변수)
Variable b = new Variable(); // 참조형변수(지역변수)
b.func(a);
}
}
클래스 변수
- 특별한 경우가 아니라면 접근을 제한해둠
- 공유하는 데이터가 필요할 때 사용
- 선언 형식:
[<접근제한자>] static <자료형> <변수명>; - 클래스가 코드에 언급되는 순간 생성되며, 프로그램이 끝날 때까지 유지
- 클래스 내부에서 this로 불러옴
생성자 메소드
- 클래스명과 같은 이름으로 존재
- 자동으로 실행되며 별도 실행 불가
- 리턴문 사용 불가능
- 초기화 작업에 사용
- 오버로딩: 동일한 메소드명을 가진 메소드들을 개수와 유형을 기준으로 구분
객체지향 기술 적용
상속
extends키워드를 사용해서 상위클래스 지정- 형식:
class <하위 클래스명> extends <상위 클래스명> { ... } - 재사용, 재정의, 추가 멤버를 확장해서 구현
- 메소드 오버라이딩: 상위 클래스의 메소드를 재정의하여 사용하는 기술
업캐스팅 예시
class SuperObject {
public void paint() {
draw();
}
public void draw() { // 4. 오버라이딩된 하위 클래스의 paint 호출
draw(); // 3. 자기자신 다시 호출함
System.out.println("Super Object"); // 6. 마지막에 출력
}
}
class SubObject extends SuperObject {
public void paint() {
super.draw(); // 2. 실제 호출되는 메소드 -> 상위 클래스의 draw 메소드 호출
}
public void draw() {
System.out.println("Sub Object"); // 5. 문자열 출력
}
}
public class Main {
public static void main(String[] args) {
SuperObject b = new SubObject(); // 1. 상위 참조변수로 업캐스팅
b.paint();
}
}
// 결과
// Sub Object
// Super Object
추상 클래스
abstract class Shape { // 추상 클래스 정의
abstract void draw(); // 추상 메소드 정의
}
class Circle extends Shape {
void draw() { // 추상 메소드 오버라이딩
System.out.println("원을 그립니다");
}
}
class Rectangle extends Shape {
void draw() { // 추상 메소드 오버라이딩
System.out.println("사각형을 그립니다");
}
}
public class Helloworld {
public static void main(String[] args) {
Circle c1 = new Circle();
Rectangle r1 = new Rectangle();
c1.draw(); // 메소드명 통일 가능
r1.draw();
}
}
// 결과
// 원을 그립니다
// 사각형을 그립니다
인터페이스
다중 상속의 문제점을 해결하기 위한 방법으로, 자바는 둘 이상의 상위 클래스를 상속받는 다중상속을 금지함. 다중상속을 방지하면서 다중상속의 이점을 가지는 기능이 인터페이스임
특징
- 모든 메소드가 추상 메소드로만 구성
interface와implements키워드를 사용해서 구현, 상속- 상속은 기존 클래스의 멤버를 ‘확장’하는 개념이지만 인터페이스는 확장된 클래스의 기능을 ‘제한’하거나 ‘변경’하는 ‘다형성’의 개념
interface Coffee { // 상위
abstract void drink_coffee();
}
interface Cookie { // 상위
abstract void eat_cookie();
}
class Cafe implements Coffee, Cookie { // 하위
public void drink_coffee() {
System.out.println("커피를 마신다.");
}
public void eat_cookie() {
System.out.println("쿠키를 먹는다.");
}
public void talk() {
System.out.println("대화를 한다.");
}
}
public class HelloWorld {
public static void main(String[] args) {
Cafe k = new Cafe();
k.drink_coffee();
k.eat_cookie();
k.talk();
Coffee c = k; // 업캐스팅
c.drink_coffee(); // 커피만 마실 수 있음
Cookie x = k; // 업캐스팅
x.eat_cookie(); // 쿠키만 먹을 수 있음
}
}
예외처리
- 실행 도중에 문제가 발생하면 프로그램이 멈추거나 종료되는 것을 방지하기 위한 코드
- 오타는 문법 오류(Syntax Error), 의도치 않은 작동 및 입력을 예외라고 함
- 예외를 식별할 영역을 별도로 지정해야 함
public class HelloWorld {
public static void main(String[] args) {
try { // 예외 감지 영역
<코드 영역>
}
catch() { // 예외 감지 시 실행 영역
<코드 영역>
}
finally { // 무조건 실행되는 영역
<코드 영역>
}
}
}
스레드(Thread)
하나의 프로세스(프로그램)에서 둘 이상의 일을 동시에 수행하는 것
Thread 클래스 상속을 통한 구현
class Box extends Thread { // Thread 클래스 상속
public void run() { // run 메소드 재정의
System.out.println("message"); // 스레드 실행 시 수행되는 영역
}
}
public class Main {
public static void main(String[] args) {
Box a = new Box(); // 일반적인 객체 생성 방식
a.start(); // 스레드 수행 메소드
}
}
// 결과
// message
Runnable 인터페이스를 통한 구현
class Box implements Runnable { // implements 인터페이스 상속
public void run() { // run 메소드 재정의
System.out.println("message"); // 스레드 실행 시 수행되는영역
}
}
public class Main {
public static void main(String[] args) {
Thread t = new Thread(new Box()); // Thread 생성자에서 다른 생성자 호출
t.start(); // 스레드 수행 메소드
}
}
// 결과
// message
멀티스레딩
- 다수의 스레드를 동시에 실행
- 자원 소비를 줄일 수 있음
- 자원을 공유하므로 충돌이 일어날 가능성과 복잡한 코딩으로 버그 가능성이 커짐
스레드 상태
- Runnable: start 메소드로 실행이 준비된 상태
- Running: run 메소드로 스레드가 실행되는 상태
- Blocked: 스레드가 잠시 작업을 멈춘 단계
- Dead(Done): 스레드 수행이 완료된 상태
댓글이 보이지 않으면 GitHub에 로그인한 뒤 새로고침해 주세요. 공개 댓글은 로그인 상태에서 더 안정적으로 표시됩니다.