본문 바로가기
학교 공부/자바

[JAVA] 자바 5번째 수업

by krapoi 2022. 4. 20.
반응형

오늘은(2022-04-20) 자바의 상속에 대해서 배웠다.

 

먼저 상속은 상속을 받은 자식 클래스에서 지정해야 한다.

 

먼저 부모 클래스부터 만들어 주자.

package d0420;

public class Parent {

	protected String name;
	
	public void sayhello() {
		System.out.println(name + "님 안녕하세요.");
	}
}

그다음 자식 클래스를 만들어 보자.

package d0420;

public class Child extends Parent{
	
	protected int age;
	
	public static void main(String[] args) {
		Child c = new Child();
	
	}
}

위 자식 클래스를 보면 extends를 볼 수 있는데 저걸 붙인 뒤 뒤에 부모 클래스 이름을 붙여주면 상속이 된다.

또한 자식 클래스는 부모 클래스에 있는 객체를 쓸 수 있다.

이때 부모는 자식 클래스에 있는 객체를 사용할 수 없다.

package d0420;

public class Child extends Parent{
	
	protected int age;
	
	public static void main(String[] args) {
		Child c = new Child();
	
		c.age = 18;	// O
		c.name = "영희";	//O
		c.sayhello();	//O
		
		Parent p = new Parent();
		
		p.age = 23;	//X
	}
}

이런 식이다.

 

이렇게 상속을 쓰다 보면 왜 상속을 쓰는지 궁금해진다.

이유를 알아보자면 재활용이 용이하다.

ctrl+c, ctrl+v를 쓰면 에러가 난다면 모두 바꿔야 한다.

하지만 상속을 했을 경우 부모 클래스 하나만 고치면 된다.

이러한 이유 때문에 사용한다고 한다.

 

이제 기본적인 상속에 대한 개념을 잡았으니 응용으로 넘어가자.

 

간단한 더하기 기능을 넣을 클래스 Adder를 만들어 주자.

package d0420;

import java.util.Scanner;

public class Adder {
	
	public static void main(String[] args) {
		Adder a = new Adder();
		a.execute();
	}

	protected final Scanner sc;
	
	public Adder() {
		this.sc = new Scanner(System.in);
	}
	
	public void execute() {
		Values v = inputValues();
		
		int result = calculate(v);
		
		showResult(v,result);
		
		sc.close();
	}
	
	public Values inputValues() {
		System.out.println("두 정수를 입력하세요.\n");
		String[] s = sc.nextLine().split(" ");
		Values v = new Values();
		v.setValue1(Integer.parseInt(s[0]));
		v.setValue2(Integer.parseInt(s[1]));

		return v;
			
	}
	
	public int calculate(Values v) {
		return v.getValue1() + v.getValue2();
	}
	
	public void showResult(Values v, int r) {
		System.out.printf("%d + %d = %d",v.value1,v.value2,r);
	}
	
	public class Values{
		private int value1;
		
		private int value2;
	
		public void setValue1(int value1) {
			this.value1 = value1;
		}
		
		public void setValue2(int value2) {
			this.value2 = value2;
		}
		
		public int getValue1() {
			return value1;
		}
		
		public int getValue2() {
			return value2;
		}
	}
	
	
}

밑에 내부 클래스는 따로 클래스를 빼기에는 이 클래스만 쓸 것 같아서 내부 클래스로 만들어 주었다.

 

이런 식으로 하게 되면 더하기 기능이 만들어진다.

그리고 이제 빼기 기능을 만들어 보자.

상속 기능을 이용해서 빼기만 연산하는 기능을 따로 만들어 줄 것이다.

 

package d0420;

public class Subtractor extends Adder{
	
	@Override
	public int calculate(Values v) {
		return v.getValue1() - v.getValue2();
	}
	
	@Override
	public void showResult(Values v, int r) {
		System.out.printf("%d - %d = %d",v.getValue1(),v.getValue2(),r);

	}
	
	public static void main(String[] args) {
		Subtractor s = new Subtractor();
		s.execute();
	}

}

이런 식으로 override를 사용해 상속한 부모의 메서드를 바꾸어 주었다.

그런데 showResult가 비슷한 부분이 너무 많다.

그렇니까 부모 클래스 Adder를 조금 바꿔주자.

public void showResult(Values v, int r) {
		System.out.printf("%d %s %d = %d",v.value1,getOperator(),v.value2,r);
	}
	
	public String getOperator() {
		return "+";
	}

getOperator를 추가해 주고, showResult의 pritf에 넣어주자.

 

그리고 자식을 바꿔주면 간단하게 된다.

package d0420;

public class Subtractor extends Adder{
	
	@Override
	public int calculate(Values v) {
		return v.getValue1() - v.getValue2();
	}
	
	@Override
	public String getOperator() {
		return "-";
	}
	
	public static void main(String[] args) {
		Subtractor s = new Subtractor();
		s.execute();
	}

}

이제 다른 예제를 들어보자.

Animal 클래스를 만들어 주자.

 

public class Animal {
	
	public void move() {
		System.out.println("움직입니다.");
	}
	
	public void eat(String food) {
		System.out.println(food + "을 먹습니다.");
	}
	
	public void birth() {
		System.out.println("새끼를 놓습니다.");
	}
}

그리고 이 Animal을 상속할 자식 클래스 Dog와 Bird를 만들어 주자.

 

Dog

package d0420;

public class Dog extends Animal{

	public void bark() {
		System.out.println("멍멍");
	}
	
	public void birth() {
		System.out.println("귀여운 강아지를 여러 마리 놓습니다.");
	}
	
}

 

Bird

package d0420;

public class Bird extends Animal{

	public void fly() {
		System.out.println("하늘을 납니다.");
	}
}

 

이제부터 조금 어려운 내용일 수 도 있다.

Animal에 main을 만들어 주자.

package d0420;

public class Animal {
	
	public void move() {
		System.out.println("움직입니다.");
	}
	
	public void eat(String food) {
		System.out.println(food + "을 먹습니다.");
	}
	
	public void birth() {
		System.out.println("새끼를 놓습니다.");
	}

	public static void main(String[] args) {
		Dog a = new Dog();
		a.birth(); //Dog의 birth
		a.bark();

		Animal d = new Dog(); //자식은 부모의 이름으로 인스턴스 가능
		d.birth(); //Animal birth
		
		//Bird s = new Dog();
	}
}

메인을 보면 기본적인 instanse인 Dog a = new Dog가 있다.

 

그런데 밑을 봐보자.

Animal d = new Dog();로 선언이 되어있다.

이게 되는 것이 Dog가 Animal을 상속하고 있기 때문이다.

그런데 우리가 Animal에는 만들지 않았지만 Dog에서는 만든 메서드가 있다.

바로 bark메서드이다.

그래서 이 bark메서드를 d.bark 해서 실행을 해보면,

에러가 날것이다.

왜냐하면 Animal에는 bark가 없기 때문이다.

d는 Animal로 명시되어있기 때문에 Animal에 없는 메서드는 호출할 수 없다.

 

마지막 응용으로 Bus카드를 만들어 보았다.

 

Bus.java

package d0420dd;

public class Bus {
	
	protected int income;
	
	protected int countOfAdults;
	
	protected int countOfStudents;
	
	protected int countOfNoin;
	
	public Bus() {
		income = 0;
		countOfAdults = 0;
		countOfStudents = 0;
		countOfNoin = 0;
	}
	
	public static void main(String[] args) {
		Bus b = new Bus();
		
		Card a1 = new CardForAdult();
		a1.charge(2000);
		
		Card adult2 = new CardForAdult();
		adult2.charge(5000);
		
		Card s1 = new CardForStudent();
		s1.charge(3000);
		
		Card s2 = new CardForStudent();
		s2.charge(500);
		
		Card n1 = new CardForNoin();
		n1.charge(1000);
		
		Card n2 = new CardForNoin();
		n2.charge(500);
		
		b.payment(a1);
		b.payment(adult2);
		
		b.payment(a1);
		b.payment(adult2);
		
		b.payment(s1);
		b.payment(s2);
		
		b.payment(n1);
		b.payment(n2);
		
		b.payment(n1);
		b.payment(n2);
		
		System.out.println("오늘의 수입 : " + b.getIncome());
		System.out.println("성인 손님 수 : " + b.getCountOfAdults());
		System.out.println("학생 손님 수 : " + b.getCountOfStudents());
		System.out.println("노인 손님 수 : " + b.getCountOfNoin());
	}
	
	public void payment(Card card) {
		if(card.canPayment()) {
			income += card.requestPayment();
			
			if(card.getType().equals("학생"))
				countOfStudents++;
			else if(card.getType().equals("성인"))
				countOfAdults++;
			else
				countOfNoin++;
				
			
			System.out.println(card.getType() + "입니다.");
		}else {
			System.out.println("잔액이 부족합니다.");
		}
	}
	
	public int getCountOfAdults() {
	
		return countOfAdults;
	}
	
	public int getCountOfStudents() {
		
		return countOfStudents;
	}
	
	public int getCountOfNoin() {
		return countOfNoin;
	}
	
	public int getIncome() {
		
		return income;
	}

}

 

Card.java

package d0420dd;

public class Card {

	protected int balance;
	
	public Card() {
		balance = 0;
	}
	public void charge(int amount) {
		balance += amount;
	}
	
	public int requestPayment() {
		return 0;
	}
	
	public int getFee() {
		return 0;
	}
	
	public boolean canPayment() {
		return false;
	}
	
	public String getType() {
		return null;
	}
	
	
	
}

 

CardForAdult.java

package d0420dd;

public class CardForAdult extends Card{
	
	public int getFee(){
		return 1200;
	}
	@Override
	public int requestPayment() {
		
		if(canPayment()) {
			balance -= getFee();
			
			return getFee();
		}
		else {
			return 0;
		}
		
	}
	
	@Override
	public boolean canPayment() {
		return balance >= getFee();
	}
	
	@Override
	public String getType() {
		return "성인";
	}
}

 

CardForStudent.java

package d0420dd;

public class CardForStudent extends CardForAdult{

	@Override
	public int getFee() {
		return 800;
	}
	
	@Override
	public String getType() {
		return "학생";
	}

}

 

CardForNoin.java

package d0420dd;

public class CardForNoin extends CardForAdult{
	@Override
	public int getFee() {
		return 500;
	}
	
	@Override
	public String getType() {
		return "노인";
	}

}

참고로 위의 CardForNoin.java는 과제이다.

 

이때까지 배운 것의 종합체이기 때문에 따로 설명을 적지는 않겠다.

이렇게 자바 수업이 끝이 났다.

 

반응형

'학교 공부 > 자바' 카테고리의 다른 글

[JAVA] 자바 4번째 수업  (0) 2022.04.13
[JAVA] 자바 세번째 수업  (0) 2022.04.06
[JAVA] 자바 첫 수업  (0) 2022.03.17