본문 바로가기

자바(JAVA)
[자바(Java)] 상속

//상속, Inheritance

- 부모가 가지는 재산을 자식에게 물려주는 행동

- 부모(클래스)가 가지는 재산(멤버 변수, 멤버 메서드)을 자식(클래스)에게 물려주는 행동

- 상속하는 이유(목적) : 코드 재사용 > 비용 절감

- 다중 상속 xx

- ★★부모가 물려준 멤버를 자식이 상속 거부할 수 없다. (무조건 모든 것을 다 상속 받아야 함.)

-  class A extends B {}
    ~ A : 자식 클래스, 서브 클래스,                기본 클래스
    ~ B : 부모 클래스, 슈퍼 클래스,  확장 클래스, 파생 클래스 

class B { //부모 클래스
	멤버 필드;
	멤버 메서드;
}

class A { // 자식 클래스
	멤버 필드1;
	멤버 메서드1;
}

public class B extends A {
	멤버 필드1;
	멤버 메서드1;
}

상속

//Phone

package ex01.sample01;

public class Phone {
	public String model;
	public String color;
	
	public void bell() {
		System.out.println("벨이 울린다.");
	}
	public void sendVoice(String message) {
		System.out.println("본인 : " + message);
	}
	
	public void receiveVoice(String message) {
		System.out.println("상대방 : " + message);
	}
	
	public void hangUp() {
		System.out.println("전화를 끊습니다.");
	}
}

 

//SmartPhone 

package ex01.sample01;

public class SmartPhone extends Phone {
	public boolean wifi;
	
	public SmartPhone(String model, String color) {
		this.model = model;
		this.color = color;
	}
	
	public void internet() { //SmartPhone 클래스의 메서드
		System.out.println("인터넷 연결");
	}
	
	public void setWifi(boolean wifi) {
		this.wifi = wifi;
		System.out.println("wifi 변경");
		
	}
}

 

//PhoneExample

package ex01.sample01;

public class SmartPhoneExample {

	public static void main(String[] args) {
		SmartPhone myPhone = new SmartPhone("갤럭시 z플립", "검정");
		
		//myPhone으로부터 상속받은 필드 읽기 	
		System.out.println("모델 : " + myPhone.model);
		System.out.println("색상 : " + myPhone.color);
		
		//Smartphone 필드 읽기
		System.out.println("와이파이 상태 : " + myPhone.wifi);
		
		// Phone으로부터 상속받은 메서드 호출
		myPhone.bell();
		myPhone.sendVoice("여보세요");
		myPhone.receiveVoice("저는 ㅇㅇㅇ입니다.");
		myPhone.sendVoice("네");
		myPhone.hangUp();
		
		//Smartphone 메서드 호츌
		myPhone.setWifi(true);
		myPhone.internet();

- 부모 클래스의 생성자를 먼저 호출한 후 자식 클래스의 생성자를 호출한다.

package ex02.sample02;

class Car {
	Car() { // 기본 생성자
		System.out.println("부모 클래스 생성자 Car()");
	}
	Car(String str) { // 매개변수를 가지고 있는 생성자
		System.out.println("부모 클래스 생성자 Car() : " + str);
	}
}

class Sedan extends Car{
	Sedan(String str) {
		System.out.println("서브 클래스 생성자 호출 : " + str);
	}
}

public class Example02 {

	public static void main(String[] args) {
		Sedan sedan1 = new Sedan("여기요");
	}
}

// super()

- 부모 클래스를 호출하는 기능 (재정의 x, 그대로 가지고 온 것.)

- 생략 가능하다.(컴파일러가 자동으로 추가함.)

public class A {
	String color;
	String model;
}

public class B extends A { 
	public B(String color, String model) { //호출(재정의x)
		super(color, model);
			....
}

// 메서드 오버라이딩

- 기각[무시]하다. 우선하다.

- 자식 클래스가 부모 클래스로부터 상속받은 메서드를 자신에게 맞게 재정의 하는 것

- 오버라이딩 후에는 부모가 선언한 메서드는 호출이 불가능하고, 자식이 오버라이딩한 메서드만 호출 가능

- 메서드 앞에 final을 붙이면 해당 메서드를 오버라이딩 할 수 없다.

메서드 오버라이딩

package ex04.sample04;

class Car {
	int speed = 0; // 필드 0으로 초기화
	void upSpeed(int speed) {
		this.speed += speed;
		System.out.println("현재 속도(부모 클래스) : " + this.speed) ;
	}
}

class Sedan extends Car {
	void upSpeed(int speed) {
		this.speed += speed;
		if(this.speed > 150) //메서드 오버라이딩
			this.speed = 150;
		System.out.println("현재 속도(서브 클래스) : " + this.speed);
	}
}

class Truck extends Car{
	
}

public class Example04 {
	public static void main(String[] args) {
		Truck truck1 = new Truck();
		Sedan sedan1 = new Sedan();
		
		System.out.println("트럭 : ");
		truck1.upSpeed(250);
		
		System.out.println("승용차 : ");
		sedan1.upSpeed(250);
	}
}

 

final

package ex05.sample05;

class Car {
	int speed = 0;
	
	void upSpeed(int speed) { // 상속 받은 자식 클래스는 이 메서드를 오버라이딩 하지 못 한다.
		this.speed = speed;
	}
}
class Sedan extends Car {
	final static String CAR_TYPE = "승용차"; 
}
public class Example05 {
	public static void main(String[] args) {
		System.out.println("Sedan 클래스 타입 :" + Sedan.CAR_TYPE);
	}
}

// super


- this와 같은 역할 > 객체를 가리키는 상대 표현

- 자기 자신(x) > 부모 객체(o)

- 상속 관계에 있는 부모 객체를 가리키는 상대 표현

- 부모(상대 표현)

- 메서드 오버라이딩에 의해 감춰진 부모 메서드 호출


package com.test.obj.inheritance;

public class Ex58_super {

	public static void main(String[] args) {

		TestChild c = new TestChild();
		
		c.bbb();

	} //main
	
}

class TestParent {

	public void test() {
		System.out.println("부모 메서드");
	}
	
}

class TestChild extends TestParent {
	
	public void bbb() {
		
		this.test();
		super.test(); //메서드 오버라이딩에 의해 감춰진 부모 메서드 호출
		System.out.println();
		
	}

	@Override
	public void test() {
		System.out.println("자식 메서드");
	}
	
}

//Cating

1. 업캐스팅, Up Casting
    
- 암시적인 형변환
    - 100% 안전
    - 자식 클래스 > 부모 클래스
    - 부모 클래스 = 자식 클래스;
    - 형변환은 되지만, 자식 클래스에는 있고 부모 클래스엔 없는 메서드는 호출할 수 없다.
       > 자식 클래스에 있는 메서드를 사용하고 싶다면, 부모 클래스에서 같은 이름의 메서드의 구현부를 비우고 선언한다.
       > 오버라이딩 기능 이용


2. 다운캐스팅, Down Casting
    - 명시적인 형변환
    - 다운캐스팅만 하는 것은 100% 불가능하지만 업캐스팅 후 다시 다운캐스팅 하는 경우는 가능
        > 평소에는 형제들과 같이 부모 배열에 넣어서 관리하다가 자식만이 가지는 고유 기능을 사용해야 할 때 다운 캐스팅을 사용해서 원래 타입 참조 변수로 형변환

    - 부모 클래스 > 자식 클래스
    - 자식 클래스 = 부모 클래스


package com.test.obj.cast;

public class Casting {

	public static void main(String[] args) {

		//상황] 대리점 운영 > 프린터 판매
		//1. 재고 확보
		//2. 주기적으로 제품 점검

		//목적] 제품 점검 > 효율적

		Printer[] ps = new Printer[8];

		for(int i = 0; i < ps.length; i++ ) {

			if(i < 5) {
				ps[i] = new HP600("black", 25000, "ink");

			} else {
				ps[i] = new LG500("white", 35000, "lazer");
			}

		}

		for(int i = 0; i < ps.length; i++ ) {
			ps[i].print();
		}

	} //main
}


class Printer {
	
	private String color;
	private int price;
	private String type;
	
	public Printer(String color, int price, String type) {
		this.color = color;
		this.price = price;
		this.type = type;
	}
	
	public void print(){
		
	}
	
}

class HP600 extends Printer {
	
	public HP600(String color, int price, String type) {
		super(color, price, type);
	}
	 
	@Override
	public void print() {
		System.out.println("HP600으로 출력합니다.");
	}
	
	public void call() {
		System.out.println("HP600 자가진단을 실시합니다.");
	}
	
}

class LG500 extends Printer {
	
	public LG500(String color, int price, String type) {
		super(color, price, type);
	}
	
	@Override
	public void print() {
		System.out.println("LG500으로 출력합니다.");
	}
	
	public void call() {
		System.out.println("인공지능 AI와 연결합니다.");
	}
	
}

!Quiz 1!

- Pet이라는 반려동물 클래스를 상속받는 Dog class와 Bird 클래스를 만들어 본다.

- 출력
    ~ 반려동물이 움직인다.
    ~ 반려동물이 움직인다.
    ~ 강아지의 이름은 누렁이, 몸무게는 10kg이다.
    ~ 새의 종류는 앵무새이고, 날 수 있다.

스스로

package ex06.sample06;


class Pets {
	String type;
	int age;
    
	void move() {
		System.out.println("반려동물이 움직인다.");
	}
}

class Dog extends Pets {
	String name;
	int weight;
}

class Bird extends Pets {
	String bird_type;	
}

public class Pet {
	public static void main(String[] args) {
		Dog dog = new Dog();
		dog.type = "강아지";
		dog.name = "누렁이";
		dog.weight = 10;	
				
		Bird bird = new Bird();
		bird.type = "새";
		bird.bird_type = "앵무새";
		
		dog.move();
		bird.move();		
		
		System.out.println(dog.type + "의 이름은 " + dog.name + "이고, 몸무게는 " + dog.weight + "kg이다.");
		System.out.println(bird.type + "의 종류는 " + bird.bird_type + "이고, 날 수 있다.");
		
	}
}

강사님

package ex06.sample06;

class Pets {
	public void move() {
		System.out.println("반려동물이 움직인다.");
	}
}

class Dog extends Pets {
	String name;
	int weight;
}

class Bird extends Pets {
	String type;
	boolean flight;
	
	boolean getFlight() {
		return flight;
	}
}
public class Pet {
	public static void main(String[] args) {
		Dog dog1 = new Dog();
		dog1.name = "누렁이";
		dog1.weight = 10;
		
		Bird bird1 = new Bird();
		bird1.type = "앵무새";
		bird1.flight = true;
		
		dog1.move();
		bird1.move();
		
		System.out.println("강아지의 이름은 " + dog1.name + "이고, 몸무게는 " + dog1.weight + "kg입니다.");
		System.out.println("새의 종류는 " + bird1.type + "이고, 날 수 " + 
		(bird1.getFlight() ? "있" : "없") + "습니다.");		
	}
}

**삼항 연산자


!Quiz 2!

- super class인 Pet 클래스를 상속받는 Dog, Bird 클래스를 작성한다.
    ~ super class move(): 반려동물이 움직인다.
    ~ sub class move() : 새가 날아간다.

- move()를 오버라이딩하여 출력하시오.

스스로

package ex07.sample07;

class Pets {
	String type;
	int age;
    
	void move() {
		System.out.println("반려동물이 움직인다.");
	}
}

class Dog extends Pets {
}

class Bird extends Pets {
	String type;
	void move() { //앞에 public 붙이기
		System.out.println(this.type + "가 날아간다.");
	}
}

public class OverRidingPet {
	public static void main(String[] args) {
		Dog dog = new Dog();
		
		Bird bird = new Bird();
		bird.type = "새";
		
		dog.move();
		bird.move();
	}
}

1. 클래스 ==> 일반 클래스

2. 클래스 ==> 추상 클래스

interface를 구현하는 implements