void main() {
// 부모클래스 상속받기
print('========mom========');
Person mom = Person(name: '엄마');
mom.speak();
mom.walk();
// 자식Hero은 부모Person의 변수,함수도 접근 가능
print('========child========');
Hero child = Hero('자식');
child.speak();
child.walk();
child.fly(); // 부모(Person)은 접근못함
// 부모Person은 자식Hero의 변수,함수접근 못함
// 만들어진 인스턴스는 자식Hero이지만, child2의 객체타입은 부모Person이기 때문에
// child2.fly()는 못씀
// 하지만 walk는 자식이 만든 '뛴다'로 실행됨 왜냐면,
// 인스턴스 자식Hero를 child2에 받았기 떄문에 override된 walk이 출력되고, 부모클래스에 정의 돼있던건 무효화시키고 자식Hero클래스에서 재정의한 함수로 호출이됨.
print('========child2========');
Person child2 = Hero('자식2222');
child2.speak();
child2.walk();
print('=======speakName=====');
speakName(mom);
speakName(child);
speakName(child2);
// speakName(Bora());
}
// 상속은 같은 타입을 묶는 개념으로도 많이쓰임
void speakName(Person person) {
print('이름 : ${person.name}');
}
class Bora extends Person {
Bora() : super(name: '보라');
}
// 부모클래스로 부터 상속받기
// 상속을 받으면 부모의 변수와 함수 사용가능
class Hero extends Person {
// super(name)는 부모 클래스 Person의 생성자 name을 따라감
// Hero생성자는 name값을 전달 받으면 Person의 name을 사용할 수 있음
Hero(String name) : super(name: name);
// 위랑 같음
// Hero(String name) {
// super.name = name;
// }
// 자식만의 고유한 함수를 만들어 사용가능, 부모(Person)은 접근못함
void fly() {
print('$name, 날다. (자식 클래쓰)');
}
// 부모랑 같은 함수의 이름을 쓸때는?? (@override 사용)
// 자식함수로 다시 재정의 시키는것(즉, 덮어쓰기)
@override
void walk() {
// print('-----walk-----');
// super.walk();
print('$name, 뛴다. (자식 클래쓰)');
// print('-----walk-----');
}
}
class Person {
Person({required this.name});
String? name;
void speak() {
print('안녕 나는 $name 입니다. (부모 클래쓰)');
}
void walk() {
print('$name은(는) 걷는중이다. (부모 클래쓰)');
}
}