본문 바로가기
App Study/Dart & Flutter

노마드코더 Dart Begginer - 4

by 쿠리의일상 2023. 6. 7.

Class

선언

class 키워드를 사용하여 선언

class 클래스명 {
	타입명 변수명 = 초기값;
}

함수의 지역 변수의 경우 타입을 var 로 사용해줄 수 있었지만

클래스의 경우 프로퍼티를 선언할 때 타입명을 꼭 지정해줘야 한다!

여기서 late, final, const 등을 사용해준다.

메서드의 경우, 다른 객체 지향 언어에서 클래스 내의 변수에 접근할 수 있는 this 등은 사용하지 않는 것을 권고하고 있음.

다만, 함수 내에서 동일한 지역 변수명이 된다면 클래스에 접근하기 위한 this 사용은 가능함.

class Player {
  final String name = 'nico';
  int xp = 22;

  void sayHello() {
    print('Hello, My name is $name'); //클래스의 name 에 접근
  }
}

 

호출

new 를 붙이지 않고(붙여도 됨) 클래스명() 으로 호출

클래스명 변수명 = 클래스명();

 

생성자

클래스마다 인자를 다르게 받아서 인스턴스를 만들어주고자 할 때 사용

생성자 함수는 클래스명과 똑같이 하되, 인자에 받아줄 타입명과 변수명을 적어준다.

class 클래스명 {
	late 타입명 변수명;

	클래스명(타입명 변수명, ...) {
    	this.변수명 = 변수명;
        // ...
    }
}

클래스명 변수명 = 클래스명(인자1, ...);
class CustomPlayer {
  late final String name;
  late int xp;

  CustomPlayer(String name, int xp) {
    this.name = name;
    this.xp = xp;
  }
}


void main() {
  CustomPlayer p1 = CustomPlayer('Kim', 100);
  var p2 = CustomPlayer('Lee', 22);
}

이때 정석으로는 late 를 변수에 써줘야 나중에 값이 들어온다는 것을 인식해서 오류가 발생하지 않음.

 

여기서 생성자 함수에서 쓸데없는 코드들이 생겼음을 알 수 있다.

dart 에선 이러한 코드를 줄일 수 있는 방법이 있는데

class 클래스명 {
	타입명 변수명;
    
    클래스명(this.변수명); // 생성자 함수의 축약
}
class CustomPlayer {
  final String name;
  int xp;

  CustomPlayer(this.name, this.xp);
}

이처럼 생성자 함수에 선언해준 프로퍼티의 값을 바로 넣어주면 된다.

 

Named constructor parameter

함수에서 했던 Named Function 처럼 생성자 함수에서도 파라미터에 이름으로 직접 접근이 가능하다.

먼저, 클래스의 프로퍼티의 타입에 required 로 꼭 입력 받아야 함을 표시하고

생성자 함수의 파라미터들을 { } 중괄호로 씌워준다.

그리고 클래스를 인스턴스화 할 때 각 프로퍼티 이름을 적어서 값을 할당해주면 된다.

class CustomPlayer {
   final String name;
   int xp;
   String team;
   int age;

  CustomPlayer({
  	required this.name, 
    required this.xp, 
    required this.team, 
    required this.age});
}

void main() {
  // 인자가 있는 클래스의 호출
  CustomPlayer p1 = CustomPlayer(
    name: 'Kim',
    xp: 100,
    team: 'Halo',
    age: 25,
  );
  var p2 = CustomPlayer(
    name: 'Lee',
    xp: 22,
    team: 'Halo',
    age: 20,
  );
}

 

이제 여기서 Optional parameter 로 설정하고 싶다면 null 이 가능하다는 의미로, nullable 인 ? 를 타입 뒤에 붙여주면 된다. 

 

Named constructor

클래스명.생성자함수명({
	required 타입명 변수명,
}) : this.변수명 = 변수명,
	 this.변수명 = 기본값 설정;

이처럼 필수로 받을 인자만 받아주고, 나머진 default value 로 초기화 시킨다.

다만 값을 넣어줄 땐 : 을 사용하여 넣어줘야 함!

콜론은 argument 와 property 를 1:1 초기화해주는 것임

  // Named Constuctor
  CustomPlayer.createBluePlayer({
    required String name,
    required int age,
  })  : this.name = name,
        this.age = age,
        this.team = 'blue',
        this.xp = 0;

 

Cascade Notation

  var p4 = CustomPlayer(
    name: 'N',
    xp: 11,
    team: 'white`',
    age: 27,
  );
p4.age += 1
p4.xp = 22;

기존의 변수명.프로퍼티 로 접근하여 값을 변경했던 방식에서....

다트에선,

  var p4 = CustomPlayer(
    name: 'N',
    xp: 11,
    team: 'white`',
    age: 27,
  )
    ..age += 1
    ..xp = 22;

이처럼 클래스의 선언부의 ; 세미콜론을 없애주고

변수명에 접근하는 것이 아닌 . 으로 프로퍼티에 접근할 수 있따!

  var p4 = CustomPlayer(
    name: 'N',
    xp: 11,
    team: 'white`',
    age: 27,
  );
  
  var p5 = p4
    ..age += 1
    ..xp = 33;

이처럼 클래스를 생성할 때만 가능한 것이 아닌, 그 이후에도 . 으로 언제든 접근이 가능하다.

 

Enum (열거형)

키워드 enum 사용 ex. flutter 의 Color 도 enum 형태임

정해져있는 범위 안이라면 실수할 가능성을 낮춰줌

enum 열거형명 {
	변수명,
    변수명,
}
enum Team {
  red,
  white,
  blue,
}

class Player {
  final String name = 'nico';
  int xp = 22;

  void sayHello() {
    print('Hello, My name is $name'); // this.name OK
  }
}

class CustomPlayer {
  final String name;
  Team team;
  int xp, age;

  // Named Constructor Parameter
  CustomPlayer({
    required this.name,
    required this.xp,
    required this.team,
    required this.age,
  });

  // Named Constuctor
  CustomPlayer.createBluePlayer({
    required String name,
    required int age,
  })  : this.name = name,
        this.age = age,
        this.team = Team.blue,
        this.xp = 0;
}

 

Abstract Classes (추상 클래스)

추상 메서드를 가진 클래스를 추상 클래스, 일종의 청사진

추상 클래스는 인스턴스를 생성할 수 없다!

// Abstract class
abstract class Human {
  void walk();
}

class User extends Human {
  void walk() {
  	print('Walking');
  }
}

추상 클래스는 extends 로 선언해줄 수 있으며, 추상 메서드의 내용을 구현해줘야한다.

 

Inheritance (상속)

extends 로 부모 클래스를 상속 받는다.

이때 상속 받은 프로퍼티는 super 로 초기화 해줘야 한다.

즉 super 는 상속 받은 부모 클래스를 가리키는 것

class Person {
  final String name;
  Person(this.name) {
    print('Name : $name');
  }
}

class SalesMan extends Person {
  final String part;

  SalesMan({
    required this.part,
    required String name,
  }) : super(name);
}

 

부모 클래스의 메서드를 오버라이딩 하고 싶을 땐, @override 키워드를 쓰고 함수를 재정의해준다.

class Person {
  final String name;
  Person(this.name) {
    print('Name : $name');
  }

  void sayHello() {
    print('사람 : $name');
  }
}

class SalesMan extends Person {
  final String part;

  SalesMan({
    required this.part,
    required String name,
  }) : super(name);

  @override
  void sayHello() {
    super.sayHello();
    print('사람 -> 세일즈맨 $name');
  }
}

부모 클래스의 함수를 자식 클래스에서 불러와주려면 역시 super 로 접근해준다.

 

** 상속과 추상 클래스의 개념은 플루터에선 잘 사용되는 개념은 아니라고 함!

 

Mixins

생성자가 없는 클래스!

클래스에 프로퍼티들을 추가할 때 주로 사용, Flutter 플러그인에 주로 사용

class 대신 mixin 키워드로 선언해주고(강의 내용과 달리 변경됨)

키워드 with 을 extends 대신 사용하여 다른 클래스의 프로퍼티와 메서드를 그저 긁어오는 용도로 사용!

=> 클래스의 재사용성이 높아지는 이점

mixin Strong {
  final double strengthLevel = 1500.88;
}

mixin QuickRunner {
  void runQuick() {
    print('Runnn!');
  }
}

mixin Tall {
  final double height = 1.99;
}

class ExPlayer with Strong, QuickRunner {}

class Ex2Palyer with Tall, Strong {}

 

'App Study > Dart & Flutter' 카테고리의 다른 글

노마드코더 Dart Beginner - 3  (0) 2023.06.05
노마드코더 Dart Begginer - 2  (0) 2023.06.04
노마드코더 Dart Begginer - 1  (0) 2023.06.03