프로그래밍/Java 공부

abstract 추상화, interface 인터페이스, polymorphism 다형성

개발계발게발 2021. 6. 9. 16:12
반응형

abstract 추상화

 

클래스 만드는 목적? -> 인스턴트 생성을 위해

추상화는 클래스를 대략적으로 만드는 것으로 인스턴스를 생성할 수 없다.
 
  자바에서는 추상화라는 개념을 구현할 수 있다.
  추상이라는 것은 현실화 되어질 필요가 없는 클래스를 말한다.
 
  자바에서는 객체지향을 통해 프로그램이 실행되는데 이 추상이라는 개념을
  클래스에 적용시키면  자신의 인스턴스를 발생시킬 수 없는 형태로 만들어진다.
 
  이렇게 인스턴화 할 필요는 없지만 상속개념에서 중요한 위치를 가지는 클래스를
  보통 추상 클래스로 선언하여 사용

추상 클래스 선언 규칙
 
  1. 클래스에 정의된 메소드 중 추상 메소드가 하나라도 있다면
  해당 클래스는 무조건 추상 클래스가 된다.
 
  2. 추상 메소드는 메소드 바디가 없는 형태 {}
  abstract 라는 키워드를 리턴 타입 앞에 선언
  파라미터 괄호()뒤에 세미콜론;을 붙여 준다.
  public void print();
 
  3. 추상 클래스는 자신의 인스턴스를 발생시킬 수 없다.
  하지만 생성자, 메소드, 필드는 모두 선언/정의 가능
  상속도 가능하다. 또한 super type으로 전개 가능하므로 다형성도 적용 가능
 
  4. 만약 추상 메소드가 하나라돌 없을 때 클래스를 추상화 하고 싶다면
  abstract라는 키워드를 붙여서 추상화 시킬 수 있다.

 

abstract class Animal {// 부모 클래스, 슈퍼 클래스, 상위 클래스
	String name;
	int age;

	public abstract void sleep();	//강제

	public abstract void eat();
}

class Cat extends Animal {// 자식 클래스, 하위 클래스

	@Override
	public void sleep() {
		System.out.println(this.name + "가 잠을 잡니다.zzzz");
	}

	@Override
	public void eat() {
		System.out.println(this.name + "가 밥을 먹습니다. 쿰척쿰척");
	}

}

class Dog extends Animal {

	@Override
	public void sleep() {
		
	}

	@Override
	public void eat() {
		
	}
}

public class Abstraction {
	public static void main(String[] args) {
		Cat cat = new Cat();
		Dog dog = new Dog();
		// Animal animal = new Animal(); 불가
		cat.eat();
		
	}
}

 

public abstract class Animal {
	String name;	
	public void setName(String name) {
		this.name = name;		
	}
}
public class Cat extends Animal {}
public class Dog extends Animal {}

public class ZooTrainer {	
//	public void feed(Cat cat) {
//		System.out.println(cat.name + "에게 먹이주기");
//	}
//	public void feed(Dog dog) {
//		System.out.println(dog.name + "에게 먹이주기");		
//	}
	
	public void feed(Animal animal) {
		System.out.println(animal.name + "에게 밥주기");
	}
	
	public static void main(String[] args) {
		Cat c01 = new Cat();
		c01.setName("R2d2");
		
		ZooTrainer trainer = new ZooTrainer();
		
		trainer.feed(c01);	//R2d2에게 먹이주기
		
		Dog d01 = new Dog();
		d01.setName("3PO"); 
		
		trainer.feed(d01);	//3PO에게 먹이주기	
	}
}

 

 

interface 인터페이스

다른 언어에서 찾기 힘든 자바의 고급 기능
단일 상속의 한계 극복

인터페이스란?
추상 클래스 = 대략 만들어진, 추상적인, 추상화
추상 클래스는 일반 메소드와 추상 메소드 둘 다 가질수 있다.
인터페이스는 오로지 추상 메소드와 상수만 가질 수 있다.

 

인터페이스 내에 존재하는 메소드는 무조건
public abstract로 선언

인터페이스 내에 존재하는 변수는 무조건
public static final로 선언

인터페이스는 다중상속과 비슷한 기능을 제공

인터페이스는 외부를 서로 이어주는 통로 역할

생성하기

interface 인터페이스명{ 
 public abstract void(); // 추상 메소드 
 } 


사용하기

class 클래스명 implements 인터페이스명, 인터페이스명...{ 
 인터페이스에서 미구현 된 메소드 오버라이드; 
} 


인터페이스 구현시 주의할 점


클래스에 인터페이스 상속시 인터페이스 내에 정의된 모든 추상 메소드를 구현해야 한다.

상속과 인터페이스의 차이점

상속 class A extends B
 B라는 클래스를 상속받아 A의 기능을 더한다.
 순수 상속 : 부모로부터 모든 권한과 재산 능력을 가져오기

인터페이스 class A implements B
 B라는 인터페이스를 구현하겠다.
 권한 상속 : 인터페이스만 가져오기 : 비어있는 것을 가져와서 구현

interface SayHi{
	//정적 변수
	//정적 메소드, 동적 메소드
	public static final int NUMBER = 0;
	public void sayHi();	//추상메소드
	public void sayBye();	//추상메소드
	public void sayBye(int number); //추상메소드
}

class Say implements SayHi{
	@Override
	public void sayHi() {	//인터페이스에 있는 미구현 메소드 구현하기
		System.out.println("Hi");
	}

	@Override
	public void sayBye() {	//인터페이스에 있는 미구현 메소드 구현하기
		System.out.println("Bye");
	}

	@Override
	public void sayBye(int number) {	//인터페이스에 있는 미구현 메소드 구현하기
		
	}
}

public class Interface01 {
	public static void main(String[] args) {
		Say sa = new Say();
		sa.sayHi();		//Hi
		sa.sayBye();	//Bye
	}	
}
class Hero{
	public void attack() {
		System.out.println("공격");
	}
	public void defend() {
		System.out.println("막기");
	}
}

//날아다니기, 먹기, lazer,
interface Fly{
	public void fly();
}
interface Eat{
	public void eat();	
}
interface Lazer{	//관련성 있는 것끼리 조합
	public void shoot();
}

class Ironman extends Hero implements Fly, Eat, Lazer{

	@Override
	public void shoot() {}
	
	@Override
	public void eat() {}

	@Override
	public void fly() {}	
}

class Hulk extends Hero implements Eat{
	@Override
	public void eat() {
		
	}	
}

public class Interface02 {	

}

 

 

Polymorphism 다형성

 

다양한 형태로 변할 수 있는 것

 다형성은 동적 바인딩(런타임 때 최종 타입이 결정되는 것)이 지원되어야 한다.

다형성:
 같은 타입이지만 실행결과가 다양한 객체를 이용할 수 있는 성질을
 말한다. 코드 측면에서 보면 다형성은 하나의 타입에 여러 객체를
 대입함으로써 다양한 기능을 이용할 수 있도록 해준다.
 다형성을 위해 자바는 부모 클래스로 타입 변환을 허용해준다.
 즉 부모타입에 모든 자식객체가 대입될 수 있다.
 이것을 이용하면 객체의 부품화 가능

 

class Hero{
	public String name;
	public void attack() {
		System.out.println("공격");
	}
	
}
class Ironman extends Hero{
	public String spot = "하늘";
	int suitCount;
	
	public void makeSuit() {
		System.out.println("Javis, 슈트 만들어 줘.");
	}
	
	@Override	
	public void attack(){
		System.out.println("Javis, 공격");		
	}	
}

class Hulk extends Hero{
	public String spot = "땅";
	
	public void change() {
		System.out.println("헐크 변신");
	}
	@Override
	
	public void attack() {
		System.out.println("주먹");
	}
	
}
class Spiderman extends Hero{
	public String spot = "바다";
	@Override
	public void attack() {
		System.out.println("거미줄 공격");
	}
}
class Thor extends Hero{
	public String spot = "번개";
	@Override
	public void attack() {
		System.out.println("번개 공격");
	}	
}

public class Polymorphism {
	public static void main(String[] args) {
		//Hero h1 = new Ironman();
		Hero h1; //컴파일타임
		h1 = new Ironman(); // 런타임
		//반드시 상위 클래스가 앞으로 와야 한다.
		
		
		h1.attack();
		
		//h1.makeSuit(); // 호출 불가
		// 변경 시켜서 쓴다.
		
		//방법1 형변환		
        ((Ironman)h1).makeSuit();
		((Ironman)h1).suitCount = 10;
        
		//방법2 
		int a = 10;
		byte ba = (byte)a;
		
		Ironman i2 = (Ironman)h1;
		i2.makeSuit();
		
		Hero[] avangers = new Hero[4];		
		
		avangers[0] = new Ironman();
		avangers[1] = new Hulk();
		avangers[2] = new Spiderman();
		avangers[3] = new Thor();

		for (Hero hero : avangers) {
			hero.attack();
		}
		for (int i = 0; i < avangers.length; i++) {
			avangers[i].attack();
		}		
	}
}

 

public class Polymorphism02 {
	public static Hero callHero(String spot) {
		if(spot.equals("하늘")) {
			return new Ironman();
		}
		else if(spot.equals("땅")) {
			return new Hulk();
		}
		else if(spot.equals("바다")) {
			return new Spiderman();
		}
		else
			return new Thor();
	}	
	public static void main(String[] args) {
		Hero h1 = callHero("바다");
		Hero h2 = callHero("땅");
		
		h1.attack();
		h2.attack();		
	}
}

 

 

 

반응형