23.03.17 : 상속(super, 오버라이딩) 과 다형성(형변환), package import

이준영·2023년 3월 17일
0
객체구성문법(한 개 클래스 간 문법)

접근제어자 class 클래스명 {
멤버 필드 변수 (접근 제어자, 자료형, 변수명)
메서드 (접근 제어자 리턴형(없으면 void 형) 메서드 명 ()  {} )
}

*인스턴스 / 클래스(static)
*특별 메서드 (main, 생성자)
*오버로딩
*가변인자 등등   

객체지향프로그램 기법(여러개의 클래스간 문법화)

캡슐화(은닉화) - 접근제어자, setter/getter
상속(extends)
추상
다형



상속

= 공통 내용의 모듈화
단일 상속이 기본(다중 상속을 편법으로 만들어야 하는 경우 있다)
조상(Object) - extends 라는 상속 구문이 없으면 컴파일러가 무조건 Object 상속 받는다.

class Parent { //extends Object 가 생략된 것
   void viewParent() {
       System.out.println("viewParent 호출");
   }
}

class Child extends Parent {  //상속
   void viewChild() {
       System.out.println("viewChild 호출");
   }
}

public class Extend1 {
   public static void main(String[] args) {
       Child c = new Child();
       c.viewChild();
       c.viewParent();
       System.out.println(c.toString());

       Parent p = new Parent();
       p.viewParent();
       //Object에서 가져온 것 
       System.out.println(p.toString());
   }
}



각각 참조값(주소값) 확인하기 = 다 같은 참조(주소)값이 나온다(독립적 아님)

class Parent { //extends Object 가 생략된 것
    void viewParent() {
        System.out.println("viewParent 호출 : " + this);
    }
}

class Child extends Parent {
    void viewChild() {
        System.out.println("viewChild 호출 : " + this);
    }
}

public class Extend2 {
    public static void main(String[] args) {
        Child c = new Child();
        System.out.println(c);
        c.viewChild();
        c.viewParent();

        Parent p = new Parent();

    }
}



private 과 상속

상속 관계에 있더라도 private 선언한 변수나 메서드는 실행되지 않는다.

class Parent { //extends Object 가 생략된 것
    private String p1 = "홍길동";
    public String p2 = "박문수";
    String p3 = "이몽룡";

    void viewParent() {
        System.out.println("viewParent 호출 : " + this);
    }
}

class Child extends Parent {
    void viewChild() {
        System.out.println("viewChild 호출 : " + this);

        //System.out.println(p1);  --> 에러
        System.out.println(p2);
        System.out.println(p3);
    }
}

class GrandChild extends Child {
    void viewGrandChild() {
        System.out.println("viewGrandChild() 호출 : " + this);
    }
}
public class Extend3 {
    public static void main(String[] args) {
        GrandChild g = new GrandChild();

        g.viewParent();

        Child c = new Child();
        //System.out.println(c.p1);  --> 에러
        System.out.println(c.p2);
        System.out.println(c.p3);
    }   
}



메서드 재정의(오버라이딩)

부모(조상) 클래스에 정의된 기능을 자식 클래스에서 적합하게 수정해서 재정의하는 것

오버라이딩 조건 (상속 관계가 전제)
1. 메서드 이름, 매개변수(개수, 순서, 타입), 리턴 타입은 부모 클래스와 같아야 한다.
2. 접근 제한자는 부모 메서드보다 같거나 넓어야 한다.
3. 부모 클래스 메서드보다 더 상위의 예외를 던질 수 없다.

오버라이딩

class Parent {
    void viewParent() {
        System.out.println("viewParent 호출 : " + this);
    }
}

class Child extends Parent {
    void viewParent() {
        System.out.println("child viewParent 호출 : " + this);
    }
}

public class Overriding1 {
    public static void main(String[] args) {
        Child c = new Child();
        c.viewParent();
    }
}

오버로딩

class Parent {
    void viewParent() {
        System.out.println("viewParent 호출 : " + this);
    }
}

class Child extends Parent {
    void viewParent(int a) {  --> 이 경우는 오버로딩이다.
        System.out.println("child viewParent 호출 : " + this);
    }
}

public class Overriding1 {
    public static void main(String[] args) {
        Child c = new Child();
        c.viewParent();
        c.viewParent(10);    --> 따라서 이 두개는 오버로딩(오버라이딩 아님)
    }
}

여기서 리턴문 형식으로 써준다면 에러가 뜬다

class Parent {
    void viewParent() {
        System.out.println("viewParent 호출 : " + this);
    }
}

class Child extends Parent {
    int viewParent() {   --> 에러! 자료형식과 리턴문이 있어 오버라이딩 할 수 없음
        System.out.println("child viewParent 호출 : " + this);
        return 10;
    }
}

public class Overriding1 {
    public static void main(String[] args) {
        Child c = new Child();
        c.viewParent();
    }
}

오버라이딩 할 수 없다는 에러문구



super

부모에 접근 (부모 객체 참조)
(this : 자식 / super : 부모 라고 생각)

class Parent {
    String p  = "홍길동";
    
    void viewParent() {
        System.out.println("viewParent 호출 : " + this);
    }
}

class Child extends Parent {
    String p = "박문수";

    void viewParent() {
        System.out.println("child viewParent 호출 : " + this);

    //super 키워드 (this:나 super:부모)
    super.viewParent();    --> 부모의 viewParent 메서드 호출
    System.out.println(p);
    System.out.println(this.p);   --> 자식 p 호출 (박문수)
    System.out.println(super.p);   --> 부모  p 호출 (홍길동)

    }
}

public class Overriding2 {
    public static void main(String[] args) {
        Child c = new Child();
        c.viewParent();
    }
}



생성자와 상속 관계

class Parent {
    Parent() {
        System.out.println("Parent 생성자 호출");
    }
}

class Child extends Parent {
    Child() {
        System.out.println("Child 생성자 호출");
    }
}

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



생성자와 super

부모가 기본 생성자가 아닌 다른생성자일 경우 super()를 사용하여 호출한다.
super도 this처럼 문장 맨 첫 줄에 있어야 한다 (주석 이외)

class Parent {
    // Parent() {
    //     System.out.println("Parent 생성자 호출");
    // }

    Parent(String data) {
        System.out.println("Parent(String data)생성자 호출");
    }
}

class Child extends Parent {
    Child() {
        //super : 멤버  / super() : 메서드  / this/this() 구조와 같다.
        //this 처럼 문장의 첫 줄에 있어야한다(주석 이외)
        super("10");
        System.out.println("Child 생성자 호출");
    }
}

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



final (

final이 붙어진 클래스는 상속할 수 없다.

final 종류
final 클래스 --> 상속 불가
final 메서드 --> 재정의(오버라이딩) 불가
final 변수 --> 값 변경 불가
상수는 final static 형식으로 많이 쓴다.

클래스에 final 붙은 경우

final class Parent { // 상속 불가
    Parent() {
        System.out.println("Parent 생성자 호출");
    }
}

class Child extends Parent {
    Child() {
        System.out.println("Child 생성자 호출");
    }
}

public class Final1 {
    public static void main(String[] args) {
        Child c = new Child();

    }
}

class에 final로 인하여 뜨는 에러



메서드에 final 붙은 경우

class Parent {
    Parent() {
        System.out.println("Parent 생성자 호출");
    }

    final void viewParent() { // --> final로 인하여 오버라이딩 할 수 없다.
        System.out.println("Parent viewParent 호출");
    }
}

class Child extends Parent {
    Child() {
        System.out.println("Child 생성자 호출");
    }

    void viewParent() {
        System.out.println("Child viewParent 호출");
    }

}

public class Final1 {
    public static void main(String[] args) {
        Child c = new Child();
        c.viewParent();
    }
}

메서드에 final을 붙일 경우 오버라이딩 할 수 없다고 뜨는 에러




다형성 - 클래스 형변환

다형성(Polymorphism)

  1. 상속관계예서 형변환이 가능하다.
  • 자식 -> 부모 = 자동형변환
  • (자식 ->)부모 -> 자식 = 강제형변환(명시적 형변환)

부모 타입 변수로 여러 자식 객체들을 호출하고 싶을 때 사용(다형성)
부모는 변하지 않지만, 부모 하나로 여러 자식들의 특성들을 사용하는 것

다형성의 예

class Parent {
    void viewParent() {
        System.out.println("Parent 호출");
    }
}

class Child1 extends Parent {
    void viewParent() {
        System.out.println("Child1 호출");
    }
}

class Child2 extends Parent {
    void viewParent() {
        System.out.println("Child2 호출");
    }
}

public class Casting3 {
    public static void main(String[] args) {
        // Child1 c1 = new Child1();
        // c1.viewParent();

        // Child2 c2 = new Child2();
        // c2.viewParent();

        Parent p = new Child1();   --> child1 참조 가능
        p.viewParent();
        
        p = new Child2();   --> child2 참조 가능
        p.viewParent();
    }
}




패키지(Package)

class를 보관하기 위한 폴더

package이름 - 도메인 형식(회사 도메인)으로 작성
ex > package com.naver.www << 반대로 작성

같은 클래스 이름이라도 패키지가 다르다면 사용 가능하다.

패키지는 기존의 컴파일 방식과는 다른 방법으로 시켜주어야 한다.
컴파일 - javac -d . -encoding utf-8 packB.java(기존 것에서 -d . 추가, 
폴더 만들어지고 안에 packB.class가 들어가짐)
jdk 10 버전 이하
{
패키지
클래스
...
}

jdk 10 이상
{
모듈  (현업에서는 아직까진 잘 사용하지 않음)
패키지
클래스
...
}

package 패키지명 --> class를 이 패키지명을 통해서 안에 넣는다는 뜻

class 클래스명 {
}


import 패키지명.클래스명 --> 패키지 안의 클래스를 가져오는 기능


pack2 만들고 packC.class를 넣고 메인에서 생성자 호출해보기

1.packC.java 생성(위에 package pack2 라고 쓰기)

  1. 명령 프롬포트에서 컴파일 시켜서 pack2에 packC.class가 들어가도록 하기

  1. 메인(실행 클래스)에서 객체 선언, 생성해주기

  1. 메인(packMain) 컴파일 후 실행하기

  1. 이것을 대신하기 위하여 import 써주기


import ↑

다른 패키지에 선언된 클래스를 사용하기 위해 필요한 키워드
package에 모든 클래스를 포함할 때는 *를 사용한다.

profile
끄적끄적

0개의 댓글