반응형
Jake Seo
제이크서 위키 블로그
Jake Seo
전체 방문자
오늘
어제
  • 분류 전체보기 (715)
    • 일상, 일기 (0)
    • 백준 문제풀이 (1)
    • 릿코드 문제풀이 (2)
    • 알고리즘 이론 (10)
      • 기본 이론 (2)
      • 배열과 문자열 (8)
    • 데이터베이스 (15)
      • Planet Scale (1)
      • MSSQL (9)
      • 디비 기본 개념 (1)
      • SQLite 직접 만들어보기 (4)
    • 보안 (7)
    • 설계 (1)
    • 네트워크 (17)
      • HTTP (9)
      • OSI Layers (5)
    • 회고 (31)
      • 연간 회고 (2)
      • 주간 회고 (29)
    • 인프라 (52)
      • 도커 (12)
      • AWS (9)
      • 용어 (21)
      • 웹 성능 (1)
      • 대규모 서비스를 지탱하는 기술 (9)
    • 깃 (7)
    • 빌드 도구 (7)
      • 메이븐 (6)
      • 그레이들 (0)
    • Java (135)
      • 이펙티브 자바 (73)
      • 자바 API (4)
      • 자바 잡지식 (30)
      • 자바 디자인 패턴 (21)
      • 톰캣 (Tomcat) (7)
    • 프레임워크 (64)
      • next.js (14)
      • 스프링 프레임워크 (28)
      • 토비의 스프링 (6)
      • 스프링 부트 (3)
      • JPA (Java Persistence API) (5)
      • Nest.js (8)
    • 프론트엔드 (48)
      • 다크모드 (1)
      • 노드 패키지 관리 매니저 (3)
      • CSS (19)
      • Web API (11)
      • tailwind-css (1)
      • React (5)
      • React 새 공식문서 요약 (1)
      • HTML (Markup Language) (5)
    • 자바스크립트 (108)
      • 모던 자바스크립트 (31)
      • 개념 (31)
      • 정규표현식 (5)
      • 코드 스니펫 (1)
      • 라이브러리 (6)
      • 인터뷰 (24)
      • 웹개발자를 위한 자바스크립트의 모든 것 (6)
      • 팁 (2)
    • Typescript (49)
    • 리눅스와 유닉스 (10)
    • Computer Science (1)
      • Compiler (1)
    • IDE (3)
      • VSCODE (1)
      • IntelliJ (2)
    • 세미나 & 컨퍼런스 (1)
    • 용어 (개발용어) (16)
      • 함수형 프로그래밍 용어들 (1)
    • ORM (2)
      • Prisma (2)
    • NODEJS (2)
    • cypress (1)
    • 리액트 네이티브 (React Native) (31)
    • 러스트 (Rust) (15)
    • 코틀린 (Kotlin) (4)
      • 자바에서 코틀린으로 (4)
    • 정규표현식 (3)
    • 구글 애널리틱스 (GA) (1)
    • SEO (2)
    • UML (2)
    • 맛탐험 (2)
    • 리팩토링 (1)
    • 서평 (2)
    • 소프트웨어 공학 (18)
      • 테스팅 (16)
      • 개발 프로세스 (1)
    • 교육학 (1)
    • 삶의 지혜, 통찰 (1)
    • Chat GPT (2)
    • 쉘스크립트 (1)
    • 컴파일 (2)
    • Dart (12)
    • 코드팩토리의 플러터 프로그래밍 (4)
    • 플러터 (17)
    • 안드로이드 스튜디오 (1)
    • 윈도우즈 (1)
    • 잡다한 백엔드 지식 (1)
    • 디자인 패턴 (1)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • 러스트
  • 자바스크립트
  • Pre-rendering
  • Java
  • 메이븐 라이프사이클
  • item8
  • 자바스크립트 인터뷰
  • 객체복사
  • 디자인패턴
  • 알고리즘
  • MSSQL
  • 도커공식문서
  • 참조 해제
  • prerendering
  • 빈 검증
  • pnpm
  • rust
  • serverless computing
  • 작업기억공간
  • 서버리스 컴퓨팅
  • 자바
  • 스프링 검증
  • 자바 검증
  • 싱글톤 패턴
  • NEXT JS
  • 슬로우 쿼리
  • next js app
  • item7
  • 자바스크립트 면접
  • bean Validation
  • 싱글톤
  • 자바 디자인패턴
  • 토비의 스프링
  • 자료구조
  • item9
  • 느린 쿼리
  • try-with-resources
  • 싱글턴
  • Next.js
  • 메이븐 페이즈
  • 추상 팩터리 패턴
  • 프로그래머의 뇌
  • 플라이웨이트패턴
  • 이펙티브 자바
  • 이펙티브 자바 item9
  • 이펙티브자바
  • 외래키 제약조건
  • 팩터리 메서드 패턴
  • 메이븐 골
  • Javadoc 자바독 자바주석 주석 Comment

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
Jake Seo

제이크서 위키 블로그

코드팩토리의 플러터 프로그래밍

코드 팩토리의 플러터 프로그래밍 - 다트 언어 마스터하기, 2장 다트(Dart) 객체지향 프로그래밍

2023. 10. 15. 19:24

코드 팩토리의 플러터 프로그래밍 - 다트 언어 마스터하기, 2장 다트(Dart) 객체지향 프로그래밍

"이 글은 골든래빗 《코드 팩토리의 플러터 프로그래밍》의 02장 써머리입니다."

객체지향 프로그래밍의 필요성

  • 적절한 추상수준을 유지하며 소스코드의 유지보수를 용이하게 하는 것
    • main() 함수에 모든 행위를 기술하지 않는다.
  • 기본적으로는 변수와 메서드를 클래스에 종속되도록 코딩하여 유지보수를 용이하게 한다.
  • 클래스를 만들어 데이터가 가질 값과 기능을 설계한다.

클래스

  • 클래스에 속한 함수는 메서드라 부름
  • 함수는 메서드를 포함하는 더 큰 개념
  • 클래스 내부 멤버 변수나 메서드에 접근할 때는 this 키워드 이용

  • [[001.다트-클래스]]
  • 다트(Dart) 언어의 클래스(Class) 정리

class Car {
  // 멤버
  String name = "sonata";

  // 메서드
  void printName() {
    // this 는 함수 내부에 같은 이름의 변수가 없다면 생략 가능하다.
    print('This car is ${this.name}');
  }
}

void main() {
  Car sonata = Car(); // 인스턴스 생성

  sonata.printName();
  print(sonata.name);
}

생성자

  • 클래스의 인스턴스를 생성하는 메서드
  • 클래스와 같은 이름을 가진 메서드

  • [[004.다트-생성자(constructors)]]
  • 다트 (Dart) 언어의 생성자 (Constructors) 정리

class Car {
  // 값을 변경할지 안할지 모르는 변수는 일단 final 키워드를 붙여준다.
  final String name;

  // 생성자
  // 클래스와 같은 이름이어야 한다.
  // 함수의 매개변수를 선언하는 것처럼 매개변수를 지정해준다.
  Car(String name) : this.name = name;

  void printName() {
    print('This car is ${this.name}');
  }
}

void main() {
  Car sonata = Car('sonata');
  Car k5 = Car('k5');

  sonata.printName();
  k5.printName();
}

네임드 생성자

  • 네임드 파라미터와 비슷한 개념
  • 클래스를 생성하는 방법을 여러개 사용하고 싶을 때 사용
  • Class.fromMap() 과 같은 네임드 생성자 기법을 이용하면, 멤버 변수가 많아 순서가 헷갈릴 때나 모든 멤버를 설정할 필요 없을 때 큰 이득을 볼 수 있음
  • 생성자에서 멤버 변수를 여러개 설정할 땐 , 키워드 이용

[[004.다트-생성자(constructors)#명명된 생성자 (Named constructors)]]

class Car {
  final String name;
  final int price;

  Car(String name, int price)
    : this.name = name,
      this.price = price;

  Car.fromMap(Map<String, dynamic> map)
    : this.name = map['name'],
      this.price = map['price'];

  void printName() {
    print('This car is ${this.name} and the price is ${this.price}');
  }
}

void main() {
  Car sonata = Car('sonata', 3000);

  sonata.printName();

  Car k5 = Car.fromMap({
    'name': 'k5',
    'price': 2500
  });

  k5.printName();
}

프라이빗 (Private) 변수

  • _ 로 시작하는 변수명을 지으면 프라이빗 변수 설정이 가능함
  • Dart 언어의 프라이빗 변수는 다른 언어와 다르게 같은 파일 내에서만 접근이 가능함
    • 자바에서의 프라이빗 변수는 클래스 내부에서만 사용하고 외부 클래스에서 접근할 수 없음
class Car {
  String _name;
  Car(this._name);
}

void main() {
  Car sonata = Car('sonata');
  // 다른 파일에서는 접근 불가능.
  print(sonata._name);
}

게터(Getter) / 세터(Setter)

  • 객체지향 프로그래밍에서 보통 클래스 멤버 변수 값을 가져오거나 설정하는 부분이 외부로 노출될지 결정하기 위해 사용한다.
  • 요즘엔 객체지향 프로그래밍에서 유지보수를 위해 불변성을 많이 이용하기 때문에 세터를 많이 사용하지 않는다.
    • final 을 이용해 불변 멤버를 최대한 활용하고 진짜 필요할 때만 일반 멤버를 생성하는 것이 좋다.
    • 자바에서도 비슷한 문제로 고통을 겪는 경우가 많다. [[04.lombok-주의점]] 에서 @Setter 사용 주의 부분이 그렇다.
  • get 과 set 키워드가 있는 것도 특이하다.
    • 보통은 void setName() { ... } 같은 식으로 메서드를 구성하는데 키워드가 있으니 좀 더 명확하고 언어적으로 접근해 특수한 기능을 넣기도 좋을 것 같다.
class Car {
  String _name = 'car';

  String get name {
    return this._name;
  }

  // final 이 아니어야 setter 가 의미가 있음
  set name(String name) {
    this._name = name;
  }
}

void main() {
  Car sonata = Car();
  sonata.name = 'sonata'; // setter 로 설정, 'car' -> 'sonata'
  print(sonata.name); // getter 로 접근
}

상속 (Externds, Inheritance)

  • 하위 클래스에게 멤버 변수와 메서드를 물려줌
  • 단 하나의 클래스만 상속 가능함
  • super() 생성자를 통해 부모 클래스의 멤버에 값이 설정되는 것이 강제됨
    • 그래야만 부모 클래스의 모든 메서드나 멤버 변수를 정상적으로 이용할 수 있기 때문임
class Car {
  final String _name;

  String get name {
    return this._name;
  }

  Car(this._name);

  void printCar() {
    print('Car');
  }
}

class Sonata extends Car {
  Sonata(
    String name
  ) : super (
    name
  );

  void printSonata() {
    print('$name Sonata');
  }
}

void main() {
  Sonata sonata = Sonata('LF');
  sonata.printSonata();
  sonata.printCar();
}

오버라이드

  • @override, 부모 클래스에 정의된 메서드를 자식 클래스의 방식으로 재정의할 때 쓰는 키워드
  • 안써도 동작에는 무관하나 유지보수를 위해 써주는 것이 좋음
class Car {
  final String _name;

  String get name {
    return this._name;
  }

  Car(this._name);

  void printCar() {
    print('Car');
  }
}

class Sonata extends Car {
  Sonata(
    String name
  ) : super (
    name
  );

  void printSonata() {
    print('$name Sonata');
  }

  @override
  void printCar() {
    print('I am $name Sonata');
  }
}

void main() {
  Sonata sonata = Sonata('LF');
  sonata.printSonata();
  sonata.printCar(); // 오버라이드된 메서드 호출
}

인터페이스

  • 공통 기능을 정의
  • 상속과 다르개 몇개든 한 클래스에 몇개의 인터페이스든 구현(implements) 가능하다.
  • 정의한 클래스를 implements 키워드를 통해 구현하면 된다.
class Car {
  final String _name;

  String get name {
    return this._name;
  }

  Car(this._name);

  void printCar() {
    print('Car');
  }
}

class Printer {
  void printItsNameTwice() {

  }
}

class Random {
  void printAnything() {

  }
}

class Sonata extends Car implements Printer, Random {
  Sonata(
    String name
  ) : super (
    name
  );

  void printSonata() {
    print('$name Sonata');
  }

  @override
  void printCar() {
    print('I am $name Sonata');
  }

  void printItsNameTwice() {
    print('$name$name');
  }

  void printAnything() {
    print('Anything about sonata');
  }
}

void main() {
  Sonata sonata = Sonata('LF');
  sonata.printItsNameTwice();
  sonata.printAnything();
}

믹스인 (Mixins)

  • 보통 다른 객체지향 언어에서도 클래스에 원하는 기능만 덧붙일 수 있는 개념으로 사용된다.
    • [[01.mixin-and-include]]
    • SCSS 의 믹스인
    • [[what-is-mixin]]
    • 자바의 믹스인
  • mixin 키워드를 따로 제공한다.
    • 뒤에 on 클래스명 으로 어떤 클래스에 대한 믹스인인지 명시하면 된다.
mixin RearCamera on Car {
  void turnOnRearCamera() {
    print('$name Turn on Rear camera');
  }

  void turnOffRearCamera() {
    print('$name Turn off Rear camera');
  }
}

mixin AutoPilot on Car {
  void turnOnAutoPilot() {
    print('$name Turn on Auto pilot');
  }

  void turnOffAutoPilot() {
    print('$name Turn off Auto pilot');
  }
}

class Car {
  final String _name;

  String get name {
    return this._name;
  }

  Car(this._name);

  void printCar() {
    print('Car');
  }
}

class Sonata extends Car with RearCamera, AutoPilot{
  Sonata(
    String name
  ) : super (
    name
  );

  void printSonata() {
    print('$name Sonata');
  }
}

void main() {
  Sonata sonata = Sonata('LF');
  sonata.turnOnRearCamera();
  sonata.turnOnAutoPilot();
}

추상 (Abstract)

  • 상속이나 인터페이스 전용 클래스를 생성하는 개념
    • 사용할 멤버 변수와 메서드 시그니쳐까지만 이용된다.
  • 어떤 클래스들의 추상적인 공통 설계도 목적으로 이용할 수 있다.
  • 인스턴스화 할 수 없다
  • 구현하는 곳에서 멤버 변수까지 그대로 다시 재작성해주어야 함
abstract class Car {
  final String name;
  final int capacity; // engine displacement

  Car(this.name, this.capacity);

  void printName(); // 구현 필요 없음
  void printCapacity(); // 구현 필요 없음
}

class Sonata implements Car {
  final String name;
  final int capacity;

  Sonata(
    this.name,
    this.capacity
  );

  void printName() {
    print('this sonata is $name');
  }

  void printCapacity() {
    print('this sonata capacity is ${capacity}cc');
  }
}

void main() {
  Sonata sonata = Sonata('LF', 1999);
  sonata.printName();
  sonata.printCapacity();
}

제네릭 (Generic)

  • 클래스나 함수가 사용하는 타입을 정의하는 타이밍을 인스턴스화하거나 실행할 때로 미룬다.
  • List, Map, Set 등의 예시가 있다.
class Cache<T> {
  // 인스턴스화 될 때까지 알 수 없음
  final T data;

  Cache({
    required this.data
  });
}

void main() {
  final cache = Cache<List<int>>(
    data: [1, 2, 3]
  );

  print(cache.data.reduce((value, element) => value + element));
}

제네릭에서 자주 이용되는 1글자 알파벳

  • T: 변수의 타입 (Type)
  • E: 리스트 내부의 요소 (Element)
  • K: 키 (Key)
  • V: 값 (Value)

스태틱 (Static)

  • 클래스의 인스턴스에 귀속되지 않고 클래스 자체에 귀속됨
  • 인스턴스끼리 공유해야 하는 값이 있을 때 용이
class Counter {
  static int i = 0;
  // int i = 0; 같은 이름의 멤버를 할당하면 에러난다.

  Counter() {
    i++;
    print(i);
  }
}

void main() {
  Counter count1 = Counter();
  Counter count2 = Counter();
  Counter count3 = Counter();
}

캐스케이드 연산자

  • 인스턴스의 멤버 변수나 메서드를 연속해서 사용하는 기능
  • 조금 더 간결한 코드 작성 가능
class Counter {
  int i = 0;

  void increment() {
    i++;
    print('now counter is $i');
  }
}

void main() {
  Counter counter = Counter()
    ..increment()
    ..increment()
    ..increment()
    ..increment();
}
반응형
저작자표시 비영리 (새창열림)

'코드팩토리의 플러터 프로그래밍' 카테고리의 다른 글

코드 팩토리의 플러터 프로그래밍 - 플러터 기본 다지기, 4장 플러터 입문하기  (1) 2023.10.29
코드 팩토리의 플러터 프로그래밍 - 다트 언어 마스터하기, 3장 다트(Dart) 비동기 프로그래밍  (0) 2023.10.21
코드 팩토리의 플러터 프로그래밍 - 다트 언어 마스터하기, 1장 다트 (Dart) 입문하기  (0) 2023.10.08
    '코드팩토리의 플러터 프로그래밍' 카테고리의 다른 글
    • 코드 팩토리의 플러터 프로그래밍 - 플러터 기본 다지기, 4장 플러터 입문하기
    • 코드 팩토리의 플러터 프로그래밍 - 다트 언어 마스터하기, 3장 다트(Dart) 비동기 프로그래밍
    • 코드 팩토리의 플러터 프로그래밍 - 다트 언어 마스터하기, 1장 다트 (Dart) 입문하기
    Jake Seo
    Jake Seo
    ✔ 잘 보셨다면 광고 한번 클릭해주시면 큰 힘이 됩니다. ✔ 댓글로 틀린 부분을 지적해주시면 기분 나빠하지 않고 수정합니다. ✔ 많은 퇴고를 거친 글이 좋은 글이 된다고 생각합니다. ✔ 간결하고 명료하게 사람들을 이해 시키는 것을 목표로 합니다.

    티스토리툴바