티스토리 뷰

1.    요약

-      instanceof : 타입변환을 해야 될 때, 먼저 자식 타입인지 확인 후에 강제형변환을 시킬 때 사용한다.

-      객체 instanceof 타입 형태로 사용되는데, parent instanceof child라고 하면 parent라는 매개변수가 참조하는 객체가 child인지 조사하는 것이다.

-      Instanceof를 사용하기 위해서는 부모 / 자식 관계기 형성되어 있어야 한다.

 

2.    추상 클래스 ( Abstract Class )

-      추상 : 실체들 간에 공통되는 특성을 추출한 것이다.

-      EX. , 강아지, 고양이, 햄스터 - > 동물 ( 추상 )

-      추상클래스 :

-      실체 클래스들의 공통되는 필드와 메소드를 정의한 클래스

-      추상 클래스는 실체 클래스의 부모 클래스 역할을 한다.

-      여러 실체들의 공통적인 부분을 추상한 것이기에, 객체 생성이 불가능 하다. ( 단독 객체 X )

-      , 객체 생성이 불가능하다는 것이지 자식 클래스가 없다는 것이 아니다.

-      추상 클래스의 용도 :

-      1 ) 실체 클래스의 공통된 필드와 메소드의 이름을 통일할 목적으로 사용

-      2 ) 상속을 통해 실체 클래스를 작성할 때 시간을 절약이 가능

-      3 ) 실체 클래스 설계 규격을 만들고자 할 때 사용

-       + 실체 클래스는 무조건 추상 클래스를 상속 받아 작성한다.

-      추상 클래스 선언 : 클래스 선언부에 public abstract class 클래스명으로 작성한다.

-      이를 통해서 New연산자로 객체를 생성하지 못하게 하고 상속을 통해 자식 클래스만 생성이 가능해진다.

 

3.    인터페이스 ( interface - 참조타입 중 하나 )

-      멤버 :

-       . Static final 상수 선언

-       . 추상메소드 선언

-       . 디폴트 메소드 ( 인스턴스 메소드 )

-       . 정적 메소드 ( clazz에 소속된 메소드 )

 

4.    인터페이스의 역할 p.346

-      인터페이스 : 개발 코드와 객체가 서로 통신하는 접점을 의미한다.

-      개발코드가 객체에 종속되지 않게 하여, 객체를 교체할 수 있도록 하는 역할

-      개발 코드 변경 없이 리턴값 또는 실행 내용이 다양해질 수 있다. ( 다형성 )

-      인터페이스의 선언 : [ public / default ] interface 인터페이스 명 { … }

-      인터페이스 선언 중괄호 { } 내에서는 static final 상수, 추상 메소드, 디폴트 메소드, default 타입과 static 타입의 메소드가 올 수 있다.

-      이를 통해 인터페이스가 부모 역할을 하고 있음을 알 수 있다.

 

5.    인터페이스의 구현

-      인터페이스의 추상 메소드에 대한 실체 메소드를 가진 객체를 구현 객체라고 부른다.

-      구현 객체를 생성하는 클래스를 구현 클래스라고 부른다.

-      구현 클래스는 implements 키워드로 명시한다.

-      Ex. public class 구현클래스명 implements 인터페이스명 { // 인터페이스에 선언된 추상 메소드의 실체 메소드 선언 }

-      이용할 수 있다는 것이지 상속받는 것이 아니기에, this.을 활용할 수 없다.

-      인터페이스의 이름 앞에는 대문자 I를 붙이고, 구현 클래스에서는 Impl를 붙이는 것이 관례이다.

-      인터페이스의 경우, 상속과 다르게 다수상속이 가능하다!

-      Ex. public class 구현클래스명 implements 인터페이스A, 인터페이스B {

-      // 인터페이스 A에 선언된 추상 메소드의 실체 메소드 선언

-      // 인터페이스 A에 선언된 추상 메소드의 실체 메소드 선언 }

-      이때 구현클래스명은 인터페이스A와 인터페이스B 모두 충족시켜야 한다.

-      이때 이름 충돌이 발생하게 된다면, import문이 다른 곳으로 지정될 수 있으니 컨트롤 키를 활용하여 잘 확인해야 한다.

-      만약 잘 못 연결되었을 경우, import을 직접 작성하여 해결하는 방법도 있다.

 

6.    인터페이스 - 익명 구현 객체

-      익명 구현객체 : 명시적인 구현 클래스를 작성하는 것을 생략하고, 바로 구현 객체를 얻는 방법이다.

-      이름 없는 구현 클래스를 선언하는 동시에 객체를 생성한다.

-      Ex. 인터페이스 변수 = new 인터페이스 ( ) { // 인터페이스에 선언된 추상 메소드의 실체 메소드 선언 } ;

-      익명 구현 객체는 주로 추상 메소드가 1-2개일 때, 사용된다.

-       + 원래 인터페이스는 추상 클래스와 같이 객체 생성이 불가능 하다.

-      인터페이스의 추상 메소드들은 모두 재정의하는 메소드가 있어야 한다.

-      추가적인 필드와 메소드를 선언하는 것은 가능하지만, 익명 객체 내에서만 사용이 가능하다.

-      그리고 익명구현객체는 인터페이스 변수로 접근하는 것이 불가능하다.

 

7.    인터페이스 - 디폴트 메소드

-      디폴트 메소드는 인터페이스만으로는 사용이 불가능 하다.

-      구현 객체가 인터페이스에 대립되어야만 인스턴스 메소드인 디폴트 메소드를 호출할 수 있다.

-      디폴트 메소드는 필요에 따라 구현 클래스가 디폴트 메소드를 재정의해 사용한다.

디폴트 메소드는 public default void setMute(boolean mute) { } 와 같이 작성한다.


01. 추상 클래스

 

package obstract_class;

 

public abstract class Phone { // 추상 클래스 선언 (***)

      

       // 1. 공통필드

       public String owner;

      

       // 2. 생성자

       public Phone (String owner) {

             this.owner = owner;

       } // constructor

      

       // 추상 클래스는 단독 객체, 객체 생성이 불가능 하여 생성자를 만들 수 있다는 것이 의문일 수는 있으나

       // 자식 클래스는 실체가 있는 콘크리트 클래스이기에, 생성자를 만드는 것이 가능하다.

      

       // 3. 공통 메소드

       public void turnOn() {

             System.out.println("폰 전원을 킵니다.");

       } // turnOn

      

       public void turnOff() {

             System.out.println("폰 전원을 끕니다.");

       } // turnOff

 

} // end class


package obstract_class;

 

public class SmartPhone extends Phone {

      

       // 1. 생성자

       public SmartPhone (String owner) {

             super(owner); // 부모객체를 먼저 생성해야 한다. (***)

       } // smartPhone constructor

      

       // 2. 메소드

       public void internetSearch() {

             System.out.println("인터넷 검색을 합니다.");

       } // internetSearch

 

} // end class


package obstract_class;

 

 

public class PhoneExample {

      

       public static void main (String[] args) {

            

//           Phone phone = new Phone // ( x ) - 객체를 생성할 수 없다는 오류 메세지가 발생한다.

             // 위 코드는 오류가 발생하게 되는데, 그 이유는 추상클래스로부터 객체를 직접 생성할 수 없기 때문이다.

             // ? 추상클래스이기에 실체가 없기 때문이다.

            

             // 1. 자식객체 생성 - 추상 클래스는 자식객체를 생성하게 된다.

             SmartPhone smartphone = new SmartPhone("홍길동");

            

            

             // 2. 부모( 추상클래스 )로부터 물려받은 메소드 호출

             smartphone.turnOn();

             smartphone.internetSearch();

             smartphone.turnOff();

            

       } // main

 

} // end class

 

02. 추상 메소드

 

package obstract_class_Animal; // 추상 메소드 (*****)

 

 

// 추상 클래스를 통해 적어도 동물이라면, 반드시 가져야 할 속성과 기능을

// 필드와 메소드로 선언하여, 이를 규격화해서, 상속받는 자식 클래스가 반드시

// 이 규격을 지키도록 해준다. ( " 추상메소드 " )

public abstract class Animal {

      

       public String kind;

      

       public void breath() {

             System.out.println("숨을 쉽니다.");

       } // breath

      

      

       // " 추상 메소드 " : 메소드의 시그니처만 있고 구현부 { }가 없다. (****)

       // 이 추상크래스를 상속받는 모든 자식클래스에서는, 이 추상메소드를 반드시

       // 구현 ( 즉, 메소드 오버라이딩(재정의) ) 해야 한다!!

       // 만일, 구현하지 않으면, 해당 자식 클래스조차 추상클래스가 되어야 한다. ( 그렇지 않으면 컴파일 오류가 난다. )

       public abstract void sound(); // : 타이어의 구격을 자식 클래스에 강제화시킴. (*****)

 

} // end class


package obstract_class_Animal;

 

public class Cat extends Animal {

      

       public Cat() {

             this.kind = "포유류";

       } // default constructor

      

       @Override

       public void sound() {

             System.out.println("야옹 ~ ");

       } // sound

      

       // 부모인 추상 클래스에 선언된, 추상 케소드를 반드시 구형(재정의, 오버라이드) 해야 한다!! (**)

       // 만일, 자식 클래스에서 구현(재정의)하지 않으면, 자식 클래스조차 abstract 키워드로

       // 추상클래스화 해야 한다!! ( why? 강제사항인 구격을 지키지 않았기 때문이다. )

 

} // end class


package obstract_class_Animal;

 

public class Dog extends Animal {

      

       public Dog() {

             this.kind = "포유류";

//           super.kind = "포유류"; // 이는 부모 클래스에 있는 값을 바꾼 것이다. 그러므로 this.을 사용하도록 하자!

       } // default constructor

        

//     부모인 추상클래스에 선언된, 추상메소드( 강제 규격 )을 구현 ( 재정의 )

       @Override

       public void sound() {

             System.out.println("멍멍!");

       } // sound

 

} // end class


package obstract_class_Animal;

 

public class AnimalExample {

      

       public static void main (String[] args ) { // 추상 클래스의 자동형변환

            

             // 1. 객체 생성

             Dog dog = new Dog();

             Cat cat = new Cat();

            

             // 2. 각 자식객체가 구현한 소리를 발생시킴

             dog.sound();

             cat.sound();

            

             // 자식클래스의 객체를 단순하게 호출한 것이다. ( 다형성 X )

            

             System.out.println("===== 사용(이용)관계로써, 자식객체 활용 =======");

            

             // 변수의 자동 타입 변환 (******)

            

             Animal animal = null; // 부모타입 변수 선언 (******)

            

             animal = new Dog(); // 다형성 1 - 부모가 자식을 감싼다.

             animal.sound(); // 다형성 2 - 오버라이딩 ( 재정의 )

             animal = new Cat();

             animal.sound();

             System.out.println("================================================");

            

             // 매개변수의 자동타입 변환 (****)

             animalSound(new Dog());

             animalSound(new Cat());

            

             // 자식 클래스를 매개변수로 주고 있다.

             // Animal animal = new Dog();와 같은 의미

            

       } // main

      

       public static void animalSound(Animal animal) {

             // 자식 클래스를 매개변수로 주고 있기에, Animal animal = new Dog();와 같은 의미이다.

             animal.sound(); // 다형성2

       } // animalSound

      

//     출력 결과 :

//    

//     멍멍!

//     야옹 ~

//     ===== 사용(이용)관계로써, 자식객체 활용 =======

//     멍멍!

//     야옹 ~

//     ================================================

//     멍멍!

//     야옹 ~

 

} // end class

 

03. 인터페이스

 

package Interface; // 인터페이스

 

 

public interface RemoteControl { // 리모콘이 반드시 공통적으로 가지고 있는 기능을 규격화시킨다. (***)

      

       // 인터페이스의 모든 멤버는 반드시 public 접근제한자를 사용해야 한다!!!! (***)

      

       // 1. 인터페이스에 선언할 수 있는 멤버로 static final 상수 선언

       public static final int MAX_VOLUME = 10;

//     int MIN_VOLUME = 0; // OK!! 인터페이스에서는 public static final를 자동으로 입력해 준다.

       public static final int MIN_VOLUME = 0;

       // 하지만 인터페이스에서는 public만 가능하다는 사실을 까먹을 수 있으니, public static final int를 모두 작성하도록 하자!

      

       // 인터페이스는 추상 클래스와 같이 객체 생성이 불가능 하다.

      

       // 2. 추상 메소드 ( 강제규격 ) - 자식 객체가 반드시 구현해야 할 기능을 선언 (***)

       // 추상 메소드를 통해서 다형성 구현

//     void turnOn(); // OK!! public abstract을 생략해도 자동으로 입력해 주지만, 가독성이 떨어지기에 지양해라!

       public abstract void turnOn();

       public abstract void turnOff();

       public abstract void setVolume(int volume);

      

//     =============================================== 자바 8 이후

      

       // 3. 디폴트 메소드 ( 완전한 인스턴스 메소드이다! ) -> 객체없이는 사용이 불가능 하다!

      

       // ? 근데 인터페이스는 객체 생성이 불가능하다면서??!

       // - > 그렇기에, 인터페이스를 활용하여 인터페이스에 있는 인스턴스 메소드를

       // 인터페이스 규격을 지키고 있는 자식이 사용할 수 있게 해주고 있다.

      

       public default void setMute(boolean mute) {

             if(mute) {

                    System.out.println("무음 처리합니다.");

             } else {

                    System.out.println("무음을 해제합니다.");

             } // if - else

       } // default method - setMute

      

       // 4. 정적 메소드

       public static void changeBattery() {

             System.out.println("건전지를 교환합니다.");

       }// changeBattery

      

} // end interface


package Interface;

 

import lombok.ToString; // Import를 꼭 적용시켜야 한다!!

 

@ToString // 실행클래스에서 출력할 때, 필드 내부를 볼 수 있도록 해준다! (*****)

public class Audio implements RemoteControl {

      

       // 1. 인스턴스 필드

       private int volume;

      

      

//     -------------------- 인터페이스의 규격을 구현 ( 재정의 ) -----------------------

      

       // 2. 추상 메소드의 실체 메소드

      

       @Override

       public void turnOn() {

             System.out.println("Audio를 켭니다.");

       } // turnOn

      

       @Override

       public void turnOff() {

             System.out.println("Audio를 끕니다.");

       } // turnOff

      

       @Override

       public void setVolume ( int volume ) {

             if ( volume > RemoteControl.MAX_VOLUME) {

                    this.volume = RemoteControl.MAX_VOLUME;

             } else if ( volume < RemoteControl.MIN_VOLUME) {

                    this.volume = RemoteControl.MIN_VOLUME;

             } else {

                    this.volume = volume;

             } // if - else if - else

            

             System.out.println("현재 Audio 볼륨 : " + volume );

            

       } // setVolume

 

} // end class


package Interface;

 

public class Television implements RemoteControl {

      

       // 1. 인스턴스 필드

       private int volume;

      

      

//     -------------------- 인터페이스의 규격을 구현 ( 재정의 ) -----------------------

      

       // 2. 추상 메소드의 실체 메소드

      

       @Override

       public void turnOn() {

             System.out.println("TV를 켭니다.");

       } // turnOn

      

       @Override

       public void turnOff() {

             System.out.println("TV를 끕니다.");

       } // turnOff

      

       @Override

       public void setVolume ( int volume ) {

             if ( volume > RemoteControl.MAX_VOLUME) {

                    this.volume = RemoteControl.MAX_VOLUME;

             } else if ( volume < RemoteControl.MIN_VOLUME) {

                    this.volume = RemoteControl.MIN_VOLUME;

             } else {

                    this.volume = volume;

             } // if - else if - else

            

             System.out.println("현재 TV 볼륨 : " + volume );

            

       } // setVolume

 

} // end class


package Interface;

 

public class RemoteControlExample {

      

       public static void main (String [] args) {

            

             RemoteControl rc; // 부모타입 ( 인터페이스 )

            

             rc = new Television( ); // 다형성 1

             System.out.println("rc1 : " + rc); // 출력 : rc1 : Interface.Television@2f92e0f4

            

             // + 모를때는 일단 출력해보고 결과를 확인해 보자!!

            

             rc.turnOn(); // 다형성 2 : 출력 - TV를 켭니다.

             rc.turnOff(); // 다형성 2 : 출력 - TV를 끕니다.

            

             rc = new Audio(); // 다형성 1

             System.out.println("rc2 : " + rc); // 출력 : rc2 : Interface.Audio@5305068a

            

             // Audio구현 클래스에 @ToString을 붙이자 " rc2 : Audio(volume=0) "로 출력이 되었다.

             // 이는 출력 당시의 필드 내부를 출력해주는 것이다.

            

             rc.turnOn(); // 다형성 2 : 출력 - Audio를 켭니다.

             rc.turnOff(); // 다형성 2 : 출력 - Audio를 끕니다.

            

       } // main

 

} // end class

 

04. 인터페이스 - 익명구현객체

 

package Interface02;

 

public interface RemoteControl {

      

       public static final int MAX_VOLUME = 10;

       public static final int MIN_VOLUME = 0;

 

       public abstract void turnOff();

       public abstract void setVolume(int volume);

      

 

      

       public default void setMute(boolean mute) {

             if(mute) {

                    System.out.println("무음 처리합니다.");

             } else {

                    System.out.println("무음을 해제합니다.");

             } // if - else

       } // default method - setMute

      

       public static void changeBattery() {

             System.out.println("건전지를 교환합니다.");

       }// changeBattery

 

} // end class


package Interface02;

 

import Interface.RemoteControl;

 

public class RemoteControlExample {

      

       public static void main (String [] args) {  // 익명구현객체 (*****)

            

             RemoteControl rc = new RemoteControl() {

                   

                    String name = "Yoseph"; // 필요시에 필드를 추가할 수 있다.

                    int age = 23;

                   

                    public void instanceMethod() {

                           System.out.println("instanceMethod() invoked."); // 메소드도 만들 수는 있다.

                    } // instanceMethod

                   

                    // 익명구현객체 선언시, 내부에 선언한 추가적인 필드와 메소드는

                    // 참조변수명.필드/메소드 형식으로 ( rc.turnOn(); )

                    // 사용불가! = > 추가적인 필드와 메소드는 익명구현객체 블록 내에서만 사용해라!!

 

                    @Override

                    public void turnOn() {

                          

                           System.out.println("turnOn() invoked. name : " + this.name);

                          

                    } // turnOn

 

                    @Override

                    public void turnOff() {

                          

                           System.out.println("turnOff() invoked. age : " + this.age);

                          

                           System.out.println("\t + this : " + this); // + this:Interface02.RemoteControlExample$1@2f92e0f4

                           // 이때 this는 익명 구현 객체인 자신임을 알 수 있다.

            

                    } // turnOff

 

                    @Override

                    public void setVolume(int volume) {

                          

                           System.out.println("setVolume() invoked.");

                          

                    } // setVolume

 

             }; // 익명 구현 객체 생성

            

             rc.turnOn();

             rc.turnOff();

             rc.setVolume(RemoteControl.MAX_VOLUME);

            

             System.out.println("rc : " + rc); // 출력 : rc : Interface02.RemoteControlExample$1@2f92e0f4

             // 이 중 $1은 익명구현객체라는 의미이며, 늘어날 때마다 $ 뒤의 숫자가 증가한다.

            

       } // main

 

} // end class

 

05. 인터페이스 - 디폴트 메소드

 

package Interface03;

 

public interface RemoteControl {

      

       public static final int MAX_VOLUME = 10;

       public static final int MIN_VOLUME = 0;

 

       public abstract void turnOn();

       public abstract void turnOff();

       public abstract void setVolume(int volume);

      

 

      

       public default void setMute(boolean mute) {

             if(mute) {

                    System.out.println("무음 처리합니다.");

             } else {

                    System.out.println("무음을 해제합니다.");

             } // if - else

       } // default method - setMute

      

       public static void changeBattery() {

            

             System.out.println("건전지를 교환합니다.");

            

       }// changeBattery

 

} // end class


package Interface03;

 

public interface Searchable {

      

       public abstract void search(String url);

 

} // end class


package Interface03;

 

import Interface03.RemoteControl;

 

public class SmartTelevision implements RemoteControl, Searchable {

      

       // RemoteControl과 Searchable을 상속 받고 있음을 알 수 있다. - 다중상속

       // 첫번째 인터페이스, RemoteControl에 선언된 추상메소드의 재정의

      

       private int volume;

      

       @Override

       public void turnOn() {

             System.out.println("TV를 켭니다.");

       } // turnOn

      

       @Override

       public void turnOff() {

             System.out.println("TV를 끕니다.");

       } // turnOff

      

       @Override

       public void setVolume ( int volume ) {

             if ( volume > RemoteControl.MAX_VOLUME) {

                    this.volume = RemoteControl.MAX_VOLUME;

             } else if ( volume < RemoteControl.MIN_VOLUME) {

                    this.volume = RemoteControl.MIN_VOLUME;

             } else {

                    this.volume = volume;

             } // if - else if - else

            

             System.out.println("현재 TV 볼륨 : " + volume );

            

       } // setVolume

      

       // 두번째 인터페이스, Searchable에 선언된 추상메소드의 재정의

      

       @Override

       public void search(String url) {

             System.out.println(url + "을 검색합니다.");

       }

 

} // end class


package Interface03;

 

public class RemoteControlExample {

      

       public static void main(String[] args) {

            

             SmartTelevision tv = new SmartTelevision();

            

             // 다형성 1

             RemoteControl rc = tv;

             Searchable searchable = tv;

            

             // 다형성 2

             rc.turnOn();

             searchable.search("http://www.naver.com");

             // 출력 : http://www.naver.com을 검색합니다.

            

             // 디폴트 메소드 호출

             rc.setMute(false);

            

//           =========================================================

            

//           RemoteControl rc2 = null; // 객체를 생성하고 있는 것이 아니라 단순히 변수를 선언하고 있는 것이다.

//           rc2.setMute(false);

            

             // 디폴트메소드( 인스턴스 메소드 )는 객체 없이는 사용할 수 없다.

            

//           =========================================================

            

             Searchable rc3 = new Searchable() {

                   

                    @Override

                    public void search(String url) {

                          

                           System.out.println("search(url) invoked.");

                          

                    } // search

                   

             }; // rc3

            

             rc3.search("http://www.daum.com"); // 다형성 2 - 오버라이드

             // 출력 : search(url) invoked.

            

       } // main

 

} // end class

728x90
댓글
«   2024/11   »
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
최근에 올라온 글
Total
Today
Yesterday
공지사항