

생성자 존재 이유
위 이미지 처럼 클래스를 통해 인스턴스를 만들었다고 가정해본다.
현재 위 이미지의 Idol 클래스에는 문제가 있다.
클래스를 통해 여러 인스턴스를 만드는 것처럼, 블랙핑크 뿐만 아니라 BTS도 만들 수 있고 레드벨벳도 만들 수 있고 굉장히 많은 수많은 무한하게 인스턴스를 생성할 수 있다고 하였다.
하지만 위 코드 이미지 처럼, 지금 현재 지금 현재 이 Idol 클래스로는 블랙핑크란 이름으로 인스턴스를 생성할 수 밖에 없다.
하지만, 파라미터를 받아 가지고 함수의 반복적인 코드를 제거할 수 있었던 것처럼 클래스에서도 파라미터를 받을 수 있는 방법이 있다.
어떻게 받냐면은 constructor(생성자) 라는 것으로 받을 수 있게 가능하도록 만들어준다.
생성자 개념
생성자(constructor)는 클래스의 인스턴스를 초기화한다.
Dart에서 생성자는 클래스와 같은 이름을 가지며, 객체를 생성할 때 자동으로 호출된다.
생성자를 통해 객체의 초기 상태를 설정하고, 필요한 초기화 작업을 수행할 수 있다.
생성자 선언 방법
생성자를 선언할 때, 해당 클래스 안에만 하면 되는데 똑같이 클래스의 이름을 먼저 적는다.
Idol 클래스 클래스니까 Idol이라고 적고, 세미클론을 붙이면 가장 기본적인 생성자가 생성된다.
이 생성자의 이 괄호 안에 부분에, 함수로 치면은 파라미터를 넣을 수 있는 부분이다.
생성자도 똑같이 괄호안에다가 파라미터를 넣을 수가 있다.
괄호안에, 어떤 파라미터를 넣으면 되냐
이름이랑, 멤버들 얘네를 사실상 바꾸고 싶기 때문에, 내부에서 선언을 하면 된다.
괄호안에는 named parameter랑 positional parameter를 모두 사용할 수가 있다.
일단은 positional parameter 먼저 넣어볼 것인데, string name을 받을 거고, list string하고서 members를 받을것이다.
그러면 얘네들를 받으면은 input을 받았다는 것인데, 그럼 얘네들를 어디에다가 저장을 해줘야 한다.
그것은 아래와 같이 하면 된다.
콜론을 넣어준 다음에, 해당 클래스를 의미하는 this라는 키워드를 사용하여 this와 점하면(this.)은 실제 이 클래스 안에 있는 모든 값들이 표시되는 것을 확인할 수 있다.
여기에서 this.name이라고 하고 name에다가, name이라는 값을 넣어줄 것이다.
여기서 this.name은 이 클래스 name이고, this.name에 할당한 name은 파라미터로 받은 name인 것이다.
members도 똑같이 위와 같은 형태로 만들어준다.
이렇게 생성자를 만드는 순간 바로 아래 이미지처럼, 표시된 부분에 빨간 줄이 생기는 거 볼 수 있다.
에러가 생긴 이유는 함수에서도 똑같이 발견할 수 있는데, 포지셔널 파라미터를 생성하고서 아무것도 넣지 않으면 이런 에러가 생겼었다.
그러면 오류를 없애기 위해, 아래 이미지처럼, positional parameter를 넣어준다.
에러가 사라졌다면, 실제로 클래스안에 정의된 변수인 name과 members의 정했던 이 값들을 지워줘도 된다.
왜냐면 외부에서 값을 받기로 했기 때문이다.
함수들도 this을 사용하여 값들을 다이나믹하게 받을 수 있다.
아래 이미지처럼 수정하면, 외부에서 값을 받아서 쓸 수 있다.
생성자 요약
여기에서 생성자를 한 번 더 간단하게 만드는 방법이 있다.
보통 클래스에서 파라미터를 이렇게 받게 되면은 한 90% 는 거의 해당 클래스의 내부에 변수 값에다가 그 값들을 그냥 지정을 해주는 역할을 거의 대부분을 한다.
그래서 위처럼 생성자를 길게 작성하는 것을 조금 더 간결하게 작성할 수 있는 방법이 개발이 되었다.
그것은 아래 이미지처럼 작성하면 된다.
this는 클래스를 지칭하기 때문에 생성자 name에 값을 받아서, 클래스 name 변수에 값을 바로 넣는다고 이해하면 된다.
물론 this.name, this.members 이렇게 해도 실제 이 클래스에 name과 members의 타입이 맞게 파라미터 안에다가 값을 넣어줘야 된다.
만약에 여기에서 갑자기 마음대로 값을 String에서 List로 바꿔버리면 에러가 난다.
그렇기 때문에 타입도 자동으로 이렇게 유추가 된다라는 것을 알 수가 있다.
기본 생성자
기본 생성자는 가장 단순한 형태의 생성자이다.
클래스 이름과 동일한 이름을 가지며, 매개변수를 통해 객체의 초기 상태를 설정할 수 있다.
클래스 선언:
클래스 사용:
이 예제에서:
- name과 age는 final 키워드로 선언되어 변경 불가능하다.
- 생성자 Idol(this.name, this.age)는 매개변수로 받은 값을 바로 멤버 변수(클래스 내부에 정의된 변수)에 할당한다.
- Idol 클래스의 생성자는 위치 기반 파라미터를 사용하므로, 순서대로 인자를 전달한다. = ('제니', 26)
명명된 파라미터를 사용한 생성자
객체 생성 시 매개변수의 이름을 명시적으로 지정할 수 있게 해준다.
생성자 앞에 required 키워드를 사용하여 해당 파라미터가 필수임을 지정한다.
클래스 선언:
클래스 사용:
이 예제에서:
- 생성자 파라미터를 중괄호 {}로 감싸 명명된 파라미터로 만들었다.
- 파라미터 순서에 구애받지 않는다.
- 객체 생성 시 Idol(name: "제니", age: 26)과 같이 파라미터 이름을 명시적으로 사용한다.
선택적인 명명된 파라미터를 사용한 생성자
명명된 파라미터에 기본값이 있으면 required 키워드가 필요없어진다.
기본값이 있기 때문에 실제 클래스를 사용할 떄, 클래스 안에 값을 넣어 주지 않아도 된다.
실행 결과:
안녕하세요! 저는 제니이고, 26살입니다.
클래스 안에 값을 넣어주게 되면, 그 값이 출력되게 된다.
실행 결과:
안녕하세요! 저는 지수이고, 25살입니다.
이 예제들에서:
- 생성자 파라미터를 중괄호 {}로 감싸 명명된 파라미터로 만들었다.
- 파라미터 순서에 구애받지 않는다.
- 객체 생성 시 Idol(name: "제니", age: 26)과 같이 파라미터 이름을 명시적으로 사용해도 된고 안해도 된다.
- 이름을 명시적으로 사용하는 형태는 Flutter 개발시 각 위젯(클래스)이 파라미터를 가지는 것과 같다.
*실제 위젯에서 사용되는 선택적인 명명된 파라미터를 사용한 생성자
선택적인 명명된 파라미터를 사용한 생성자는 실제 Futter에서 많이 사용되는 형태이다.
예를 들어서 Column 위젯이 있다고 가정할떄, mainAxisAlignment 파라미터를 선택적으로 사용한다.
실제 Column 위젯의 정의로 들어가보면, Flex 위젯을 상속하고 있다.
다시 Flex 위젯의 정의에 들어가보면, mainAxisAlignment가 기본값을 가지고 있는 것을 볼 수 있다.
네임드 생성자
네임드 생성자는 클래스에 여러 생성자를 정의할 때 유용하다.
클래스 이름 뒤에 점(.)을 찍고 원하는 이름을 붙여 정의한다.
클래스 선언:
클래스 사용:
이 예제에서:
- Idol.namedConstructor는 String, int데이터로부터 Idol 객체를 생성하는 네임드 생성자이다.
- 이를 통해 다양한 형태의 데이터로부터 객체를 생성할 수 있는 유연성을 제공한다.
const 생성자와 팩토리 생성자
const 생성자
컴파일 타임 상수 객체를 생성할 때 사용한다.

팩토리 생성자
매번 새 인스턴스를 생성하지 않고, 캐시된 인스턴스를 반환하거나 하위 타입의 인스턴스를 반환해야 할 때 사용한다.
일반 생성자 vs Factory 생성자
먼저 일반 생성자와 factory 생성자의 차이점을 이해하는 것이 중요하다.
일반 생성자
- 새로운 인스턴스를 항상 생성한다.
- this 키워드를 사용할 수 있다.
- 생성자 본문이 실행되기 전에 인스턴스 변수가 초기화된다.
Factory 생성자
- 새로운 인스턴스를 반환할 수도 있고, 기존 인스턴스를 반환할 수도 있다.
- this 키워드를 사용할 수 없다.
- 생성자 내부에서 인스턴스 변수에 직접 접근할 수 없다.
- return 문을 사용해야 한다.
Factory 생성자의 장점
- 객체 캐싱: 동일한 객체의 여러 인스턴스가 필요하지 않을 때 유용하다.
- 서브클래스 인스턴스 반환: 인터페이스를 구현하는 구체적인 클래스의 인스턴스를 반환할 수 있다.
- 복잡한 초기화 로직: 객체 생성 전에 복잡한 로직을 실행할 수 있다.
- 싱글톤 패턴 구현: 클래스의 단일 인스턴스만 생성하고 싶을 때 사용한다.
Factory 생성자 사용 예시
간단한 예시를 통해 factory 생성자의 사용법을 알아보겠다.
1. class Circle:
- 원을 나타내는 클래스를 정의한다.
- radius라는 한 개의 final 속성을 가진다.
2. Circle(this.radius);
- 생성자는 클래스의 인스턴스를 생성할 때 호출된다.
- this.radius는 생성자 매개변수로 전달된 값을 radius 변수에 할당한다.
- radius 변수는 생성자를 통해 초기화되어야 하므로, 이 생성자가 필요합니다.
3. factory Circle.fromDiameter(double diameter) { return Circle(diameter / 2); }
- Factory 생성자 내부에서 실제 객체 생성을 수행한다.
- Factory 생성자는 특별한 유형의 생성자로, 객체를 생성하는 로직을 커스터마이징할 수 있다.
- diameter / 2를 통해 지름을 반으로 나누어 반지름을 계산합니다.
- fromDiameter는 지름을 입력받아 반지름을 계산한 후 Circle 인스턴스를 반환한다.
- Factory 생성자는 반드시 해당 클래스의 인스턴스를 반환해야 한다.
5. double calculateArea() { return 3.14 * radius * radius;}
- 원의 넓이를 계산하는 메서드이다.
- calculateArea 메서드는 원의 면적을 계산하여 반환한다.
- π * r^2 공식을 사용하여 원의 넓이를 계산한다 (여기서는 π를 3.14로 계산).
6. main() 함수:
- Circle.fromDiameter(10)을 호출하여 지름이 10인 원을 생성한다.
- Factory 생성자가 호출되어 내부적으로 반지름이 5인 Circle 객체를 생성한다.
- 생성된 원의 반지름과 면적을 출력합니다.
이 예제에서 Factory 생성자의 주요 이점은 다음과 같다:
- 사용자가 원의 지름을 입력하더라도, 내부적으로는 반지름을 사용하여 객체를 생성한다.
- 객체 생성 과정에서 입력 값(지름)을 가공(반지름으로 변환)할 수 있다.
- 클래스의 public API를 단순화하면서도 내부적으로는 더 적절한 형태로 데이터를 저장할 수 있습니다.
Factory 생성자의 핵심은 객체 생성 과정을 커스터마이즈할 수 있다는 점이다.
이 예제에서는 사용자가 제공한 지름 값을 이용해 내부적으로는 반지름을 사용하는 객체를 생성하고 있다.
이는 Factory 생성자의 유연성을 잘 보여주는 간단한 예시이다.
'Dart > OOP' 카테고리의 다른 글
Dart 문법 OOP - 오버라이드 (0) | 2024.08.20 |
---|---|
Dart 문법 OOP - 상속 (0) | 2024.08.20 |
Dart 문법 OOP - 게터와 세터 (0) | 2024.08.20 |
Dart 문법 OOP - private 변수 (0) | 2024.08.20 |
Dart 문법 OOP - 클래스와 인스턴스 (0) | 2024.08.20 |

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!