Flutter앱 유지보수 1년 간 해보기 프로젝트 -12(Dart 추상화, 캡슐화, 접근지정자, Recode, Destructing)

박경현·2023년 12월 4일
0

처음 Dart언어 봤을때는 그냥 자바나 C++같다고 생각했는데 여기에 JS 스타일이 점점 추가되고 있었다

이번 3.0버전에 등장한 Record와 Destructing은 JS에 있을법한 스타일이라서 꽤나 유용하면서 신기한 스타일이라 적어봤다

객체지향의 특징 - 캡슐화와 정보은닉

공부하면서 본 내용에서 캡슐화를 이렇게 설명했다

캡슐화 - 어떤 객체가 목적을 수행하기 위해 데이터(변수)와 기능(함수)을 적절히 모은 것

정보은닉 - 클래스 내부 정보를 함부로 공개하지 않는 것
변수는 private로, getter,setter로 불러오고 데이터 삽입을 해주면 된다

class Person2 {
	String _name;
    String get getName() {
    	return (_name != null) ? _name : 'Lee';
    }
    String set setName(String name) {
    	return (name != null) ? _name = name : _name = 'Park';
    }
 }

void main() {
	Person2 p2 = Person2();
}

객체지향의 특징 - 추상화와 추상클래스

추상화 - 어떤 객체들의 공통된 데이터와 메서드를 묶어서 이름(클래스명)을 부여하는 것,
중복된 부분을 많이 없앨 수 있고 코드 재사용률을 높인다

이런 추상화를 사용하기 위해서는 추상클래스를 사용하면 된다!

추상클래스의 특징
추상 메서드를 상속 받으면 무조건 내부 정의해줘야한다
일반 메서드도 상속 받아서 재정의 해줘야한다
일반 클래스는 extends로 상속, 추상클래스는 implements로 여러개 상속 가능하다!
추상클래스는 앞에 abstract가 붙는다

abstract class Person {
	eat();
    sleep() { print('sleep');}
}
abstract class Junior {
	work() { print('work');}
}
class Developer implements Person, Junior {
	@override
    eat() {
    	print('Developer eat a meal');
    }
    sleep() {print('Developer sleep');}
    work() {print('work');}
}
void main() {
	Developer p = Developer();
    p.eat();
    p.work();
}

Record 와 Destructing

이제부터는 다트3.0버전에 새로 들어온 신기술들인데 JS에서 본 적 있는(?) 애들이긴 하다
엄청난건 아니지만 정확하게 표현하게 도와주고 훨씬 편하게 코딩하도록 도와준다

Record는 순서랑 타입을 보장해준다가 핵심이다!
정확하게 그 타입으로 반환해야한다!
대신 반환시 튜플로 반환되긴 함! 이건 어쩔 수 없다!

main() {
	final result = nameAndAge({
    'name': '민지',
    'age': 20,
  });
  print(result);
  print(result.$1); // result[0] 처럼 튜플에서 이렇게 사용
  // 지금은 String관련 메서드가 나옴!
  print("--------");
  final result3 = getNewJeansWithType();
  for(final item in result3) {
    print(item.$1);
    print(item.$2);
  }
  print("--------");
  final result4 = getNewJeansWithType2();
  for(final item in result4) {
    print(item.$1);
    print(item.$2);
  }
  print("--------");
  final result5 = getNewJeansWithType3();
  for(final item in result5) {
    print(item.name);
    print(item.age);
  }
}

// 이름과 나이를 맵에서 추출하기
// 이게 Record다! -> 순서랑 타입을 보장!!
(String, int) nameAndAge(Map<String,dynamic> json) {
  // 이렇게 적으면 동시에 반환 되면서 리스트로 반환
  // 타입에 대한 보장을 못받음 -> 
  // 순서와 타입 동시에 보장받고 싶다!
  //return [json['name'], json['age']];
  return (json['name'] as String, json['age'] as int);
}

List<Map<String, dynamic>> getNewJeans() {
  return [
    {
      'name': '민지',
      'age' : 20,
    },
    {
      'name': '혜린',
      'age' : 18,
    }
  ];
}
List<(String, int)> getNewJeansWithType() {
  return [
    (
      '민지',
       20,
    ),
    (
     '혜린',
      18,
    )
  ];
}

List<(String name, int age)> getNewJeansWithType2() {
  return [
    (
      '민지',
       20,
    ),
    (
     '혜린',
      18,
    )
  ];
}

List<({String name, int age})> getNewJeansWithType3() {
  return [
    (
      name: '민지',
      age: 20,
    ),
    (
     name: '혜린',
     age: 18,
    )
  ];
}

///////////////

void main() {
  //final minji = ('민지', 20);
  // print(minji.$1);
  final (name, age) = ('민지', 20);
  print(name);
  print(age);
  
  // 다른 타입들 넣으니까 오류 남! 
  final newJeans = ['민지', '혜린'];
  final [String a, String b] = newJeans;
  print(a);
  print(newJeans);
  
  final numbers = [1,2,3,4,5,6,7,8];
  final [x, _ ,y, ...rest ,z, aa] = numbers;
  print(x);
  print(y);
  print(z); // ...실행 시 맨 뒤 제외 중간 버림
  print(rest); // _가 있으면 그 부분 제외함
}
// 값을 분해한 상태에서 받아오기
// 레코드를 결국 하나하나 저장해서 쓰게 될거임
// 그래서 분해가 가능하면 좋다 destructing

profile
SW로 문제를 해결하려는 열정만 있는 대학생

0개의 댓글