Dart 기본 문법 06

GreenBean·2023년 4월 4일
0
post-thumbnail

Dart

Dart 공식문서
다트 ( Dart ) 상속
다트 ( Dart ) 접근 지정자

Dart 의 상속

# 상속

// class 부모 클래스명 {
//   멤버 변수;
//   멤버 함수() {
//   }
// }
//
// class 자식 클래스명 extends 부모 클래스명 {
//   @override
//   멤버 함수() {
//   }
// }

class Person {
  String name;
  
  setName(String name) {
    this.name = name;
  }
  
  showInfo() {
    print("name is $name");
  }
}

class Student extends Person {
  int studentID;
  
  
  showInfo() {
    print("name is $name and id is $studentID");
  }
}
  • 상속은 객체 지향 프로그래밍의 꽃이라 할 수 있음
    • 객체 지향 프로그래밍에서 상속은 클래스의 멤버를 물려주는 것을 의미
    • 이때 물려주는 쪽을 부모 클래스 ( 혹은 Super Class ) 라고 하고 상속을 받는 쪽을 자식 클래스 ( 혹은 Sub Class ) 라고 함
  • 상속 받는 쪽 ( 자식 클래스 ) 은 extends 키워드를 통해서 상속받고자 하는 부모 클래스를 지정
    • @override 어노테이션은 부모 클래스의 메서드를 재정의하고 싶을 때 사용
    • 재정의한다는 의미는 기존 메서드에서 구현한 내용 대신 다른 동작을 하는 코드를 구현하는 것
# 예시

class Person {
  late String name;
  
  setName(String name) {
    this.name = name;
  }
  
  getName() {
    return name;
  }
  
  showInfo() {
    print("name is $name");
  }
}

class Student extends Person {
  late int studentID;
  
  
  showInfo() {
    print("name is $name and id is $studentID");
  }
}

main() {
  Student student = Student();
  student.studentID = 2023;
  student.setName("Park");
  student.showInfo();
}

------------------------------------------------------------------------------------------

# 결과

name is Park and id is 2023
  • Student 클래스는 Person 클래스를 상속받고 있음
    • 따라서 Student 클래스는 자식 클래스이고 Person 클래스는 부모 클래스
  • Person 클래스는 1개의 멤버 변수와 3개의 메서드로 구성되어 있음
    • 자식 클래스인 Student 클래스는 이 멤버 변수와 메서드를 모두 상속 받음
    • 따라서 해당 멤버 변수와 메서드를 별도로 Student 클래스 내에 선언하지 않아도 사용 가능
    • 선언된 위치만 부모 클래스에 있을 뿐이지 자식 클래스 내에 존재하지 않는 것과 같음
  • 만약 함수의 기능을 변경하고 싶다면 재정의하면 됨
    • 부모 클래스의 showInfo() 메서드를 재정의 하기 위한 방법
      • Line 20 을 보면 @override 어노테이션이 있고 이것은 showInfo() 메서드를 재정의하기 위한 것
      • showInfo() 는 부모 클래스에서는 name 만 출력하고 있음
      • 자식 클래스의 멤버 변수인 studentID 도 추가해서 출력하도록 변경
  • 이때 자식 클래스의 showInfo() 메서드 내부를 주목
    • Line 22 를 보면 부모 클래스의 메서드인 getName() 메서드에 접근하기 위해서 super 라는 키워드를 사용
    • super 는 부모 클래스를 가리키지만 생략도 가능
    • 자식 클래스는 이미 부모 클래스의 getName() 메서드도 상속 받았기 때문
  • 또한 getName() 을 통해서 name 에 접근하지 않고 곧바로 name 변수를 출력해도 됨
    • name 역시 상속받았기 때문
  • 마지막으로 설펴볼 것은 Line 5 의 this 키워드
    • this 는 해당 인스턴스를 가리킴
    • 여기서는 this.name 이 Person 클래스의 인스턴스 변수인 name 을 가리키고 name 은 setName(String name) 메서드의 인자를 가리킴
    • 변수명이 동일하기 때문에 구분하기 위해서 this 로 인스턴스 변수를 명확히 가리킨 것
  • 상속은 왜 사용할까?
    • 일단 코드를 재사용하기 때문에 클래스가 간소화되고 수정 및 추가가 쉬워짐
      • 위 코드를 기준으로 보면 Student 클래스는 부모 클래스에 있는 멤버들을 일일이 다시 선언할 필요가 없었음
      • 따라서 Student 클래스는 매우 간결해짐
    • 그리고 해당 클래스에서 필요한 기능을 쉽게 추가 가능
      • studentID 변수를 추가했고 showInfo() 메서드도 필요에 맞게 수정함
  • 만약 Student 클래스 하나가 아닌 Employee 클래스 ∙ Manager 클래스 ∙ Programmer 클래스 등 사람과 관련된 수많은 객체를 위한 클래스를 생성한다고 생각해보면 더욱 코드 재사용성이 값진 의미를 가짐
    • 또한 Employee 클래스 하위에 Manager 클래스 ∙ Programmer 클래스를 두는 방식을 또 한번 코드를 재사용할 수 있고 각 객체의 특징에 대해 유연하게 정의하고 수정 및 추가가 가능

Dart 의 접근 지정자

  • 객체 지향 4대 특징
    • 추상화
    • 캡슐화
    • 상속
    • 다형성

캡슐화

  • 간단하게 캡슐화를 설명하면 어떤 객체가 어떤 목적을 수행하기 위한 데이터 ( 멤버 변수 ) 와 기능 ( 메서드 ) 을 적절하게 모으는 것

추상화

  • 추상화는 어떤 객체의 공통된 데이터와 메서드를 묶어서 이름 ( 클래스명 ) 을 부여하는 것
    • 단순히 말하면 클래스를 만드는 일
    • 공통 속성을 추출해나가는 과정을 추상화라고 함
  • 추상화를 잘한다면 중복되는 부분을 많이 없앨 수 있어 코드 재사용률을 높일 수 있음

접근 지정자

  • 접근 지정자는 클래스의 멤버 변수 또는 메서드 앞에 선언되고 종류에 따라 해당 멤버들에게 접근할 수 있는 범위가 달라짐
  • Java 의 경우 네 가지 접근 지정자가 존재
    • 그 중에 private 라는 접근 지정자는 동일 클래스 내에서만 접근이 가능
    • 그리고 public 은 접근 범위에 제한 없이 모든 곳에서 접근 가능
# 접근 지정자

class Person {
  String name;
  int _age;
  eat() {
    print("eat");
  }
  _sleep() {
    print("sleep");
  }
}
  • 다트의 접근 지정자는 딱 두 종류로 private 과 publi
    • 하지만 접근 범위가 자바와 다름
    • 다트에서 private 멤버의 접근 범위 는 동일 클래스가 아니라 라이브러리 (=자바 기준으로 패키지)
  • 또한 접근 지정자의 키워드도 다름
    • 다트는 기본적으로 아무런 키워드가 없을 경우 public
    • private 으로 선언하기 위해서는 변수나 메서드 앞에 _ ( 밑줄 ) 을 붙여야 함
      • 위의 코드에서 _ 가 붙은 _age 와 _sleep() 은 private 이고 name 과 eat() 은 public
# 예시 1

import 'package:dartEx01/src/Person.dart';

main() {
  Person p = Person();
  p.eat();
  // p._sleep(); error
}

# 예시 2

class Person {
  String name;
  int _age;
  
  eat() {
    print("eat");
  }
  
  _sleep() {
    print("sleep");
  }
}
  • Person 클래스를 main.dart 가 아닌 외부의 Person.dart 에 선언
    • main.dart 에서 Person.dart 를 import 하고 public 메서드인 eat() 을 호출
      • 이때 정상적으로 호출이 되어 eat 이 출력됨
      • 하지만 주석 처리된 _sleep() 을 호출하면 에러가 발생
    • private 인 _sleep() 은 main.dart 에서 접근이 불가능하기 때문
profile
🌱 Backend-Dev | hwaya2828@gmail.com

0개의 댓글