• Home
  • About
    • Young's Github Pages photo

      一日不作一日不食

    • About
    • Github
  • Posts
    • All Posts
    • All Tags
  • Projects

Java 정리 15

03 Dec 2018

Reading time ~4 minutes

Java 정리 15 - 객체다형성, abstract class, interface


객체다형성

  • 같은 이름의 객체를 다르게 쓸 수 있는 것
  • is-a 관계 객체화
    • 부모클래스로 데이터형 선언, 자식클래스 생성자로 객체화 하는 것
      • 자식은 부모를 알고 있기 때문에 가능
      • 부모만 사용할 수 있으면 됨.
    • 부모클래스의 자원(변수, 메소드) 사용 가능, 자식클래스 자원 사용 불가
      • 단, 자식이 Override한 method는 사용가능
부모클래스명 객체명 = new 자식클래스생성자();
class Super{
    int i;
    public Super() { }
    public void printI() { System.out.println("부모 i="+i); }
}
class Sub extends Super {
    int i;
    int j;
    @Override
    public void printI() { System.out.println("자식 i="+i+",  부모 i="+super.i); }
    public void printJ() { System.out.println("자식 j="+j); }
}
class IsARelation {
  public static void main(String[] args) {
    // s로 부모클래스의 변수, 메소드, 자신의 자원 사용가능
    Sub s = new Sub();

    s.i = 10;
    s.printI();    // 자식 i=10, 부모 i=0
    
    // 부모클래스의 변수, 메소드, Override된 자식메소드 사용가능
    Super s2 = new Sub();
    
    s2.i = 100;
    s2.printI();   // 자식 i=0, 부모 i=100
  }
}

추상클래스

  • 클래스는 명사적특징을 정의한 변수, 동사적 특징(일)을 정의한 메소드가 존재
    • 메소드는 부모가 구현하는 경우와 부모가 구현하지 않는 경우로 구분됨
    • 부모가 구현하지 않는 경우 사용하는게 추상 메소드
  • 추상클래스는 상속을 목적으로 만들어지는 클래스
    • abstract method를 가질 수 있는 class
    • 자식클래스가 반드시 구현하도록 강제성을 부여
  • 객체화가 되지 않음
    • 자식 클래스가 생성되면서 부모가 만들어지는 경우에는 객체화가 된다
  • 추상메소드
    • method의 body가 없다.
    • 일을 정의할 수 없고 일의 목록만 정의
      • 자식클래스에서 반드시 구현해야 함

01

// abstract class
접근지정자 abstract class 클래스명 { ... }

// abstract method
접근지정자 abstract 반환형 method명(매개변수명, ...);

/* 접근 지정자
다른 패키지에서 상속받아 사용해서 보통 public, protected 사용
public     
protected
default      
static       
synchronized
---------------------------------------------------------
final - 상속(Override)을 막기 때문에 final 사용불가
*/
/**
* 상속을 목적으로 만드는 부모클래스
* 객체화가 안됨
* 자식클래스가 반드시 구현해야할 abstract method를 가지는  클래스.
*/
abstract class AbstractSuper {
     
  int i;
  
  public AbstractSuper() {
    // 자식클래스가 생성될때만 호출됨
    System.out.println("AbstractSuper의 생성자");
  }
  
  public void method() {
    System.out.println("부모 일반 method");
  }
  
  // abstract method는 자식이 반드시 구현해야할 일의  목록을 정의
  public abstract void absMethod();
  public abstract String absMethod1(int i);
  
  /* public static void main(String[] args) {
      new AbstractSuper(); // 추상클래스는 객체화 될 수  없다.
  } */
}
/**
* 추상클래스를 부모로 하는 자식클래스
* 자식클래스는 반드시 부모클래스의 모든 추상 메소드를  Override 해야한다.
*/
class AbstractSub extends AbstractSuper{
  // Override 규칙
  // 접근지정자는 광의로 변경가능, 반환형, method명, 매개변수는 동일
  @Override
  public void absMethod() {
    System.out.println("Override한 absMethod");
  }
  @Override
  public String absMethod1(int i) {
    System.out.println("Override한 absMethod1");
    return String.valueOf(i);
  }
  
  public static void main(String[] args) {
  
    AbstractSub as = new AbstractSub();
    
    as.absMethod();
    System.out.println(as.absMethod1(100));
  }
}

02

abstract class Person {
    public abstract void paint();
}
class HongGilDong extends Person {
    @Override
    public void paint() {
      System.out.println("동양화를 그린다.");
    }
}
class Clark extends Person {
    @Override
    public void paint() {
      System.out.println("서양화를 그린다.");
    }
}
class UsePerson {
    public static void main(String[] args) {
      HongGilDong gd = new HongGilDong();
      Clark superman = new Clark();

      gd.paint();
      superman.paint();
    }
}

03


인터페이스

  • 다중상속의 장점을 사용하기위해 사용
  • 기능추가를 손쉽게 할 수 있다.
  • 약결합의 구현으로 객체간 유연성을 향상시킬 수 있다
    • 약결합, 응집도 높은 프로그램이 좋은 프로그램
  • 객체화는 안됨
    • 구현클래스가 생성되면 그 주소는 저장가능
    • 즉, is-a 관계의 객체화 가능
  • 여러 부모인터페이스 상속가능
  • jdk 1.8에서부터 Default method가 추가됨
    • 일을 할 수 있는 { }를 가진 method
  • abstract method를 가진다

04

접근지정자 interface 인터페이스명 extends 부모인터페이스명, ... {

    // 상수

    // abstract method, interface에선 abstract 사용안해도 추상메소드
    접근지정자 반환형 method명(매개변수,..);
    접근지정자 abstract 반환형 method명(매개변수,..);

    // default method
    접근지정자 default 반환형 method명(매개변수명,.. ) {

    }

}
/* 접근지정자
public  (패키지 외부에서 접근가능)
default (패키지 접근지정자, 패키지 내에서만 접근 가능)
*/

05


인터페이스 상속, 구현 예제

06

  • 인터페이스는 여러 부모인터페이스를 상속할 수 있다.
    • 인터페이스간 상속 시 추상 method를 Override하지 않는다.
    • 구현 클래스가 모든 추상 method를 Override한다.
public interface InterA {
  public String msgA();
}

public interface InterB {
  public String msgB();
}

public interface SuperInterface extends InterA, InterB {
     
  // 상수
  public static final int FLAG_VALUE = 12;
  
  // 추상메소드
  // "abstract" 없어도 abstract method다.
  public void methodA(); 
  public abstract void methodB(String i);
}
// 인터페이스를 구현하는 클래스
public class InterfaceImplements implements SuperInterface {
  @Override
  public String msgA() { // InterA
    return "오늘은 월요일";
  }
  @Override
  public String msgB() { // InterB
    return "내일은 화요일";
  }
  @Override
  public void methodA() { // SuperInterface
    System.out.println("methodA");
  }
  @Override
  public void methodB(String i) { // SuperInterface
    System.out.println("methodB i=" + i);
  }
  public void test() { // InterfaceImplements
    System.out.println("test method");
  }

  public static void main(String[] args) {

    // 자식클래스로 객체화하면 모든 method 호출 가능
    InterfaceImplements ii = new InterfaceImplements();
    System.out.println("-----InterfaceImplements  Instantiation-----");
    System.out.println(ii.msgA());
    System.out.println(ii.msgB());
    ii.methodA();
    ii.methodB("Hi");
    ii.test();

    // is-a 관계의 객체화
    // is-a 관계의 객체화는 메소드 접근에 제한을 줄 수 있다.
    System.out.println("-----SuperInterface is-a-----");
    SuperInterface si = new InterfaceImplements();
    System.out.println(si.msgA());
    System.out.println(si.msgB());
    si.methodA();
    si.methodB("hi");

    System.out.println("-----InterA is-a-----");
    InterA ia = new InterfaceImplements();
    System.out.println(ia.msgA());

    System.out.println("-----InterB is-a-----");
    InterB ib = new InterfaceImplements();
    System.out.println(ib.msgB());

    // interface는 객체화되지 않는다.
    // InterA ia1 = new InterA();
  }
}

default method

  • 인터페이스 내부에 일을 기술할 수 있는 method
  • default method를 사용하게 되면 인터페이스가 추상클래스와 비슷해짐
public interface UseDefault {
  public void test();
  
  public default void temp() {
    System.out.println("default method - temp method");
  }
}

public class UseDefaultMethod implements UseDefault {
  @Override
  public void test() {
    System.out.println("Override한 method");
  }
  public static void main(String[] args) {
    
    // 자식클래스로 객체화
    UseDefaultMethod udm = new UseDefaultMethod();
    udm.test();
    udm.temp(); // default method
    
    // is-a 관계의 객체화
    UseDefault ud = new UseDefaultMethod();
    ud.test();
    ud.temp();  // default method
  }
}


Java