객체(Object) 를 지향(Oriented) 하는 프로그래밍은 코딩을 작성할 때 사용할 수 있는 하나의 패러다임, 더 일반적으로는 하나의 글쓰기 장르라고 볼 수 있다.
잠시 객체 지향 프로그래밍을 접어두고, 코딩이 어떻게 동작하는지부터 생각해보자. 어떤 프로그래밍 언어를 쓰더라도 코드는 컴파일러를 거쳐서 수행된다. 사람이 작성한 코드를 기계어로 번역하는 작업이 필요한 것인데, 이때 코드는 위에서부터 아래로 한 줄씩 코드를 읽고, 번역하고, 내용을 수행한다.
화가가 그림을 그려서 파는 작업을 위의 문단의 내용만 갖고서 코드로 표현하면 다음과 같다.
var 화가 지갑 = 0
var 화가가 갖고 있는 그림 = 1
var 손님 지갑 = 20000
var 손님이 갖고 있는 그림 = 0
var 손님은 그림을 갖고 싶다 = true
if (10000 >= 손님 지갑 && 손님은 그림을 갖고 싶다) {
손님 지갑 -= 10000
화가 지갑 += 10000
손님이 갖고 있는 그림 += 1
화가가 갖고 있는 그림 -= 1
손님은 그림을 갖고 싶다 = false
}
Kotlin 컴파일러는 위에서부터 읽으며 모든 내용을 절차대로 수행할 것이다. 이때, 만약 손님이 1명이 아니라 여러 명이라면 코드는 계속해서 저 코드를 부분적으로 반복하며, 많은 줄을 작성해야할 것이다.
그렇다. 굉장히 귀찮은 작업이며, 이것을 해결하기 위해 나온 것이
절차적 프로그래밍과 객체 지향 프로그래밍이다.
잠깐, 절차적 프로그래밍 ?
절차적 프로그래밍은 함수의 재호출을 이용해 코드를 재활용하는 방법을 의미한다.즉, 컴파일러가 위에서부터 아래로 순서대로 읽는 것과는 별개로 (애초에 모든 코드는 절차적이다.) , 함수같은 Procedural 를 재활용하자는 의미에서 Procedural Programming 인 것이다.
이 글에서 절차적 프로그래밍은 함수를 통해 코드를 재활용한다는 의미로만 사용하고, 그 이상의 내용은 다루지 않는다.
객체(Object) 를 지향(Oriented) 하는 프로그래밍은 코딩을 작성할 때 사용할 수 있는 하나의 패러다임, 더 일반적으로는 하나의 글쓰기 장르라고 볼 수 있다.
객체를 지향한다고 하니, 객체가 무엇인지 알아보자.
여기서 말하는 객체
란 하나로써 존재할 수 있는 무언가를 의미한다.
사람, 고양이, 우주, 자동차 등이 될 수 있다.
언급된 객체들의 특징은 자신이 주체
가 될 수 있다는 점이다.
고양이는 고양이로서 존재할 수 있고, 우주는 우주로서 존재할 수 있다.
고양이를 이루는 것 중에는 털이 있지만, 털이 조금 빠진다고 고양이가 고양이가 되진 않는다.
털이 빠진 고양이가 될 순 있지만.
굉장히 관념적이지만, 여기서 말하는 객체
가
하나로서 존재할 수 있는 어떤 추상적인 무언가
로 이해했다면 완벽하다.
객체 지향 프로그래밍은 프로그래밍을 짤 때 객체
단위로 코드를 작성하기를 지향
한다는 것이다.
고양이라는 하나의 객체에는 성격, 근육, 털, 행동 등등 여러가지 것들이 포함될 수 있다. 어떠한 것들은 있을 수도 있고, 없을 수도 있지만 고양이
라는 객체는 존재하며,
이 같은 생각을 바탕으로 코드를 작성하겠다는 패러다임이 바로 객체 지향 프로그래밍(Object Oriented Programming) 이다.
코틀린으로 실제 객체, 고양이를 작성을 해보자.
위에서 언급한 하나로서 존재할 수 있는 객체
, 즉 고양이는 Class
로 정의되며, 그 내부의 털, 성격, 근육 등은 변수
혹은 함수
로 정의할 수 있다.
fun main(){
val cat = Cat()
println("눈동자는 ${cat.눈동자}, 털은 ${cat.털}, 성격은 ${cat.성격}")
cat.털 = "깎아버리기!"
cat.눈동자 = "까망색"
println("${cat.털}, ${cat.눈동자}")
cat.밥과 관련된 행동(true)
}
class Cat(){
val 눈동자: String = "Blue"
var 털: String = "너무 많아"
val 성격: String = "커여워"
fun 밥과 관련된 행동(밥: Boolean){
if(!밥){
println("냥냥펀치!!")
} else {
println("와구와구")
}
}
}
결과
눈동자는 Blue, 털은 너무 많아, 성격은 커여워
눈동자는 Blue, 털은 깎아버리기!, 성격은 커여워
와구와구
.
으로 할 수 있다. .
로 할 수 있다.한편, 클래스도 매개변수를 받을 수 있다. 같은 내용을 매개변수를 받는 형태로 바꾼다면 다음과 같다.
fun main(){
val cat = Cat()
println("눈동자는 ${cat.눈동자}, 털은 ${cat.털}, 성격은 ${cat.성격}")
cat.털 = "깎아버리기!"
cat.눈동자 = "까망색"
println("${cat.털}, ${cat.눈동자}")
cat.밥과 관련된 행동(false)
}
class Cat( val 눈동자: String = "Blue",
var 털: String,
val 성격: String = "커여워")
{
fun 밥과 관련된 행동(밥: Boolean){
if(!밥){
println("냥냥펀치!!")
} else {
println("와구와구")
}
}
}
결과
Error --> 매개변수 값을 선언해주세요.
눈동자는 Blue, 털은 깎아버리기!, 성격은 커여워
냥냥펀치!!
클래스의 매개변수는 val, var 타입이 올 수 있으며 val 은 변경 불가, var 은 변경 가능이다.
클래스의 매개변수는 Cat 의 눈동자와 같이 기본값을 줄 수도 있고, 털처럼 기본값을 안줄 수도 있다. 기본값을 주지 않은 매개변수는 선언 시 반드시 매개변수값을 넣어주어야 한다. 기본값이 있는 곳에 새로운 매개변수 값을 넣으면 새로운 값으로 덮어쓴다.
이렇게 작성된 코드는 반복작업도 굉장히 간편하다. 밥과 관련된 행동을 반복하고 싶다면 다음과 같이, 코드 한 줄이면 반복 작업을 수행할 수 있다.
fun main(){
val cat = Cat()
cat.밥과 관련된 행동(false)
cat.밥과 관련된 행동(true)
cat.밥과 관련된 행동(true)
cat.밥과 관련된 행동(true)
}
class Cat( val 눈동자: String = "Blue",
var 털: String,
val 성격: String = "커여워")
{
fun 밥과 관련된 행동(밥: Boolean){
if(!밥){
println("냥냥펀치!!")
} else {
println("와구와구")
}
}
}
결과
냥냥펀치!!
와구와구
와구와구
와구와구
한편 같은 객체이지만, 서로 다른 존재를 부르고 싶을때도 간편하다.
fun main(){
val catBlue = Cat("Blue", "너무많아!", "도도해!")
val catBlack = Cat("Black", "조금있어!")
val catOdd = Cat("Odd", "깍어비리기!!", "나른해")
println("${catBlue.눈동자}, ${catBlue.털}, ${catBlue.성격}")
println("${catBlack.눈동자}, ${catBlack.털}, ${catBlack.성격}")
println("${catOdd.눈동자}, ${catOdd.털}, ${catOdd.성격}")
}
class Cat( var 눈동자: String,
var 털: String,
val 성격: String = "커여워")
{
fun 밥과 관련된 행동(밥: Boolean){
if(!밥){
println("냥냥펀치!!")
} else {
println("와구와구")
}
}
}
결과
Blue, 너무많아!, "도도해!
Black, 조금있어! 커여워
Odd, 깍어비리기!!, 나른해
참고로 Class 를 직접 부르면 컴파일러는
클래스는 직접 호출하지 않고, 반드시 변수 등에 선언을 하고서 사용해야 한다. 클래스는 수치만 들어간 설계도이기에 설계도를 직접 호출하면 당연히
실제 사용자는 ? 를 띄울 뿐이다.
객체 지향 프로그래밍은 하나의 객체를 관점으로 프로그래밍을 작성하는 것을 의미한다. 반복적인 작업을 피하고, 이해와 효율성을 높이기 위해 사용된다.
Class 는 하나의 객체를 담는 그릇이다. 실제 치수, 내용 등을 포함하고 있지만 기본적으로 설계도이기에 사용 시 다른 변수에 선언을 하고서 사용해야 한다.
모듈화를 통해 코드 전체의 이해와 재사용으로 효율성이 높아진다.
단, 모듈화로 인해 컴파일러는 더 많은 코스트를 요구하여 성능에는 더 안 좋다. 또한 설계 자체에 시간이 오래 걸릴 수 있다.
감사합니다 :)
참고
Udemy # Android Jetpack Compose: The Comprehensive Bootcamp [2022]