나의 수업일지

인천 일보 아카데미 10일차 확장_상속자_오버라이딩 / 추상화

GUPING 2023. 3. 7. 20:41
  • 확장을_알아보자
package day10;

public class FruitMain {

> 하나의 class에 새로운 Class를 생성하는것을 확장이라고 합니다
> 예시문을 살펴보며 알아보겠습니다

> extends Fruit 는 Fruit Class를 상속 받는다는 말이다
> 그렇기 때문에 Class 안에 필드와 메소드가 없어도 Fruit에 있는 필드와 메소드를 사용 가능
> 하지만 반대로 상속해주는 Class는 상속 받는 Class의 필드와 메소드를 마음대로 가져와 사용할 수 없다

class Fruit{
    String name;
    boolean isSeed;
    public void remobeSeed() {
        isSeed = false;
    }
}

class Fruit2 extends Fruit{ 
    String color;            

    public void colorChange(String color) {
        this.color = color;
    }
}

> 아래 실행 예시문을 살펴보면
> Fruit2를 f2로 지정하고 가져와 사용할 수 있게하였다
> Fruit2의 필드에는 color하나 뿐이지만 Fruit를 상속받아 필드와 메소드를 사용 할 수 있기 떄문에
> 필드에 name과 isSeed가 없어도 저장하고 실행할 수 있는 모습이다

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Fruit f = new Fruit();
        f.name = "사과";
        f.isSeed = true;
        f.remobeSeed();

        System.out.println(f.name+"/"+f.isSeed);
        Fruit2 f2 = new Fruit2();
        f2.color = "빨강";
        f2.name = "사과";
        f2.isSeed = true;

        f2.remobeSeed();

        System.out.println(f2.name+"/"+f2.isSeed+"/"+f2.color);
    }

}

 

  • 확장_상속을_알아보자
> 위에서 알아봤던 상속을 한번 더 자세히 알아보는 시간이다
> 아래의 예시문을 살펴보자

> class Tv를 class Tv2에 상속한모습
> 그렇기에 Tv2에서도 Tv에 있는 필드와 메소드가 사용 가능하다

class Tv{
    boolean power;
    int channel;

    public void power() {
        this.power = !power;
    }

    public void channelUp() {
        this.channel++;
    }
    public void channelDown() {
        this.channel--;
    }
}

class Tv2 extends Tv{
    int volum;

    public void volumUp() {
        this.volum++;
    }

    public void volumDown() {
        this.volum--;
    }
}


>상속 받은 class Tv2를 사용해보고 실행해보며 좀 더 자세하게 알아보기 위한 예시
package day10;

public class TvMain {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Tv2 tv2 = new Tv2();
        tv2.power = true;
        tv2.channel = 10;
        tv2.volum = 20;
        tv2.power();
        tv2.channelUp();
        tv2.channelUp();
        tv2.volumDown();
        tv2.volumDown();;

        System.out.println(tv2.power+"/"+tv2.channel+"/"+tv2.volum);}
	> 분명 tv2에는 volum만 있지만 나머지 필드를 상속 받아 저장하고 메소드도 잘 실행되는 모습
        > 하지만 상속을 해준 class Tv는 Tv2를 가져와 사용할 수 없다

}

 

  • 상속_좀 더_알아보기
> 좀 더 복잡한 class를 만들고 상속을 알아보며
> 메소드 안에 메소드를 넣어 사용하는 방법을 알아보자

class Person {
    String name;
    int age;
    boolean isFull;

    public Person() {

    }

    public Person(String name) {
        this.name = name;
    }

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public Person(String name, int age, boolean isFull) {
        this(name, age); 
        > 생성자에서 생성자를 불러와 사용하는것 이렇게 작성하는 경우 3번의 생성자를 생행하고 isFull을 실행
        this.isFull = isFull;
//        Student s = new Student("홍길동", 99 , fasle , "S100"));
    }

}

class Student extends Person {
    String sno;

    public Student() {

    }

    public Student(String name, int age, boolean isFull, String sno) {
        super(name, age, isFull);
        > super는 자신의 부모를 의미함 Student는 Person을 상속 받았기에 super로 사용 가능
        this.sno = sno;
        > this는 자기 자신
    }

}

 

  • 예시문_확장_상속자_오버라이딩
> 상속으로 오버라이딩하는 방법을 알아보자

class Car {
    String color;
    String tire;
    int speed;

    public void run() {
        System.out.println("Car run메소드");
        this.speed++;
    }
}

class SportCar extends Car {
    String engine;

    public void run() {
        System.out.println("SportCar run메소드");
        this.speed += 2; 
        > 상속 받은 메소드를 자식이 재정의 하는것을 오버라이딩이라고 한다
        > 단 메소드의 선언법은 동일해야한다 
    }

    public void rue1() {
        System.out.println("SportCar rum1메소드");
        this.speed += 4;
        > 이렇게 메소드 선언법이 다르면 그냥 다른 메소드일 뿐이다
    }
}

 

  • 예시문_확장_오버라이딩
> 위에서 설명한것처럼 오버라이딩은
> 메소드의 선언법은 동일해야한다
> 오버라이딩은 안에있는 실행문을 재정의하는것을 말한다

public class AnimalMain {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Dog dog = new Dog();
        dog.cry();
        dog.eat();
        dog.drink();
        Cat cat = new Cat();
        cat.cry();
        cat.eat();
        cat.drink();
    }

}

> class를 살펴보면 Animal클래스를 각 dog ,cat class에 상속하였다
> 각 클래스에서 겹치는 메소드는 cry이고
> Animal class의 cry메소드에는 "동물이 운다"를 출력하게하였다
> 하지만 각 dog ,cat class에서 오버라이딩을 이용하여 재정의 하였기 때문에
> 실행문에서는 새로 정의한 "멍멍" , "냥냥"이 출력되는 것을 확인 할 수 있다
class Animal{

    public void eat() {
        System.out.println("동물이 먹다");
    }
    public void cry() {
        System.out.println("동물이 운다");
    }
}

class Dog extends Animal{
    public void cry() {
        System.out.println("멍멍");
    }
    public void drink() {
        System.out.println("강아지가 마신다");
    }

}
class Cat extends Animal{
    public void cry() {
        System.out.println("냥냥");
    }
    public void drink() {
        System.out.println("고양이가 마신다");
    }
}

 

  • 추상메소드_추상class
> 추상화란?
> 여러 클래스에 중복되는 메소드나 필드를 한곳에 몰아 넣고 나누어 쓰는걸 추상화라고한다

public abstract class Animal {
    > abstract : class 안에 추상 메소드가 하나라도 존재하면 추상 class라고 한다
    > 그렇기 때문에 앞에 abstract를 붙여준 모습이다

    private String name;

    public Animal() {

    }

    public Animal(String name) {
        this.name = name;
    }

    public abstract void cry(); 
    > 접근제한자 뒤에 abstract를 붙여서 추상 메소드를 만들었다
    > 추상 메소드는 자식 메소드에서 무조건 오버라이딩을 해주어야한다
    
    > 추상메소드 특징 : 입장 제한자 뒤에abstract이 있음 , 중괄호가 없다

}
==============================================================================================

 

  • adstract_예시문
package day10_1;

public abstract class Salary {
> class안에 추상 class가 있다면 abstract를 붙여 추상 class로 만들어주여야한다
    int salary;

    public abstract void tax();
    > Salary class를 만들고 tax라는 추상 class를 만들었다
}
======================================================================== 추상 class
class 정규직 extends Salary {
    public void tax() {
        double tax = salary * 0.1;
        System.out.println("정규직 세금은 :"+tax);
    }
}

class 계약직 extends Salary {
    public void tax() {
        double tax = salary * 0.033;
        System.out.println("계약직 세금은 :"+tax);
    }
}
> 추상 class를 상속받은 메소드들은 꼭 사용할때 오버라이딩을 해주어야한다
> abstract는 제외하고 메소드의 선언법을 같게 작성하여 실행문을 넣어주었다
======================================================================== 상속받은 class
>아래는 추상 class를 상속받은 class들의 메소드 사용 예시문이다
package day10_1;

public class SalaryMain {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        정규직 a = new 정규직();
        계약직 b = new 계약직();
        a.salary = 2000000; < 상속 받았기 때문에 필드에 salary 변수가 없지만 사용가능
        a.tax(); < 추상 메소드 실행문을 넣어주었기 때문에 실행가능
        b.salary = 1500000;
        b.tax();

    }

}

 

  • 지금까지 배운 내용들을 이용하여 만들어보기 _ 읽어보기 _  저장용
package day10_2;

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

public class Main {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Scanner sc = new Scanner(System.in);
		List<Student> sList = new ArrayList<>();
		List<Teacher> tList = new ArrayList<>();
		boolean run = true;

		while (true) {
			System.out.println("====학교종이땡땡땡====");
			System.out.println("1.학생 2.강사");
			System.out.print("메뉴 선택 >");
			int menu = sc.nextInt();

			if (menu == 1) {
				while (true) {
					System.out.println("1.학생등록 2.학생리스트 3.학생조회 0.뒤로가기");
					System.out.print("메뉴 선택 >");
					menu = sc.nextInt();
					if (menu == 1) {
						Student student = new Student();
						System.out.print("이름 >");
						student.setName(sc.next());
						System.out.print("성별(1.남자 2.여자) >");
						int num = sc.nextInt();
						if (!(num == 1 || num == 2)) {
							System.out.println("없는 성별입니다");
							continue;
						}
						char gender = (num == 1) ? 'M' : 'F'; // 삼항연사자 조건을 넣으면 대입할때 사용
						student.setGender(gender);
						System.out.print("생년월일 >");
						student.setBirthday(sc.next());
						student.setId();
						System.out.print("퍙균 >");
						student.setAvg(sc.nextDouble());
						System.out.print("학과 >");
						student.setDept(sc.next());

						if (tList.size() == 0) {
							System.out.println("선택가능한 지도교수가 없습니다");
						} else {
							System.out.println("----------1----------");
							for (int i = 0; i < tList.size(); i++) {
								System.out.println((i + 1) + "\t" + tList.get(i).getName());
							}
							System.out.println("--------------------");
							System.out.println("지도 교수 >");
							int tNum = sc.nextInt();
							student.setTname(tList.get(tNum - 1).getName());
							tList.get(tNum-1).setStudentCnt();
							tList.get(tNum-1).setSalary();
						}
						sList.add(student);
						System.out.println("학생등록 완료!");
					} else if (menu == 2) {
						System.out.printf("주민번호\t\t이름\t성별\t생년월일\t학번\t지도교수\t평균\t학과\n");
						System.out.println("-----------------------------------------------------------");
						for(Student s : sList) {
							s.print();
						}
					} else if (menu == 3) {

					} else if (menu == 0) {
						break;
					}
				}
			} else if (menu == 2) {
				while (true) {
					System.out.println("1.강사등록 2.강사리스트 3.강사조회 0.뒤로가기");
					menu = sc.nextInt();
					if (menu == 1) {
						Teacher teacher = new Teacher();
						System.out.print("이름 >");
						teacher.setName(sc.next());
						System.out.print("성별(1.남자 2.여자) >");
						int num = sc.nextInt();
						if (!(num == 1 || num == 2)) {
							System.out.println("없는 성별입니다");
							continue;
						}
						char gender = (num == 1) ? 'M' : 'F'; // 삼항연사자 조건을 넣으면 대입할때 사용
						teacher.setGender(gender);
						System.out.print("생년월일 >");
						teacher.setBirthday(sc.next());
						teacher.setId();
						tList.add(teacher);
						System.out.println("강사등록 완료!");
						
					} else if (menu == 2) {
						System.out.printf("주민번호\t\t이름\t성별\t생년월일\t강사번호\t월급\n");
						System.out.println("-----------------------------------------------------------");
						for(Teacher t : tList) {
							t.print();
						}
					} else if (menu == 3) {
						System.out.println("강사번호 >");
						String tno = sc.next();
						for(Teacher t : tList) {
							if(tno.equals(t.getTname())) {
								for(Student s : sList) {
									if(s.getTname().equals(t.getName())) {
										System.out.println(s.getName());
									}
								}
							}
						}

					} else if (menu == 0) {
						break;
					}
				}
			}
		}
	}
}