
인식의 체계, 사물에 대한 인식이나 생각의 틀, 체계
프로그램을 만드는 데에도 패러다임이 있다.
- 소프트웨어 개발의 패러다임
- 자바가 객체지향 패러다임을 따라가는 대표적인 프로그래밍 언어
- 프로그램을 객체(Object)라는 기본 단위로 구성하고 문제를 풀어나간다.
- 여기서 객체란, 프로그램에서 필요한 데이터를 추상화한 것 (상태와 행위를 추상화)
객체 지향 프로그래밍에는 네 가지 특징이 있다.
1. 캡슐화 (Encapsulation)
2. 상속 (Inheritance)
3. 다형성 (Polymorphism)
4. 추상화 (Abstraction)
- 필요한 정보만 남기고 세부사항을 감추는 것
- 복잡한 시스템의 중요한 내용은 보여주고, 불필요한 세부 사항은 숨기는 원칙
- 객체가 공통적으로 수행할 수 있는 기능을 정의하고, 이 기능에 대한 세부 사항은 숨긴다. Java에서는 추상 클래스 (abstract class)와 인터페이스(interface)를 통해 추상화를 구현한다.
EX) 전화하는 것, 문자 보내는 것 어떻게 되는 건지 알고 보내는가? NO!
사용자 인터페이스만 보게 된다.
- 객체의 데이터와 그 데이터를 처리하는 메소드를 하나로 묶어서 외부로부터 객체의 내부 구현을 숨기는 원칙
- 객체의 상태(데이터)는 외부에서 직접 접근하거나 변경할 수 없으며, 객체가 제공하는 공용 메서드를 통해서만 데이터를 조작할 수 있다.
- 기존의 클래스(부모 클래스)를 바탕으로 새로운 클래스(자식 클래스)를 생성
- 부모 클래스의 속성과 메서드를 자식 클래스가 재사용할 수 있도록 한다.
- 코드의 재사용성을 높이고, 계층적인 관계를 통해 객체 관의 관계를 명확히 한다.
- 동일한 메서드 이름이지만, 다양한 형태로 구현될 수 있는 기능
- 메서드 오버로딩과 메서드 오버라이딩으로 구현
같은 이름의 메서드를 매개변수의 타입이나 개수(메서드 시그니처)에 따라 다르게 정의
상속받은 메서드를 자식 클래스에서 재정의하여 구체적인 동작을 정의
- 프로그램을 구성하는 기본 단위
- 데이터와 이을 처리하는 메서드를 하나로 묶어놓은 하나의 실체(개체)
- 상태(State)와 행동(Behavior)로 구성
객체가 가지는 속성(Property)이나 데이터, 객체의 내부 상태를 정의
객체가 수행할 수 있는 동작, 객체의 메서드를 통해 구현
붕어빵 : 개념 -> 객체
붕어빵 안에 팥 or 슈크림 -> 상태
붕어빵을 만들기 위해 달궈놓은 틀 -> 클래스
붕어빵 틀로 나온 실제 붕어빵 -> 인스턴스
- 객체의 상태를 나타내는 필드(변수)와 객체의 동작을 정의하는 메서드로 구성
- 추상화를 통해 데이터와 메서드를 하나의 단위로 묶어준다.
- 객체의 상태를 표현
- 클래스의 속성 (Property)를 나타내는 변수
- 클래스의 인스턴스가 가지는 데이터를 저장하며, 인스턴스 변수와 정적 변수로 나뉜다.
- 인스턴스 변수는 각 객체가 독립적으로 가지는 데이터이며, 정적(static)변수는 클래스 자체에 속하며 모든 객체가 공유
- 객체의 행동을 표현
- 클래스의 동작을 정의하는 함수
- 객체의 상태를 변경하거나 특정 작업을 수행
클래스를 바탕으로 생성된 구체적인 객체
- 객체를 초기화하는 특별한 종류의 메서드
- 클래스의 인스턴스를 생성할 때 호출되며, 객체의 초기 상태를 설정하는 데에 사용
- 반환 타입이 존재하지 않는다.
- 생성자는 오버로딩을 통해 여러 생성자를 정의할 수 있으며, 각각의 생성자별로 인스턴스가 보유할 수 있는 값들이 달라진다.
매개변수가 없는 생성자를 기본 생성자라고 한다. 기본생성자는 컴파일러(javac)에 의해 자동으로 정의한다. 단, 하나의 생성자라도 있으면 기본 생성자를 자동으로 제공하지 않는다.
매개변수를 받아 객체의 필드를 초기화하는 생성자이다. 사용자 정의 생성자를 만들어놓으면, 이가 기본 생성자의 역할을 하고, 기본 생성자를 따로 만들고 싶으면 오버로딩을 통해 따로 정의해야 한다.
인스턴스(instance)를 생성하기 위해서 new 키워드를 사용하여 클래스의 생성자를 호출한다.
- 자바에서 객체 자신을 참조하는 키워드
- 클래스의 인스턴스 메서드나 생성자 내에서 객체 자신의 참조를 제공한다.
this는 같은 클래스의 다른 생성자를 호출할 때도 사용한다. 이를 통해 코드 중복을 줄이고 생성자의 초기화를 통합할 수 있다.
public class A {
private int b;
private int c;
public A() {
this(0,0); // 다른 생성자를 호출
}
public A(int b, int c) {
this.b = width;
this.c = height;
}
}
메서드가 this를 반환하여 연속적으로 메서드를 호출할 수 있게 하는 패턴
- 변수와 메소드가 유효하고 접근 가능한 범위를 정의하는 개념
- 변수가 선언된 위치에 따라 달라지는 유효 범위를 의미
- 클래스 수준에서 멤버를 정의할 때 사용
- 인스턴스와는 독립적으로 메모리에 할당되고 모든 인스턴스가 공유하는 특성이 있다.
- 클래스 로딩 시 메모리에 할당된다.
public class AClass {
private int instanceVar;
private static int staticVar;
public void instanceMethod() {
// 인스턴스 변수와 정적 변수 모두 접근 가능
instanceVar = 10;
staticVar = 20;
}
public static void staticMethod() {
// 정적 변수만 접근 가능
staticVar = 30;
// instanceVar는 접근 불가능
}
}
public static void main(String[] args) {
Myclass instance1 = new MyClass();
Myclass instance2 = new MyClass();
Myclass instance3 = new MyClass();
instance1.instanceMethod(50); // staticField = 40, fieldA = 50
instance2.instanceMethod(30); // staticField = 40, fieldA = 30
Myclass.staticMethod(40); // staticField = 40, fieldA = 50
// 클래스에서 공유하는 변수, Myclass에 있는 static 변수의 값이 바뀐 것
}
- 기존 클래스(부모 클래스, 슈퍼 클래스)의 속성과 메소드를 새로운 클래스(자식 클래스, 서브 클래스)에게 물려줘서 사용할 수 있게 하는 것
- 상속을 통해 자식 클래스는 부모 클래스에서 정의된 모든 속성과 메서드를 그대로 사용할 수 있으며, 필요한 경우 이를 확장하거나 재정의(오버라이딩) 할 수 있다.
한 클래스가 단 하나의 상위 클래스로부터 상속을 받는 방식
한 클래스가 두 개 이상의 상위 클래스로부터 상속을 받는 방식
여러 하위 클래스가 하나의 상위 클래스를 상속받는 방식이다. 하나의 부모클래스가 여러 자식 클래스를 가질 수 있다.
상속이 여러 단계로 이어지는 방식이다. 한 클래스가 다른 클래스의 하위 클래스가 되고 다시 상위클래스가 되는 형태이다.
여러 종류의 상속기법을 결합하여 사용하는 방식이다. 이전의 상속 패턴들을 조합하여 복잡한 상속구조를 형성한다.
class 클래스 이름 extends 부모클래스 이름 {
}
- 부모 클래스에서 상속받은 메서드를 자식 클래스에서 재정의하는 것
- 오버라이딩을 통해 자식 클래스는 부모 클래스의 기본 동작을 자신만의 방식으로 수정할 수 있고, 이를 통해 다형성을 구현한다.
class Dog {
public void bark(int times) {
for(int i=0;i<times;i++){
System.out.println("멍!");
}
}
}
class Husky extends Dog {
@Override
public void bark(int times) {
for(int i=0;i<times;i++){
System.out.println("멍!");
System.out.println("멍!");
}
}
}
Override된 메서드는 부모 클래스보다 더 제한적일 수 없다.
Override된 메서드는 원본 메서드와 시그니처가 일치해야 한다.
메서드 이름, 메서드 매개변수 리스트, 반환 타입이 동일하야 한다. 그렇지 않을 경우, 오버로딩이 된다.
Override된 메서드는 원본메서드와 예외처리가 일치해야 한다.
super 키워드는 하위 클래스에서 상위 클래스를 가리킬 때 사용한다. 상속 관계에서 자식 클래스가 부모 클래스의 기능을 참조하거나 호출할 때 사용한다.
class Husky extends Dog {
public Husky(String name) {
super(name);
} # 자식 클래스의 생성자에서 super()를 호출하여 부모클래스의 생성자를 호출할 수 있으며, 이를 통해 부모 클래스의 필드를 초기화하거나 기본 설정을 수행할 수 있다. 부모 클래스의 생성자는 super()를 사용하여 명식적으로 호출하지 않더라도 자식 클래스의 생성자가 호출될 때 자동으로 호출된다.
@Override
public void eat(String food) {
super.eat(food); # 부모 클래스 참조
System.out.println("멍!");
}
}
- 클래스의 기본 형태를 정의하고, 이를 상속받아 구체적인 구현을 제공할 수 있도록 하는 클래스
- 직접적으로 인스턴스화될 수 없으며, 다른 클래스가 이를 상속받아 구현을 완성해야 한다.
- 상속을 통해 공통적인 기능을 제공하면서, 자식 클래스에서 구체적인 동작을 정의할 수 있는 기반을 마련한다.
Abstract Class는 추상 메서드(Abstract Method)를 하나 이상 보유할 수 있다. 추상 메서드는 메서드의 선언만 포함하며, 메서드 본체가 없다.
Abstract Class는 구현된 메서드도 보유할 수 있다. 이러한 일반 메서드는 자식 클래스에서 재정의(오버라이딩)할 필요 없이 그대로 사용할 수 있다.
Abstract Class는 직접 인스턴스로 생성하는 것이 불가능하다. 즉, new 키워드를 사용하여 추상 클래스의 객체를 생성할 수 없다. 추상 클래서는 오직 자식 클래스에서 구현된 다음에 생성하여 사용할 수 있다.
public abstract class Animal {
public abstract void yelling();
public void eat(int amount) {
System.out.println(amount + "만큼 먹었습니다. 배가 부릅니다.");
}
public void sleep(int hours){
System.out.println(hours + "만큼 낮잠을 잤습니다. 개운합니다.");
}
}
오늘은 수업을 들으며 기록도 잘하고, 수업 내용도 놓치지 않고 잘 따라왔다. 그리고, 자율학습 시간 때 강의 자료를 쭉 다시 복습하면서 내가 놓친 부분, TIL에 더 기록할 부분, 이해가 되지 않는 부분을 뽑아낼 수 있었다. 강의 자료를 보고 이해가 되지 않는 부분을 바로 바로 강사님께 질문할 수 있어 더 이해하기 좋았던 것 같다 ! 수업을 듣고, 진짜 이해하고, 이것을 기록하는 것까지 어떻게 해야 할지 고민이 많았는데 하루하루 좀 나아지고 틀이 잡혀가는 것 같다.
Q. OOP 특징 중 추상화는 불필요한 구체적인 부분은 숨기고, 중요한 부분을 강조하여 보여주는 거라고 이해했습니다. 이를 abstract class와 interface로 구현할 때, (아직 interface는 안 배웠지만) 추상 메소드로 메소드 본체를 구현하지 않는 것이 불필요한 부분을 숨기는 거라고 할 수 있는 건가요? 아니면 자식 클래스에서 꼭 구현하게 함으로써 중요한 부분을 드러내서 강조한다고 이해해야 하나요
A. 추상 메서드로서 메서드를 구현하지 않고 두는 것은 불필요한 것을 숨긴다 라는 표현 보다는 해당 객체가 “무엇을 할 수 있는지”에 초점을 맞추어 정의해둔 다음에 이 클래스를 구현하는(상속받는)클래스는 반드시 해당 기능을 구현해야하는 것을 지정하기 위함이라고 보는것이 보다 적절할 수 있을 것 같습니다.
즉, 추상 메서드는 반드시 구형해야 하는 중요한 기능만을 보여주는 것이다로 이해할 수 있을 것 같습니다.
일주일이 끝났다. 고작.. 일주일이 끝났다. 하하하하 시작이 반이겠지? 꾸준히 열심히 하고 싶다. 지금은 힘들진 않는데, 지치지 않고 잘 끝낼 수 있길 바란다. 할수록 루틴이나 공부 계획이 잡히는 것 같아서 좋다. 그리고, 슬슬 내가 전공 수업에서 배우고 까먹은 내용들이 나오기 시작하는데 열심히 잘 들어두고 기록해서 이젠 까먹지 않도록 해야 할 것 같다. 1주차를 무사히 성공적으로 잘 해낸 나에게 박수 ~! 하루 하루 퀘스트 깨는 것처럼 하면 잘 되겠지 뭐~ !!
그리고, 6시 이후 시간에 어떻게 하면 생산적으로 시간을 보낼 수 있을지 고민해봐야겠다 ! 파이팅 ! :)