ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [JAVA] Abstract(추상클래스)
    언어/JAVA 2022. 9. 8. 11:15

    -상속을 통한 다형성(부모클래스를 상속받아 여러형태의 자식클래스를 생성 & 활용 & type casting)을 구현함에 있어서 강제성을 부여하기 위한 클래스
    -일반적인 상속의 문제점: 강제성의 부재
    -상속을 통해 다형성(부모클래스를 상속받아 여러 형태의 자식 클래스를 생성하고 활용함)을 구현하고자 하여도, 하위클래스에서 메소드 오버라이딩을 구현하지 않으면 다형성을 완벽히 구현할 수 없음. 이때, 오버라이딩을 구현하지 않는것이 문법상 문제가 없다는 점을 강제성의 부재라고 함

    class Animal{
    	public void crying() { 
    		System.out.println("울음 소리~");  
    	}
    }
    
    class Dog extends Animal{
    	public void crying() { 	
    		System.out.println("멍~멍~"); 
    	}
    } // 부모클래스의 crying 메소드를 오버라이딩한 강아지 클래스
    class Cat extends Animal{
    }// 부모클래스의 crying 메소드를 오버라이딩 하지 않은 고양이 클래스
    
    public class Abstract01 {
    	public static void main(String[] args) {
    		Dog dog = new Dog();
    		dog.crying();
    		Cat cat = new Cat();
    		cat.crying();
    	}
    }

     

    추상메소드를 포함한 클래스: 추상 메서드를 하나이상 포함하면 추상클래스라고 부름
    추상메서드: 메소드의 원형만 존재하고 실제 내용이 없는 메소드


    추상메소드의 작성방법

    접근지정자 abstract 리턴값의타입 메소드명( 매개변수 );

    - 추상 클래스는 일반 클래스와 동일하게 일반 멤버변수 일반 메소드, 생성자 등을 포함할 수 있음.
    - 단, 추상 메소드를 포함할 수 있는 특징이 추가된 클래스
    - 추상클래스는 상속을 통한 다형성 구현을 위해서 생성됨

    abstract class AbstractAnimal{    // 추상클래스
    	public abstract void crying();    // 추상메서드
    }
    class DogA extends AbstractAnimal{
    	@Override
    	public void crying() {
    		System.out.println("멍~멍~");		
    	}
    }
    
    class CatA extends AbstractAnimal{
    	@Override
    	public void crying() {  
    		System.out.println("야옹~");	
    	}
    }
    public class Abstract02 {
    	public static void main(String[] args) {
    		DogA d = new DogA();
    		d.crying();
    		CatA c = new CatA();
    		c.crying();
    		
    		// 추상클래스는 상속전용으로 만들어지므로, 아래와 같이 단독으로 객체 생성을 하지 못함
    		// AbstractAnimal a = new AbstractAnimal(); // 에러
    		// 추상메서드를 포함하고 있는 클래스는, 말그대로 완전하지 않은 클래스상태라는 뜻
    		// 따라서 자체적인 객체 생성이 되지 않음.
    		
    		// 추상클래스로 추상클래스만의 객체를 만들수는 없지만
    		// 추상클래스(부모)의 레퍼런스 변수로, 자식클래스의 인스턴스 주소는 저장 가능
    		// AbstractAnimal a = new AbstractAnimal(); X
    		// AbstractAnimal b = new DogA();  O
    		// AbstractAnimal c = new CatA();  O
    		AbstractAnimal dog = new DogA();
    		AbstractAnimal cat = new CatA();
    		dog.crying();
    		cat.crying();
    		dog.addAge();
    		cat.addAge();
    		
    		increamentAge(d);
    		increamentAge(c);
    		
    	}
    	// 자식 클래스의 인스턴스를 전달인수로 보내면, 
    	// 함수의 매개변수인 부모 레퍼런스가 받아서 사용할 수 있음
    	public static void increamentAge( AbstractAnimal animal ) {
    		animal.addAge();
    	}
    
    }

     

    추상 클래스의 단점
    - 추상 메소드 구현의 강제성이 아래의 경우 단점이 될 수 있음
    - 추상 메소드의 갯수가 많으면 상속에 부담을 주게 됨
    - 자식 클래스에서 사용하지 않을 추상 메소드라도, 객체 생성을 위해 반드시 구현해야 하는 문제점이 있음

    abstract class AbstractA{
    	public abstract void test1();
    	public abstract void test2();
    	public abstract void test3();
    	public abstract void test4();
    	public abstract void test5();
    	public abstract void test6();
    	public abstract void test7();
    }
    
    class AbstractA_Sub1 extends AbstractA{
    	@Override
    	public void test1() {}
    	@Override
    	public void test2() { }
    	@Override
    	public void test3() { }
    	@Override
    	public void test4() { }
    	@Override
    	public void test5() { }
    	@Override
    	public void test6() { }
    	@Override
    	public void test7() { }
    }
    // AbstractA 클래스를 상속 받은 클래스는 필요없는 메서드가 있어도, 추상매서드를 모두 오버라이드(구현)해야함
    
    // 모든 추상매서드가 구현(오버라이드)된 AbstractA_Adapter 클래스를 생성하고,
    // 이 클래스를 상속받아 사용하면 필요없는 매서드를 강제로 구현(오버라이드)하지 않고 
    // 필요한 것만 구현하여 사용 가능
    class AbstractA_Adapter extends AbstractA {
    	@Override
    	public void test1() { }
    	@Override
    	public void test2() { }
    	@Override
    	public void test3() { }
    	@Override
    	public void test4() { }
    	@Override
    	public void test5() { }
    	@Override
    	public void test6() { }
    	@Override
    	public void test7() { }
    }
    class AbstractA_Sub2 extends AbstractA_Adapter {
    	public void test1() {
    		System.out.println("test1 오버라이딩~!");	
    	}
    }
    
    public class Abstract03 {
    	public static void main(String[] args) {
    		// 어댑터 클래스를 상속받은 클래스도 추상클래스의 자식(손자)클래스가 됨
    		AbstractA obj = new AbstractA_Sub2();
    		obj.test1();
    		// 할아버지 손자간 다형성을 구현하여 물려주고 오버라이딩된 메서드를 할아버지 레퍼런스가 사용 가능
    		
    		// 함수의 전달인수로 손자인스턴스 주소를 보내고, 
    		// 함수의 매개변수로 할아버지 레퍼런스 사용이 아래와 같이 가능함
    		test( obj );
    	}
    	public static void test( AbstractA object1 ) {
    	}
    }

    '언어 > JAVA' 카테고리의 다른 글

    [JAVA] Exception(예외처리)  (0) 2022.09.08
    [JAVA] Interface  (3) 2022.09.08
    [JAVA] Formatter  (0) 2022.09.08
    [JAVA] Collection  (0) 2022.09.08
    [JAVA] String Class  (0) 2022.09.08

    댓글

Designed by Tistory.