[TIL] 객체 지향 프로그래밍 <클래스와 객체> (1/2)
Do it! 코틀린 프로그래밍 [둘째마당, 객체 지향 프로그래밍] 학습
객체 지향 프로그래밍 (OOP: Object-Oriented Programming) 은 프로그램의 구조를 객체 간 상호작용으로서 표현하는 프로그래밍 방식으로, 절차적 프로그래밍의 한계를 극복하고자 나온 방법론
📍 절차적 프로그래밍? 코딩한 순서대로 프로그램이 수행될 수 있도록 작성하는 방법론. 단순하고 오류를 예측하기 쉽지만 구조적이지 못해 복잡한 프로그램을 설계하기 어려움
✏️1. 클래스와 객체의 정의✏️
1-1. 객체지향 프로그래밍과 용어
📌객체 지향 프로그래밍의 용어 정리
코틀린 | 다른 언어 |
---|---|
클래스(Class) | 분류, 범주 |
프로퍼티(Property) | 속성(Attribute), 변수(Variable), 필드(Field), 데이터(Data) |
메서드(Method) | 함수(Function), 동작(Operation), 행동(Behavior) |
객체(Object) | 인스턴스(Instance) |
📌 클래스의 멤버가 될 수 있는 것
- 생성자와 초기화 블록 : 객체가 생성될 때 자동 실행되는 메서드 또는 코드 블록
- 프로퍼티 : 변수의 이름과 변수의 접근 함수가 포함된 형태
- 메서드 : 일반적인 함수의 형태
- 중첩(Nested)클래스와 이너(Inner)클래스:클래스 내부에 구성되는 클래스
- 객체 선언:클래스 없이 접근할 수 있는 객체
1-2. 클래스
📌 클래스 다이어그램
- 통합 모델링 언어(UML: Unified Modeling Language) : 객체 지향 프로그램 설계를 위한 다이어그램 표기법. 개발 단계에서 팀 의사소통을 우너활히 하는데 도움
- 다이어그램 기법의 종류
- 클래스(Class) 다이어그램
- 클래스의 정의와 관계를 나타내는 다이어그램
- 클래스 이름, 프로퍼티, 메서드를 손쉽게 파악 할 수 있음
- 시퀀스(Sequence) 다이어그램
- 시간의 개념을 통해 클래스에서 생성된 객체의 실행 흐름을 나타냄
- 객체 간의 실행 순서를 보기에 적합
- 유스 케이스(Use Case) 다이어그램
- 사용자 관점에서 사용 방법에 대해 설명
- 사용자가 어떤 식으로 사용할 것인지 보여줌
- 상태 머신(State-Machine) 다이어그램
- 시스템 관점에서 상태가 어떻게 변화하는지 나타냄
- 객체의 상태변화를 볼 수 있음
- 클래스(Class) 다이어그램
📌 추상화 (Abstraction)
- 목표로 하는 대상에 대해 필요한 만큼 속성과 동작을 정의하는 과정을 추성화라고 함
📌 클래스 선언하기
⬇️ 클래스 구조
class bird{} // 내용이 비어 있는 클래스 선언
class bird // 중괄호 생략 가능
class bird{
// 프로퍼티
// 메서드
}
⬇️ 클래스 선언과 객체 생성
class Bird {
var name: String = "bird"
fun fly() = println("bird $name")
}
fun main() {
val coco = Bird() // 클래스 생성자를 통한 객체의 생성
println("$coco.name") // 객체의 멤버 프로퍼티 읽기
coco.fly() // 객체의 멤버 메서드 사용
}
📌 객체와 인스턴스 정리하기
- 클래스로부터 객체(Object)를 생성해야만 클래스라는 개념의 실체인 객체가 물리적인 메모리 영역에서 실행됨. 이를 객체 지향 언어에서는 구체화 또는 인스턴스화(Instantiate)되었다고 함.
- 메모리에 올라간 객체를 인스턴스(Instance)라고 함
✏️2. 생성자 (Constructor)✏️
클래스를 통해 객체가 만들어질 때 기본적으로 호출되는 함수를 생성자 라고함
⬇️ 생성자 선언
class 클래스 이름 constructor(필요한 매개변수..) { // 주 생성자 위치
...
constructor(필요한 매개변수..) { // 부 생성자 위치
// 프로퍼티(변수) 초기화
}
}
2-1. 부 생성자
- 클래스의 본문에 함수처럼 선언
class Bird {
var name: String // 프로퍼티(변수)
var wing: Int
var beak: String
// 부 생성자 - 매개변수를 통해 초기화할 프로퍼티에 지정
constructor(name: String, wing: Int, beak: String) {
this.name = name // this.name 은 현재 클래스의 프로퍼티를 나타냄
this.wing = wing
this.beak = beak
}
}
⬇️ this 키워드를 사용하지 않는 방법
class Bird {
var name: String // 프로퍼티(변수)
var wing: Int
var beak: String
constructor(_name: String, _wing: Int, _beak: String) {
name = _name // name : 클래스의 프로퍼티, _name : 생성자의 매개변수
wing = _wing
beak = _beak
}
}
-> 프로퍼티와 매개변수를 구분하기 위해 다른 이름을 사용
-> 매개변수 이름 앞에 언더스코어(_) 사용
⬇️ 매개변수가 다르게 부 생성자를 여러개 선언
class Bird {
constructor(_name: String, _wing: Int, _beak: String) {
name = _name // name : 클래스의 프로퍼티, _name : 생성자의 매개변수
wing = _wing
beak = _beak
}
// 매개변수가 다른 또 다른 부 생성자
constructor(_name: String, _wing: Int){
name = _name
wing = _wing
beak = "short"
}
}
fun main() {
val coco = Bird("coco", 2, "short")
val noBeak = Bird("coco", 2)
}
2-2. 주 생성자
- 클래스 이름과 함께 생성자 정의를 이용할 수 있는 기법
- 클래스 이름과 블록 시작 부분 사이에 선언
// 주 생성자 선언
class Bird constructor(_name: String, _wing: Int, _beak: String) {
var name: String // 프로퍼티(변수)
var wing: Int
var beak: String
}
// constructor 키워드 생략 가능
class Bird(_name: String, _wing: Int, _beak: String) {
var name: String // 프로퍼티(변수)
var wing: Int
var beak: String
}
// 내부의 프로퍼티를 생략하고 생성자의 매개변수에 프로퍼티 선언
class Bird(val name: String, val wing: Int, val beak: String) { }
📌 초기화 블록을 가진 주 생성자
- 초기화에 꼭 사용해야 할 코드가 있다면 init{...} 초기화 블록을 클래스 선언부에 넣어주어야 함
// 주 생성자 선언
class Bird(var name: String, var wing: Int, var beak: String) {
// 초기화 블록
init{
println("---초기화 블록 시작---") // (1)
}
}
fun main() {
val coco = Bird("coco", 2, "short")
// 객체 생성과 함꼐 초기화 블록이 수행
// (1) 문구가 출력
}
📌 프로퍼티의 기본값 지정
// 프로퍼티의 기본값 지정 (name, wing의 기본값을 지정)
class Bird(var name: String = "coco", var wing: Int = 2, var beak: String) { }
fun main() {
// 기본값이 있는 것은 생략, 없는것만 전달 가능
val coco = Bird(beak = "short")
}
✏️3. 상속(Inheritance)과 다형성(Polymorphism)✏️
3-1. 상속(Inheritance)
자식 클래스를 만들 때 상위 클래스(부모 클래스)의 속성과 기능을 물려받아 계승하는 것
⬇️하위 클래스 선언하기
open class BaseClass(someArgs: Int) // 상속 가능한 클래스
class SomeClass(someArgs: Int) : BaseClass(someArgs) // 클래스 상속의 선언
class SomeClass : BaseClass { ..constructor().. }
- 코틀린은 기본적으로 상속이 불가능하도록 선언됨. 클래스를 선언할 때 open키워드를 사용해야 파생 클래스에서 상속 가능
- 📍 코틀린은 기본적으로 상속이 불가능하도록 선언됨. 하지만 자바는 기본적으로 선언하는 클래스가 상속 가능한 클래스이며, 자바에서 상속할 수 없는 클래스로 선언하려면 final 키워드를 사용해야함
- 모든 클래스는 묵시적으로 Any를 최상위 클래스로 가짐
3-2. 다형성(Polymorphism)
이름이 동일하지만 매개변수가 서로 다른 형태를 취하거나 실행 결과를 다르게 가질 수 있는 것
📌 오버로딩(Overloading)
- 동일한 클래스 안에서 같은 이름의 메서드가 매개변수만 달리해서 여러 번 정의될 수 있는 개념
- 반환값은 동일하거나 달라질 수 있으나, 구현되는 동작은 대부분 동일
fun add(x: Int, y: Int): Int {
return x + y
}
// 자료형이 다름
fun add(x: Double, y: Double): Double {
return x + y
}
// 매개변수의 개수가 다름
fun add(x: Int, y: Int, z: Int): Int {
return x + y + z
}
📌 오버라이딩(Overriding)
- 하위 클래스에서 새로 만들어지는 메서드가 이름이나 매개변수, 반환값이 이전 메서드와 똑같지만 새로 작성되는 것
- 파생 클래스가 오버라이딩하기 위해 기반 클래스에서는 open 키워드, 파생 클래스에서는 override키워드를 각각 사용
// 부모 클래스
open class Bird{ // 상속 가능
fun fly() { ... } // 최종 메서드로 오버라이딩 불가
open fun sing() { ... } // 오버라이딩 가능
}
// 자식 클래스
class Lark() : Bird() {
fun fly() { /* 재정의 */ } // !오류! fly()는 open키워드 X
override fun sing() { /* 재정의 */ } // 오버라이딩 가능
}
Author And Source
이 문제에 관하여([TIL] 객체 지향 프로그래밍 <클래스와 객체> (1/2)), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@zzangdd/TIL-객체-지향-프로그래밍-클래스와-객체저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)