Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
Tags
- Flutter
- Json Serializable
- Flutter code generator
- 네이티브 VS 크로스플랫폼
- flutter tutorial
- 햄스터
- Riverpod
- flutter tutorial coach mark
- flutter 2.8
- 영화리뷰
- 햄스터케이지
- gorouter
- 플러터 2.8
- 플러터 튜토리얼 플러그인
- 플러터
- Class Modifier
- Flutter textstyle
- Flutter variablefont
- Flutter Freezed
- 햄스터 사막모래
- Flutter Json
- 햄쨩일기
- 햄스터사육장
- Indexed Stack
- VariableFont
- 햄쨩
- opentype-font
- 뒤로가기 버튼
- 햄스터 계란
- 골든햄스터
Archives
- Today
- Total
통조림
[Dart] 클래스 Modifier 본문
코드 깃허브
https://github.com/KoreanTuna/Dart-Class-Modifier
참고
https://dart.dev/language/class-modifiers
extends와 implements
- Dart는 Java와 다르게, 일반 클래스도 implements할 수 있다.
- extends도 메소드 override가능, implements도 override가능.
그렇다면 Dart에서 2개의 차이는?
- extends는 부모의 변수와 메소드에 접근 가능. 구현없이도 메소드 사용 가능
- implements는 모든 변수와 메소드를 override해서 구현 해야한다, 다중상속 가능
Class Modifier
💡 Class modifiers control how a class or mixin can be used, both from within its own library, and from outside of the library where it's defined.Class Modifier는 라이브러리 내부 클래스 혹은 외부에서 해당 클래스를 사용할 수 있는 방법을 제한하는데 사용된다.
- final class
- mixin class (그냥 mixin과 다름)
- base class
- abstract class
- sealed class
- interface class
base class
- base 클래스를 구현하거나 확장하는 모든 클래스는base,final,sealed 로 표시해야 한다.
- 외부 라이브러리에서는 implements할 수 없다.
- == 다중상속 받는 with에 base class를 추가할 수 없다.
So, 외부 클래스에서 base 클래스가 보장하는 것들을 위반하는 것을 방지할 수 있다.
ex) 내부 라이브러리에서 제작한 기능 그대로만 사용하고, 기능을 변경시키거나 수정하지 못하도록 하기 위해.
// Library a
base class Vehicle {
...
}
// Error: base class는 base, final ,sealed만 상속 가능
class ProtoVehicle extends Vehicle{
...
}
// No Error : 내부 라이브러리 안에서는 base도 구현 가능
base class PostVegicle implements Vehicle{
...
}
// Library b
// 문제없음
base class Car extends Vehicle {
...
}
// Error : 외부 라이브러리에서 구현 불가능
base class Car implements Vegicle{
...
}
base class가 필요한 반례
class A {
void _privateMethod() {
print('I inherited from A');
}
}
void callPrivateMethod(A a) {
a._privateMethod();
}
import 'a.dart';
class B implements A {
// No implementation of _privateMethod()!
}
main() {
callPrivateMethod(B()); // Runtime exception!
}
final class
- base 클래스를 구현하거나 확장하는 모든 클래스는base,final,sealed 로 표시해야 한다.
- final class는 외부 라이브러리에서는 상속할 수 없다.
- final은 base의 기능을 포함한다.
// Library a
final class Vehicle {
...
}
// 내부 라이브러리에서 확장이라 문제없음
final class ProtoVehicle extends Vehicle{
}
// Library b
// Error : 외부 라이브러리에서 확장 불가능
final class Car extends Vehicle {
...
}
// Error : 외부 라이브러리에서 구현 불가능
final class Car implements Vehicle {
...
}
abstract Interface class
- Java에서 사용되는 interface와 거의 동일하게 사용할 수 있도록 하는 제어자.
- 외부 라이브러리에서는 확장은 불가능하고 구현만 가능.
- 생성 불가능
// Library a
abstract interface class Fish {
void makeSound();
abstract int size;
}
// Library b
// Error 발생
class Bass extends Fish{
}
class Shark implements Fish {
Shark(this.size);
@override
void makeSound() {
print('Shark makes sound');
}
@override
int size;
}
sealed class
- 암묵적으로 abstract 기능을 포함한다.
- 자식 클래스들은 abstract하지 않다.
- 외부 라이브러리에서 생성되거나 확장되거나 구현하지 못한다.
- 생성 불가능
- enum처럼 사용할 수 있다.
- exhausitive한 속성을 적극적으로 활용하는 것을 권장하고 있음
sealed class Vehicle {}
class Car extends Vehicle {}
class Truck implements Vehicle {}
class Bicycle extends Vehicle {}
// ERROR: Cannot be instantiated
Vehicle myVehicle = Vehicle();
// Subclasses can be instantiated
Vehicle myCar = Car();
String getVehicleSoundWithError(Vehicle vehicle) {
// ERROR: The switch is missing the Bicycle subtype or a default case.
return switch (vehicle) {
Car() => 'vroom',
Truck() => 'VROOOOMM',
};
}
String getVehicleSound(Vehicle vehicle) {
// No Error
return switch (vehicle) {
Car() => 'vroom',
Truck() => 'VROOOOMM',
Bicycle() => 'ring ring',
};
}
.
.
sealed class 사용해보기
깃허브에는 package 형태로 class modifier를 사용해서 API를 호출하는 단에서 어떻게 활용할 수 있는지 고민해봤다.
라이브러리 단에서 sealed class로 부모 클래스를 선언한다.
sealed class BettherCalendarCase {
final Color backgroundColor;
Future<void> showCalendar(
BuildContext context, {
required BettherCalendarConfig config,
});
BettherCalendarCase(this.backgroundColor);
}
.
.
.
.
자식 클래스들을 선언한다.
class RedCalendar implements BettherCalendarCase {
Future<void> showCalendar(BuildContext context, {required BettherCalendarConfig config}){
...
}
}
class YellowCalendar implements BettherCalendarCase {
Future<void> showCalendar(BuildContext context, {required BettherCalendarConfig config}){
...
}
}
class GreenCalendar implements BettherCalendarCase {
Future<void> showCalendar(BuildContext context, {required BettherCalendarConfig config}){
...
}
}
.
.
.
.
라이브러리 호출 코드
sealed class는 Exhaustiveness checking를 보장하기 때문에, Switch문에서 빠지는 자식 클래스 없이 케이스 검사가 가능하다. (빠져있는 자식클래스가 있다면 error가 발생한다)
class HomeScreen extends StatelessWidget {
const HomeScreen({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
body: SizedBox(
width: double.infinity,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
ElevatedButton(
onPressed: () async {
await getColorCanlendar(BlueCalendar(), context);
},
child: const Text('Show Calendar'),
),
const Text('Hello, world!'),
],
),
),
);
}
Future<void> getColorCanlendar(
BettherCalendarCase calendarCase, BuildContext context) async {
return switch (calendarCase) {
RedCalendar() => RedCalendar().showCalendar(context),
BlueCalendar() => BlueCalendar().showCalendar(context),
GreenCalendar() => GreenCalendar().showCalendar(context),
YellowCalendar() => YellowCalendar().showCalendar(context),
};
}
}
'Software > Flutter' 카테고리의 다른 글
[Flutter] IOS 앱 종료 기능 이슈 (0) | 2024.04.02 |
---|---|
[Flutter] Riverpod & Flutter hooks (1) - 기본적인 사용방법 (0) | 2024.04.02 |
[Flutter]GoRouter Redirection (0) | 2024.04.02 |
[Flutter] JsonSerializable & Freezed (0) | 2023.08.18 |
[Flutter]Variable Font (0) | 2023.08.18 |