[JAVA]/09. 다형성
09. 다형성코드예제 ver.2( 부모클래스를 추상클래스로!)
76beny
2022. 4. 15. 21:08
■ 부모클래스( ver1 과 다르게 추상클래스로!)
- abstract : 추상클래스로 만드는 키워드
[abstract의 특징]
1.생성되지 않는다.
2.abstract 메소드를 가질 수 있다.
3. 일반 메소드나 멤버변수 선언이 자유롭다.
사용방법: 상속이나 Type으로 활용된다.
package com.kh.ex03.poly_abstract;
public abstract class Car { // 부모 클래스,abstract 추상클래스로 만들어 버림
protected int cc = 0; // cc : 배기량
public Car(int cc) {
this.cc = cc;
}
public void oilling() {
System.out.println("주유중 입니다.");
}
public void move() {
System.out.println("부릉부릉");
}
@Override
public String toString() {
StringBuffer sb = new StringBuffer();
sb.append("Name : " + this.getClass().getSimpleName());
sb.append(", cc : " + cc);
return sb.toString();
}
}
■ 부모클래스에 상속된 추상클래스 추가로 만들기
-현대i카 라는 추상클래스를 만들어서 국산 자동차를 그룹화해보는것!
[일반메소드와 추상메소드의 차이]
추상메소드 : 몸통을 가지지 않는다! 그리고 상속받은 클래스에서 강제로 생성한다.
일반메소드 : 공통적인 기능을 가질때 사용.
package com.kh.ex03.poly_abstract;
public abstract class HyundaiCar extends Car {//HyundaiCar(브랜드)를 추상클래스로 하나 만들기
//abstract class의 특징
//1.생성되지 않는다.
//2.abstract 메소드를 가질 수 있다.
//3. 일반 메소드나 멤버변수 선언이 자유롭다.
//사용방법: 상속이나 Type으로 활용된다.
public HyundaiCar(int cc) {
super(cc);
}
//추상메소드 : 몸통을 가지지 않는다! 그리고 상속받은 클래스에서 강제로 생성한다.
//현대종류 차들이 공통적으로 각자 가지고 있었던 nickName을 추상메소드로 만들어버림
abstract public void nickName();//앞으로 nickName이렇게만 쓰라고 박아버리는것
//일반메소드 : 공통적인 기능을 가질때 사용.
//현대차는 블루핸즈에서 수리받을수 있다(가정)해서 service로 메소드 추가로 생성함.
public void service() {
System.out.println("블루핸드로 출발합니다.");
}
// public static void main(String[] args) { // 생성 불가능함. why?
// HyundaiCar Car = new HyundaiCar(13) {//추상클래스는 생성되지 않기 떄문이다!
// }
}
■ 자손클래스 -1 ( 국산차)
- 부모클래스에 상속된 현대i카 라는 추상클래스에 (국산차)자손클래스들을 상속한다.(BMWM5,테슬라제외)
//<Avante>
package com.kh.ex03.poly_abstract;
public class Avante extends HyundaiCar {//클래스 이름을 Car->HyundaiCar로 변경한다
//why? HyundaiCar.java에서 상속했기 때문에 바꾸기 (Car>HyundaiCar>Avante)개념
public Avante() {
super(1600); // 아반떼는 1600cc 이다.
}
@Override
public void oilling() {
System.out.println("휘발유를 주유중입니다.");
}
//AvantenickName을 nickName으로 변경한다
//why? Avante보다 상위클래스인 HyundaiCar에서 각 차들의 각각 설정된 닉네임을
//abstract public void nickName();로 추상메소드로 만들었기 때문에!
@Override
public void nickName() {
System.out.println("아방이");
}
}
//<Grandure>
package com.kh.ex03.poly_abstract;
public class Grandure extends HyundaiCar {//클래스 이름을 Car->HyundaiCar로 변경한다
//why? HyundaiCar.java에서 상속했기 때문에 바꾸기 (Car>HyundaiCar>Grandure)개념
public Grandure() {
super(3000); // 3000cc
}
@Override
public void oilling() {
System.out.println("휘발유를 주유중입니다.");
}
@Override
public void move() {
System.out.println("(조용한)부르르르르릉");
}
//GrandurenickName을 nickName으로 변경한다
//why? Grandure보다 상위클래스인 HyundaiCar에서 각 차들의 각각 설정된 닉네임을
//abstract public void nickName();로 추상메소드로 만들었기 때문에!
@Override
public void nickName() {
System.out.println("각그랜저");
}
}
package com.kh.ex03.poly_abstract;
public class Sonata extends HyundaiCar{//클래스 이름을 Car->HyundaiCar로 변경한다
//why? HyundaiCar.java에서 상속했기 때문에 바꾸기 (Car>HyundaiCar>Sonata)개념
public Sonata() {
super(2000); // 2000 CC
}
@Override
public void oilling() {
System.out.println("휘발유를 주유중입니다.");
}
@Override
public void move() {
System.out.println("부르르르르릉");
}
//SonatanickName을 nickName으로 변경한다
//why? Sonata보다 상위클래스인 HyundaiCar에서 각 차들의 각각 설정된 닉네임을
//abstract public void nickName();로 추상메소드로 만들었기 때문에!
@Override
public void nickName() {
System.out.println("소나 타는 차"); // 실제 이름의 유례, 고 정주영 회장님의...
}
}
■ 자손클래스_2 ( 테슬라, BMWM5 : 해외차라서 현대i카 클래스에 상속시키지 않고 부모클래스에만 상속시킴)
//<BMWM5>
package com.kh.ex03.poly_abstract;
public class BMWM5 extends Car{
public BMWM5() {
super(4395); // cc가 커지면 배기량 올라감 = 힘, 토크, 마력
}
@Override
public void oilling() {
System.out.println("고급 휘발유를 주유중입니다.");
System.out.println("기름을 땅바닥에 뿌립니다.");
}
@Override
public void move() {
System.out.println("부와와와와와왕아아아앙앙(시끄럽게)");
}
void doc3sa() { // 독삼사 = BMW, 벤츠, 아우디
System.out.println("나는 독일에서 온 자동차야.");
}
}
//<TeslaModel3>
package com.kh.ex03.poly_abstract;
public class TeslaModel3 extends Car {
//다른 규격의 자동차모델 자식클래스를 생성했을경우! => 어떻게하는지 ex04에서 보자!
// 전기차인데... CC?
public TeslaModel3() {// 해외 전기차이기때문에 현대차랑 규격(연비단위) 틀림(가정한다)
super(175); // kw/h 단위인데... cc?
}
@Override//생성
public void oilling() { // 호환 안되는듯?// 전기차는 오일링이 아니니까!(가정함)
System.out.println("충전중인데... 오일링?");
}
@Override//생성
public void move() {
System.out.println("(조용히) 위이이이이이잉");
}
}
■ Run
package com.kh.ex03.poly_abstract;
public class _Run {
public static void main(String[] args) {
Car[] carArray = new Car[4];// 4로 변경
//System.out.println(Arrays.toString(carArray));
//carArray[0] = new Car(1000); // 추상클래스는 생성되지 않음!
carArray[0] = new Avante();
carArray[1] = new Sonata();
carArray[2] = new Grandure();
carArray[3] = new BMWM5();
for (int i = 0; i < carArray.length; i++) {
//((Avante)carArray[i]).oilling(); // java.lang.ClassCastException(오류뜸)
// why? 캐스팅 잘못해서(형변환 잘못해서?) => 형변환 함부로 하면 안되고 instanceof로 타입 체크하면서 변환해야함!
printCar(carArray[i]);
}
}
private static void printCar(Car car) { // 인자가 다형성 속성을 사용중
System.out.println(car.toString());
car.move(); // 동적 바인딩 : 실행 전에 호출될 메소드를 정하지 않고,
//실행 후 실시간(동적)으로 메소드를 호출하는 방법
car.oilling();
//ex02패키지의 Run 에서 instanceof뒤에 현대 차종류 별로 각각 되있던걸 새로 생성한 상위추상클래스인HyundaiCar 로 변경해줌.
if (car instanceof HyundaiCar) {
((HyundaiCar) car).nickName(); // 추상클래스로 Type Casting이 가능하다!즉, HyundaiCar를 타입으로 씀!
((HyundaiCar) car).service();// 현대차는 모두 블루핸즈로 출발합니다가 뜸(HyundaiCar추상클래스에 있던 메소드)
}
if (car instanceof BMWM5) {
((BMWM5) car).doc3sa();
}
System.out.println("--------------------------------------");
}
}
//동적바인딩 : 실행전에 호출될 메소드를 정하지 않고, 실시간(동적)으로 메소드를 호출하는 방법.