9. 상속

2023. 3. 27. 17:44Lang/Java

728x90
반응형

1. 상속 (extends)

  • 기존의 클래스를 재사용하여 새로운 클래스를 작성하는 것
  • 이미 만들어진 클래스의 멤버들을 물려받아 새로운 클래스를 정의한다
  • 공통되는 부분을 base클래스로 추상화, 이를 상속하면서 Derived 클래스를 정의한다.
  • 하위클래스가 상위클래스를 상속받으면 하위는 상위의 모든 것을 이용할 수 있다.

부모클래스 - 상위(super)클래스, 기본(base)클래스, 조상클래스
자식클래스 - 하위(sub)클래스, 파생(derived)클래스, 자손클래스

class 클래스명 extends 부모클래스

class Parent{
}
class Child extends Parent{
}
import java.util.Scanner;

class Person{
    private int age;
    private String name;
    public void setAge(int age) {
        this.age = age;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return this.age;
    }
    public String getName() {
        return this.name;
    }
}

class Student151 extends Person{
    private String stNo;
    public String getStNo() {
        return stNo;
    }
    public void setStNo(String stNo) {
        this.stNo = stNo;
    }
} // 자식클래스인 student는 부모클래스인 Person의 멤버변수 name과 age를 모두 이용할 수 있다.


public class sp {

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        System.out.println("이름, 나이, 학번입력!");
        String name = sc.nextLine();
        int age = sc.nextInt();
        sc.nextLine();
        String stNo=sc.nextLine();

        Student151 st = new Student151();
        st.setAge(age);
        st.setName(name);
        st.setStNo(stNo);

        System.out.println(st.getStNo());
        System.out.println(st.getName());
        System.out.println(st.getAge());
    }
}

상속과 protected

package day15;
import day15sub.MyParent;

//부모클래스가 다른 패키지에 있을 경우

class MyChild extends MyParent{
    public void putData() {
        //varprivate  //부모클래스의 private 변수 접근 불가
        varprotected = 10; // 부모클래스의 protected 변수 접근 가능
        //vardefault  // 부모클래스의 default 클래스 접근 불가
        varpublic = 40; // 부모클래스의 public 변수 접근 가능
    }
}

public class ProtectedTest {

    public static void main(String[] args) {
        MyChild ch = new MyChild();
        //ch.varprivate
        //ch.varprotected //자식클래스는 받아오지만, 멤버변수는 다른패키지에 있기에 메인클래스에서는 접근 불가
        //ch.vardefault
        ch.varpublic = 10;

    }

}

상속의 생성 순서

class GrandFather{
    GrandFather(){
        System.out.println("그랜파 생성자");
    }
}

class Father extends GrandFather{
    Father(){
        System.out.println("파더 생성자");
    }
}

class Child extends Father{
    Child(){
        System.out.println("차일드 생성자");
    }
}



public class Inheritance3 {

    public static void main(String[] args) {
        Child ch = new Child();
    }

} // 자식클래스 생성시, 부모클래스부터 차례로 생성 후 자식클래스를 생성하는 것을 알 수 있다.

object 클래스

  • object클래스 : 모든 클래스의 최상위 클래스

  • 생성하는 클래스는 자동적으로 object를 상속받고 있다

    class exam{
    }
    class exam (extends object){
    }

  • toString, equals 등의 메서드들을 사용할 수 있는 이유


2. 오버라이딩

  • 부모클래스로부터 상속받은 메서드의 내용을 변경하는 것
  • 상속받은 메서드를 자식클래스에 맞게 변경해야 하는 경우
class Point{
    protected int x;
    protected int y;

    public String findLocationd() {
        String result = "x="+x+", y="+y;
        return result;
    }
}

class Point3D extends Point{
    private int z;

    public String findLocationd() {
        String result = "x="+x+", y="+y+", z="+z;
        return result;
    }
}

public class PointTest {

    public static void main(String[] args) {
        Point p = new Point();
        String res = p.findLocationd();
        System.out.println("2 : "+res);

        Point3D p3 = new Point3D();
        System.out.println("3 : "+p3.findLocationd());
    }
}

a. 오버라이딩 조건

  • 메서드의 선언부는 부모클래스와 완전히 일치해야 한다
    • 내용만을 재정의 하는 것
    • 이름이 같아야 한다.
    • 매개변수가 같아야 한다.
    • 리턴타입이 같아야 한다.

3. this / super

a. this

  • this. : 자기자신을 가리키는 참조변수
  • this() : 한 생성자에서 다른 생성자를 호출
    • 생성자의 이름으로 클래스 이름 대신 this 사용
    • 첫 줄에서만 호출 가능
  • 클래스 내 유일하게 호출할 수 없는 메서드 : 생성자
    • 생성자를 호출하는 유일한 방법 : this()
class Car{
    private String color;
    private String gearType;
    private int door;

    Car(String color, String gearType, int door){
        this.color = color;
        this.gearType = gearType;
        this.door = door;
    }
    /*
    Car(){
        this.color = "white";
        this.gearType = "auto";
        this.door = 4;
    } 중복되는 줄이 많다
    */
    Car(){
        this("white","auto",4);
    } // this를 이용, 오버로딩 생성자의 중복부분을 삭제

    Car(String color){
        this(color, "auto",4);
    }

    public void showInfo() {
        System.out.println(color);
        System.out.println(gearType);
        System.out.println(door);
    }
}

public class ThisTest {

    public static void main(String[] args) {
        Car c1 = new Car();
        c1.showInfo();

        Car c2 = new Car("Black");
        c2.showInfo();

        Car c3 = new Car("Red","manual",2);
        c3.showInfo();
    }

}

b. super

  • 자식클래스에서 부모클래스로부터 상속받은 멤버를 참조하는데 사용

    • 부모의 멤버 호출 : super.멤버
    • 부모의 생성자 호출 : super()
  • 상속받은 멤버와 자신의 멤버이름이 같을 때 구별하기 위해 사용

  • 그 외에는 근본적으로 this와 같다.

  • ex) super.

    class Parent {
      int x=10;
    }
    class Child extends Parent {
      void method() {
          System.out.println("x=" + x);  // 10
          System.out.println("this.x=" + this.x); // 10
          System.out.println("super.x="+ super.x); // 10
      }
    }
    class Parent {
      int x=10;
    }
    class Child extends Parent {
      int x = 20;
      void method() {
          System.out.println("x=" + x); // 20
          System.out.println("this.x=" + this.x); // 20
          System.out.println("super.x="+ super.x); // 10
      }
    }
  • ex) super()

    class Point{
      protected int x;
      protected int y;    
    
      Point(int x, int y){
          //super() 가 생략되어있으며, 최상위 클래스 object를 호출하고있다.
          this.x = x;
          this.y = y;
      }
      public String findLocation() {
          return "x="+x+", y="+y;
      }
    }
    class Point3D extends Point{
      private int z;
      Point3D(int x, int y, int z){
          super(x,y);
          // 부모생성자가 매개변수를 가지고 있다면, 자식은 부모의 생성자에
          // 매개변수를 넣어줘야 한다.
          // 모든 클래스의 생성자 첫줄에는 생성자 호출을 해야하며
          // super()가 보이지는 않지만 들어가있다.
          this.z=z;
      }
      public String findLocation() {
          return super.findLocation()+", z="+z;
      }    
    }
    public class SuperTest {
    
      public static void main(String[] args) {
          Point3D a = new Point3D(10,20,30);
          System.out.println(a.findLocation());
      }
    }

4. final

  • 변수 : 값 변경할 수 없는 상수가 된다.(멤버, 지역 둘다 사용 가능)
  • 메서드 : 오버라이딩 불가
  • 클래스 : 자식클래스를 정의할 수 없다.
    • ex) String, Math 클래스
class Parent2{
    public void func1() {
        System.out.println("func1()");
    }
    public final void func2() {
        System.out.println("func2()");
    }
}
class Child2 extends Parent2{
    public void func1() {
        System.out.println("오버라이딩 func1");
    }
    /*
    public void func2() {
        System.out.println("오버라이딩 func2");
    } error 
    */
}

class MyFinal{
    public final static double PI=3.141592;
    public final int DELIVERY=3000;
    int age = 20;
}

public class FinalClassTest {

    public static void main(String[] args) {
        MyFinal obj = new MyFinal();
        System.out.println(obj.age);
        System.out.println(MyFinal.PI);
        System.out.println(obj.DELIVERY);

        obj.age = 23;
        // MyFinal.PI=3.14;
        // obj.DELIVERY=2500;

        //final 지역변수
        final double INTEREST_RATE=0.02;
        System.out.println(INTEREST_RATE);

        // INTEREST_RATE = 0.15;
    }
}
  • 지역변수에서 final은 static와 함께 사용 불가
    • final필드가 이미 static필드의 특성을 띄고있다.
    • 클래스명으로 접근
  • 생성자를 이용해 final 멤버변수 초기화
    • final 변수
      • 상수지만 선언과 함께 초기화하지 않고 생성자를 통해 초기화 가능
      • 각 인스턴스별 다른 값을 갖도록 할 수 있다.
    • static final 변수
      • 선언과 함께 초기화
      • 클래스 차원에서 하나만 생성, 모든 인스턴스가 같은 값을 갖는다
class Card{
    final String KIND;
    final int NUMBER;
    static final int WIDTH=100;
    static final int HEIGHT=250;

    Card(String k, int num){
        KIND = k;
        NUMBER=num;
    }
    public void showInfo() {
        System.out.println("카드 종류"+KIND);
        System.out.println("카드 숫자"+NUMBER);

        // KIND="spade"; error
    }
}

public class CardFinal {

    public static void main(String[] args) {
        Card c1 = new Card("dia",5);
        c1.showInfo();

        Card c2 = new Card("heart",9);
        c2.showInfo();

        System.out.println("너비:"+Card.WIDTH);
        System.out.println("높이:"+Card.HEIGHT);
    }
}

5. 클래스 포함관계 (Has a)

  • 클래스 자체를 다른 클래스의 멤버변수로 포함
  • 상속 이외에 클래스를 재사용하는 방법
    • 상속 이용시
      • is a 관계가 성립
      • ~은 일종의 ~이다
      • sportsCar is a Car
    • 포함 이용시
      • has a 관계가 성립
      • ~은 ~을 가지고 있다
      • Circle has a Point
  • 상속 이용 ex)
class Points{
    protected int x;
    protected int y;

    Points(int x, int y){
        this.x=x;
        this.y=y;
    }
}
class Circle extends Points{
    private int r;
    Circle(int x, int y, int r){
        super(x,y);
        this.r=r;
    }
    public void pritnInfo() {
        System.out.println("x="+x+", y="+y);
        System.out.println("r="+r+"\n");
    }
}

public class IsATest {

    public static void main(String[] args) {
        Circle c = new Circle(10, 20, 30);
        c.pritnInfo();
    }
}
  • 포함 이용 ex)
class Points2{
    int x;
    int y;

    Points2(int x, int y){
        this.x=x;
        this.y=y;
    }
}

class Circle2{
    private Points2 p;
    private int r;

    Circle2(Points2 p, int r){
        this.p = p;
        this.r = r;
    }
    public void pritnInfo() {
        System.out.println("x="+p.x+", y="+p.y);
        System.out.println("r="+r+"\n");
    }
}

public class HasATest {

    public static void main(String[] args) {
        Circle2 c = new Circle2(new Points2(40,50),60);
        c.pritnInfo();
    }
}
728x90
반응형

'Lang > Java' 카테고리의 다른 글

11. 추상  (0) 2023.03.27
10. 다형성  (0) 2023.03.27
8. static  (0) 2023.03.27
7. 클래스  (0) 2023.03.27
6. 배열  (0) 2023.03.27