1. 상속(inheritance)
1) 새로운 클래스를 선언할 때
기존에 사용중이던 클래스의 필드에서 가져오고 싶은 필드가
있다면 상속을 받는다.
2) 여러 클래스를 만들 때 공통요소들을 먼저 묶고
부모 클래스를 선언한 후 상속해준다.
2. 생성자
: 자식 생성자를 호출했을 때 자식 필드만 메모리에 할당된다면,
자식 객체는 절대 부모 필드에 접근할 수 없다.
따라서, 자식 생성자 호출시 부모 생성자가 먼저 호출되고
그 다음 자식 생성자가 호출 된다. 코드에서는
부모 생성자 호출 시 super()로 작성한다.
생략이 가능하고, 생략시 컴파일러가 자동으로 호출해준다.
3. 다형성(Polymorphism)
1) 오버로딩(Overloading)
2) 재정의(Overriding)
: 부모의 메소드 중 수정하고자 하는 것이 있다면 자식 필드내에서
부모의 메소드와 똑같은 이름으로 선언한다.
부모 생성자가 먼저 호출되기 때문에 부모의 메소드가 메모리에
먼저 올라가고, 자식 생성자 호출 시 메모리에 같은 이름의
메소드가 있다면 또 만들어지는 것이 아니라,
기존의 부모 필드의 메소드에 자식에서 재정의한 코드값이
덮어 씌워진다. 따라서 자식 객체로 이 메소드에 접근하면
재정의한 기능으로 실행된다.
4. 상속 방법
class A{
A필드
}
class B extends A{
A, B필드
}
[일반회사/ 외국회사/ 국가기반산하기관 혹은 참고문언/ 논문]
A : 부모 클래스, 슈퍼 클래스, 상위 클래스, 기반 클래스
B : 자식 클래스, 서브 클래스, 하위 클래스, 파생 클래스
5. 다중 상속은 모호성 때문에 지원하지 않는다.
(jdk1.8버전부터는 사실상 다중 상속이 지원이 된다.)
6. 오늘 실습코드
1) 모여라 셀럽동물
** Animal 클래스 **
package day21;
//모여라 셀럽동물!(유아용 게임)
//동물(캐릭터)은 여러마리
import java.util.Random;
import java.util.Scanner;
//이름, 먹이 종류, 먹이 개수, 체력
//생성자 만들기(기본 생성자도 선언)
//먹기 : 먹이갯수 1감소 체력 1증가
//자기 : 3초당 체력 1씩 증가
//산책하기 : 랜덤한 퀴즈 맞추면 체력 2증가, 틀리면 체력 1감소, 무조건 체력은 1감소
public class Animal {
String name;
String feed;
int feed_cnt;
int hp;
public Animal() {}
public Animal(String name, String feed, int feed_cnt, int hp) {
super();
this.name = name;
this.feed = feed;
this.feed_cnt = feed_cnt;
this.hp = hp;
}
//먹기
void eat() {
if(feed_cnt != 0) {
feed_cnt --;
hp ++;
System.out.println(name + "이(가) " + feed + "을(를) 먹는 중...");
System.out.println("현재 체력 : " + hp);
System.out.println("먹이 갯수 : " + feed_cnt);
}else {
System.out.println(name + " 먹이가 없어요~ 산책하고 오세요!!");
}
}
//자기
void sleep() {
System.out.print("자는중");
for (int i = 0; i < 3; i++) {
System.out.print(".");
try {Thread.sleep(1000);} catch (InterruptedException e) {;}
}
hp ++;
System.out.println("현재 체력 : " + hp);
System.out.println();
}
//산책하기
void walk(String[] arQ, int[] arA) {
System.out.println("현재 체력 : " + hp);
if(hp > 1) {
hp--;
Random r = new Random();
Scanner sc = new Scanner(System.in);
int idx = r.nextInt(arQ.length);
int choice = 0;
System.out.println(arQ[idx]);
choice = sc.nextInt();
if(choice == arA[idx]) {
System.out.println("와~ 잘했어요! 정답!");
feed_cnt += 2;
}else {
System.out.println("아쉬워요! 다시 한번 도전 해보세요!");
hp--;
if(hp == 0) {
System.out.println(name + " 회복중!!");
sleep();
}
}
}else {
System.out.println("체력이 부족해요!! 잠을 자고 오세요!");
}
}
}
** Zoo 메인 클래스 **
package day21;
import java.util.Random;
import java.util.Scanner;
public class Zoo {
public static void main(String[] args) {
Animal dog = new Animal("멍멍이", "뼈다귀", 5, 5);
Animal penguin = new Animal("펭수", "생선", 7, 3);
Animal pig = new Animal("꿀꿀이", "감자", 9, 1);
//클래스 배열
//각 방에 객체가 있다. 따라서 한 번 접근해도 필드의 주소값이다.
//클래스명[] 배열명 = {new 생성자(), new 생성자(),....};
Animal[] arAnimal = {dog, penguin, pig};
String[] arQ = {"Q.다음 중 나무가 아닌 것은?\n"
+ "1.은행나무\n2.단풍나무\n3.우유\n4.소나무\n",
"Q.다음 중 착한 일을 한 친구는 누굴까요?\n"
+ "1.철수 : 동생이 말을 안들어서 때렸어요.\n"
+ "2.영희 : 엄마 설거지를 도와 드렸어요\n"
+ "3.민수 : 사탕을 먹었는데 안 먹었다고 했어요.\n"
+ "4.수영 : 친구 장난감을 훔쳤어요.",
"Q.빵이 3개가 있었어요.\n 철수가 빵을 한 개 먹었어요.\n"
+ "남은 빵은 몇 개 일까요?\n"
+ "1.2개\n2.3개\n3.4개\n4.9000개"
};
int[] arA = {3, 2, 1};
int choice = 0, menu_choice = 0;
Scanner sc = new Scanner(System.in);
while(true) {
System.out.println("[모여라 셀럽 동물!]");
System.out.println("캐릭터를 선택하세요!");
System.out.println("1.강아지\n2.펭귄\n3.돼지\n4.나가기");
//선택한 캐릭터 번호 - 1은 arAnimal의 인덱스 번호로 사용된다.
choice = sc.nextInt();
if(choice == 4) {break;}
//사용자가 선택한 번호는 1부터 시작하기 때문에 -1을 해준다.
choice--;
while(true) {
System.out.println("1.밥먹기\n2.산책하기\n3.잠자기\n4.캐릭터 선택하기");
//choice를 재사용하면 어떤 캐릭터를 선택했는지 알 수 없기 때문에
//새로운 변수를 선언하고 사용한다.
menu_choice = sc.nextInt();
if(menu_choice == 4) {break;}
switch (menu_choice) {
case 1:
//사용자가 선택한 choice-1번째 방의 동물(객체)로 필드에 접근한다.
arAnimal[choice].eat();
break;
case 2:
arAnimal[choice].walk(arQ, arA);
break;
case 3:
arAnimal[choice].sleep();
break;
}
}
}
}
}
2) InheritanceTest
package day21;
class A{
//인스턴스 변수, 객체화를 해야 사용 가능
int data;
//클래스변수, 클래스로 접근해서 사용 가능
static int num;
public A() {
System.out.println("부모 생성자 호출");
}
void printData() {
System.out.println(data);
}
void intro() {
System.out.println("A 클래스");
}
}
class B extends A {
String name;
public B() {
//무조건 부모 클래스 먼저 호출해야 함
//생략하면 맨 위에 super가 생략되어 있다고 보면 됨
//부모 먼저 호출해야하기 때문에 맨 앞에 작성해줘야 함
A.num = 20;
data = 100;
System.out.println("자식 생성자 호출");
}
//재정의
@Override
void intro() {
//super.intro(); 가 있으면 기존에 A클래스에 정의된 메소드 정보와
//함께 새롭게 정의한 정보 추가(즉, 추가하기)
//super.intro(); 를 삭제하면 A클래스에 정의된 메소드 정보가
//삭제되고 재정의(즉, 덮어쓰기)
super.intro();
System.out.println("B 클래스");
}
}
public class InheritanceTest {
public static void main(String[] args) {
B obj = new B(); //부모생성자가 먼저 호출된 다음에 자식 생성자가 호출된다는 증거
obj.intro(); //부모생성자가 먼저 호출된 다음에 자식 생성자가 호출된다는 증거
obj.printData();
}
}
** 자식생성자보다 부모생성자가 먼저 올라간다
그렇기 때문에 무조건 부모 클래스 먼저 호출해야 하는데
이 때, super를 맨 뒤에 작성하면 에러가 발생함
3) Road
package day21;
class Car{
String brand;
String color;
int price;
public Car() {}
public Car(String brand, String color, int price) {
super();
this.brand = brand;
this.color = color;
this.price = price;
}
void engineStart() {
System.out.println("열쇠로 시동 킴");
}
void engineStop() {
System.out.println("열쇠로 시동 끔");
}
}
class SuperCar extends Car{
String mode;
// //자식클래스 생성자 생성할때
// //부모클래스의 있는 매개변수를 자식클래스의 매개변수로 사용할 수 있음
// public SuperCar(String brand, String color, int price, String mode) {
// super(brand, color, price);
// this.mode = mode;
// }
}
public class Road {
}
7. 단축키
** 메소드 이름 일부 쓰고 Ctrl + Space : 재정의
** Alt + Shift + S + O : 자식클래스의 생성자 만들때
부모클래스의 생성자를 통해 부모클래스에 있는 생성자의 매개변수를 사용할 수 있음
'웹_프론트_백엔드 > 단과' 카테고리의 다른 글
[단과_C] 2020.02.13 (0) | 2020.02.14 |
---|---|
[단과_JAVA] 2020.02.13 (0) | 2020.02.14 |
[단과_JAVA] 2020.02.11 (0) | 2020.02.12 |
[단과_JAVA] 2020.02.10 (0) | 2020.02.11 |
[단과_JAVA] 2020.02.07 (0) | 2020.02.10 |