# 상속
원칙적으로 JAVA는 단일 상속만을 지원하지만 다중상속 하는 기능도 지원을 한다.
class A{
data;
method;
}
A클래스를 물려 받는 B클래스
extends : 상속 받기 위한 keyword
class B extends A{
}
A(부모) <- B(자식)
B가 A를 상속 받으면 UML 표기법 에서는 부모쪽으로 화살표가 향한다.
ex) is -an 관계가 성립하면 상속을 받을 수 있다
Lion is an Animal //Lion이 물려 받는다
사자는 동물의 특징을 가지고 있어서 사자는 동물이다
Apple is a Fruit //Apple 가 물려받는다
사과는 과일이다.
Tiger is an Animal //Tiger 가 물려받는다.
호랑이는 동물이다.
Generalization : 일반화 부모 클래스, super class, base class
-추출된 class의 공통적인 특성을 모아 super class로 정의할 수 있다.
Specialization : child class, subclass, derived class
-비슷한 속성과 기능을 가지고 있는 다른 class를 상속 받아 새로운 class를 정의할 수 있다.
#상속 기본 코드 구조
package com.inherit;
//부모 클래스, super class, base class, parent class
class Parent{
String name="Tom"; //부모 클래스의 field
String address="Seoul";
public void printName() {
System.out.println("name:"+name);
}
public void printAddress() {
System.out.println("address:"+address);
}
}
//자식 클래스, sub class, derived class, child class
public class Child extends Parent {
int age=25; //자식 클래스의 field는 부모 클래스의 name, address 포함해서 총 3개
public static void main(String[] args) {
Child c = new Child();
//상속 관계가 존재하는, 자식 객체를 생성하면, 메모리에 부모 객체가 먼저 만들어 진다.
때문에
자식 객체를 생성할때는 부모 객체가 만들어 지도록 변수값을 넘겨야한다.
*
그래서 자식 클래스 생성자를 만들때
super(변수) 이런식으로 먼저 부모 객체가 만들어 질 수 있도록 변수를 넘겨줘야 한다.
*
c.printName(); // 부모 클래스의 printName()
c.printAddress();
}
//메소드는 main, 부모 클래스의 printName(); 부모 클래스의 printAddress();
이렇게 가지고 있다.
}
#method overriding
부모한테서 물려 받은 메소드를 자식 클래스에 맞게 수정하는 일(오버라이딩)
!!method 이름, 리턴타입, 파라메터 타입 모두 동일해야함
접근지정자는 수정이 가능하다.
중요 !!!!! (부모가 가지고 있는 접근 지정자 보다 커지는건 괜찮은데 좁아지는건 안된다)
//부모 클래스, super class, base class, parent class
class Parent {
String name = "Tom";
String address = "Seoul";
public void printName() {
System.out.println("name:" + name);
}
}
//자식 클래스, sub class, derived class, child class
public class Child extends Parent {
int age = 25;
//method overriding : 부모한테서 물려 받은 메소드를 자식 클래스에 맞게 수정하는 일
public void printName() {//method 이름, 리턴타입, 파라메터 타입 모두 동일
System.out.println("name: Tomson" );
}
이렇게 해도 되고 밑에 처럼 source에서 자동으로 추가 해주면 된다.
@Override :@annotation: 프로그램에 대한 설명이나 설정 사항 등을 나타냄
:오버라이딩된 메소드에서는 안붙이거나, 붙여도 상관이 없는데 오버라이딩이랑 상관없는
메소드에 붙이게 되면 오류가 나게된다
@Override
protected void printName() {
System.out.println("name: Tomson");
}
//자식이 부모메소드를 오버라이딩 하게 되면 게속 overriding된 메소드가 실행됨
//overriding 된 메소드 말고 부모 클래스의 메소드를 사용하고 싶으면 super 키워드를 이용해준다.
//super, this, --> static 메소드에서 사용이 불가능 하다.
그래서 main에서 사용이 불가능 하고 메소드를 하나 더 만들어서 사용한다.
public void callSuper() { //부모 클래스의 printName() 호출한다.
super.printName();
}
public static void main(String[] args) {
Child c = new Child();
//상속 관계가 존재하는, 자식 객체를 생성하면, 메모리에 부모 객체가 먼저 만들어 진다.
//그래서 생성자를 찍어보면 부모생성자 부터 생성되고 자식 생성자가 만들어진다.
c.printName(); //재정의된 자식 클래스의 printName() 호출
c.printAddress(); //부모클래스의 printAddress //부모클래스에만 존재해서
c.callSuper(); //부모 클래스의 printName()호출
}
}
상속 예제
부모 클래스 Parts
package com.computer2;
public class Parts {
String maker;
int price;
public Parts(String maker, int price) { //부모 클래스 생성자
this.maker = maker;
this.price = price;
}
public void info() {
System.out.println("maker :"+maker);
System.out.println("price :"+price);
}
}
자식 클래스 Mouse
package com.computer2;
public class Mouse extends Parts { //Parts 클래스 상속
boolean wireless;
public Mouse(String maker, int price, boolean wireless) {
super(maker,price); //부모의 생성자 호출
자식 클래스의 생성자가 호출될때 부모클래스의 생성자가 먼저 호출이 되기 때문에 부모 클래스가 생성자를 먼저 생성할
수 있도록 위와 같은 방식으로 값을 넘겨 주어야 한다.
무조건 super가 위에 있어야 오류가 안난다.
//this.maker=maker; //이렇게 값을 정하게 되면 자식 클래스의 생성자가 호출될때
//this.price=price; //부모 클래스의 생성자가 파라미터가 맞지 않기 때문에 생성되지가 못한다
this.wireless=wireless;
}
public boolean isWireless() {
return wireless;
}
public void click() {
System.out.println("마우스 클릭중 입니다");
}
public void scroll() {
System.out.println("마우스 스크롤 중입니다");
}
@Override
public void info() {
super.info();
System.out.println("마우스 wireless :"+wireless);
}
}