1. 오버라이딩
: 상속받은 부모클래스의 정보(프로퍼티)나 행위(메소드) 재설계
= 리디파인...?
- 받는 인자의 개수, 타입 같음
- 부모 클래스의 메소드와 같은 이름을 가진 하나의 함수만을 가짐
= 부모 클래스의 메소드와는 다른 메소드가 된 것
(+) 자식 클래스만의 정보, 동작을 만들 수 있음
(+) 재사용성, 일관성 등의 장점 유지
*오버라이딩 단축키
Control + O
fun main() {
var bird = Bird("새")
var chicken = Chicken("닭", 2)
bird.fly()
chicken.fly()
}
open class Bird(name:String) { //open 작성
var name: String = ""
init {
this.name = name
}
open fun fly() { //메소드에서도 open을 써야하는듯
println("${name}은 날아요~")
}
}
class Chicken(name: String, age: Int) : Bird(name) {
var age:Int = 0
init { //부모클래스에 init 있으니 여기도..?
this.age = age
}
override fun fly() {
// 부모객체의 fly메소드를 부르는 행위임. 이걸 포함하려면 작성하기
// super.fly()
println("${age}살의 ${name}가 날아봅니다~ 꼬끼오!")
}
}
*super 안 쓰는 이유를 더 찾아봤는데
// super.메서드이름() --> 내부적으로 상속받으면 자동으로 만들어지는 부모객체. = 부모객체의 메서드를 불러라
//그럼 오버로딩 후에는 super 쓰나? 확인하기@@@ --> 딱히 쓰지 않아도... 다른 메소드가 있더라. 자바로 바꾸면 나타나던데
코틀린에서는 `super` 키워드를 사용하여 부모 클래스의 생성자나 메서드를 호출할 필요가 없는 경우가 있는데, 그 이유는 다음과 같습니다: 1. **기본 생성자 호출**: 자식 클래스가 부모 클래스를 상속받을 때, 부모 클래스의 기본 생성자가 호출됩니다. 이는 코틀린에서 기본적으로 제공되는 동작입니다. 따라서 대부분의 경우에는 명시적으로 `super` 키워드를 사용하지 않아도 됩니다. 2. **메서드 오버라이딩**: 부모 클래스의 메서드를 자식 클래스에서 오버라이드할 때에도 `super` 키워드를 사용하지 않아도 됩니다. 부모 클래스의 메서드를 호출하려면 `super`를 사용할 수 있지만, 그렇지 않은 경우에는 자식 클래스에서 오버라이드된 메서드가 호출됩니다. 3. **부모 클래스 생성자 호출**: 만약 자식 클래스가 부모 클래스의 생성자를 오버라이드하거나 추가적인 생성자를 정의할 때에는 `super` 키워드를 사용하여 부모 클래스의 생성자를 명시적으로 호출해야 합니다. 하지만 코틀린에서는 생성자 호출을 간단히 처리하기 때문에, `super` 키워드를 사용하지 않고도 부모 클래스의 생성자가 자동으로 호출됩니다. 결론적으로, 코틀린은 명시적인 `super` 호출을 최소화하여 코드를 간결하게 만들 수 있도록 설계되었습니다. 따라서 대부분의 경우에는 `super`를 사용하지 않아도 됩니다. |
(...라는데 이건 조금 더 비교해서 정리해야할 듯. 자바랑 c++이랑 다 섞여서 뒤죽박죽이네)
- object 표현식을 사용해 하위 클래스 만들지 않고 클래스의 특정 메서드 오버라이딩하기
//익명 객체 : 이름이 없는 클래스 인스턴스 만들기.
open class Hero(){
fun work() = println("working")
open fun fly() = println("flying")
}
fun main(){
val person = object: Hero(){ //object 표현식으로 fly() 구현의 재정의
override fun fly() = println("not flying")
}
person.work()
person.fly()
}
//working
//not flying
(1) 활용사례 1
window.addMouseListener(object: MouseAdapter){
override fun mouseClicked(e: MouseEvent){
...
}
override fun mouseEntered(e: MouseEvent){
...
}
}
- object: MouseAdapter라는 구문은 MouseAdapter 클래스를 상속하는 익명 객체를 생성.
(MouseAdapter 클래스는 MouseListener 인터페이스의 구현을 제공하는 추상 클래스)
익명 객체를 생성함으로써, 필요한 메서드만 오버라이드하여 해당 이벤트를 처리할 수 있음.
(위의 코드에서는 mouseClicked와 mouseEntered 메서드를 오버라이드하여 각각 마우스 클릭 및 진입 이벤트를 처리함)
MouseListener 인터페이스를 직접 구현하는 대신 익명 객체를 사용하여 더 간결하게 코드를 작성할 수 있음
(2) 활용사례 2 - 단 한 번 사용할 인터페이스의 구현 클래스 정의 없이 사용하기
interface Shape{
fun onDraw() //구현해야 할 메서드
}
val triangle = object: Shape{
override fun onDraw(){
//여기서 단 한 번 구현함
}
}
(3) 활용사례 3 - 객체는 필요하지만 상위 인터페이스, 클래스가 없는 경우
fun foo(){
val adHoc = object{
var x: Int = 0
var y: Int = 0
}
print(adHoc.x + adHoc.y)
}
2. 오버로딩
: 매개변수의 개수, 자료형을 다르게 해 동명의 다른 메소드를 만든다
//반환자료형은 오버로딩에 영향을 주지 않음
- 받는 인자, 개수 등이 달라짐
//매개변수의 개수 등에 따라 어느것이 쓰일지가 결정됨
- 상속 관련 --> 자식 클래스는 부모 클래스의 함수와 같은 이름을 가진 두 개의 함수를 가짐
//하나는 부모 클래스에 정의되어있고, 나머지는 자식 클래스에 정의됨
fun main() {
var calc = Calculator() //객체 만들기
var intResult = calc.add(1,2)
var doubleResult = calc.add(1.2, 2.2)
println("정수 덧셈결과: ${intResult}")
println("실수 덧셈결과: ${doubleResult}")
}
class Calculator {
fun add(num1: Int, num2: Int): Int {
return num1+num2
}
fun add(num1: Double, num2: Double): Double {
return num1+num2
}
}
class Point(var x: Int = 0, var y: Int = 10) {
// plus 함수의 연산자 오버로딩
operator fun plus(p: Point) : Point {
return Point(x + p.x, y + p.y)
}
operator fun dec() = Point(--x, --y)
}
fun main() {
val p1 = Point(3, -8)
val p2 = Point(2, 9)
var point = Point()
println(point.y)
println(p1.x)
point = p1 + point
println("point = (${point.x}, ${point.y})")
point = p1 + p2 // Point 객체의 + 연산이 가능하게 되었다.
println("point = (${point.x}, ${point.y})")
--point // -- 연산자
println("point = (${point.x}, ${point.y})")
}
10
3
point = (3, 2)
point = (5, 1)
point = (4, 0)
'언어 > Kotlin' 카테고리의 다른 글
[Kotlin 문법 종합] - 접근제한자와 관련 용어 정리 (0) | 2024.03.06 |
---|---|
[Kotlin 문법 종합] - 인터페이스, 추상 클래스 (0) | 2024.03.05 |
[Kotlin 문법 종합] - 상속 (0) | 2024.03.05 |
[Kotlin 문법 종합] - 생성자, 객체 (#비교 추가하기) @@ 질문하기! (0) | 2024.03.05 |
[Kotlin 문법 종합] - 메소드, 클래스 (0) | 2024.03.05 |