문법/기본 문법

추상클래스, 인터페이스, 제어자

코딩 화이팅 2023. 1. 25. 13:09

추상클래스

  • 객체를 생성할 수 없는 클래스
  • 추상 메서드를 갖는 클래스
    추상 메서드 : 내용(구현 불가)이 없는 메서드, abstract 키워드->반드시 자식 클래스에서 오버라이드(재정의)해줘야 됨.
  • 상속 전용의 클래스
  • 클래스에 구현부가 없는 메서드가 있으므로 객체 생성 불가능
  • 상위 클래스 타입으로 자식을 참조할 수는 있다.->다형성
  • 조상 클래스에서 상속 받은 abstract 메서드를 재정의하지 않은 경우 클래스 내부에 abstract 메서드가 있으므로 자식 클래스는 abstract클래스가 되어야 함.
  • 사용하는 이유 : abstract 클래스는 구현의 강제를 통해 프로그램의 안정성 향상
package test01;

//1. 굳이 객체 생성할 필요 없음
//2. 추상 메서드를 갖는 클래스
//3. abstract 키워드
abstract public class animal {
	//추상 메서드 : 
	//1. abstract 키워드
	//2. ;으로 종료 
	//{}이 없음, 내용(구현부)없음
	abstract public void speak();
	//1. 접근제한자: public, (default), protected, private
	//2. 그외제한자(지정예약어) : static, final, abstract
	//3. 1과2의 순서는 상관이 없다.
	
	public static int a=10;
	static public int b=20;
}
=================================================================
package test01;

//일반클래스에서 추상 클래스 상속
public class cat extends animal{
	//추상클래스를 상속 받은 클래스는 추상메서드를 모두 오버라이드(재정의)해야 한다.
	
	@Override
	public void speak() {
		// TODO Auto-generated method stub
		System.out.println("야옹");
	}

}
=================================================================
package test01;

public class dog extends animal{

	@Override
	public void speak() {
		// TODO Auto-generated method stub
		System.out.println("멍멍");
	}

}
==================================================================
package test01;

public class person extends animal{

	@Override
	public void speak() {
		// TODO Auto-generated method stub
		System.out.println("새해 복 많이 받으세요");
	}

}
==================================================================
package test01;

public class test01 {
	public static void main(String[] args) {
		//추상클래스로 객체를 만들수가 있을까?
//		animal a=new animal();->불가능
		
		//다형성 가능
		animal a1=new cat();
		animal a2=new dog();
		animal a3=new person();
		
		//부모 클래스 타입의 변수이지만
		//메서드의 호출은 실제 생성된 객체가 갖고 있는 메서드가 실행됨
		a1.speak();
		a2.speak();
		a3.speak();
		
		//추상클래스를 쓰는 이유
		//1. 객체가 생성되지 못하도록 막을 때(그게 합리적일 때)
		//2. 자식 클래스에서 매서드의 재정의(오버라이드)를 강제할 때
		//3. 다형성을 이용할 때
		//4. 상속을 통한 코드 중복 제거
	}
}
package test02;

//1. 굳이 객체 생성할 필요 없음
//2. 추상 메서드를 갖는 클래스
//3. abstract 키워드
abstract public class animal {
	//추상 메서드 : 
	//1. abstract 키워드
	//2. ;으로 종료 
	//{}이 없음, 내용(구현부)없음
	abstract public void speak();
	//1. 접근제한자: public, (default), protected, private
	//2. 그외제한자(지정예약어) : static, final, abstract
	//3. 1과2의 순서는 상관이 없다.
	
	public static int a=10;
	static public int b=20;
}
===============================================================
package test02;

//일반클래스에서 추상 클래스 상속
public class cat extends animal{
	//추상클래스를 상속 받은 클래스는 추상메서드를 모두 오버라이드(재정의)해야 한다.
	
	@Override
	public void speak() {
		// TODO Auto-generated method stub
		System.out.println("야옹");
	}

}
===============================================================
package test02;

public class dog extends animal{

	@Override
	public void speak() {
		// TODO Auto-generated method stub
		System.out.println("멍멍");
	}

}
===============================================================
package test02;

//mammel은 추상클래스의 자식 클래스이지만
//굳이 객체 생성할 필요가 없음
public abstract class mammel extends animal{
	//자식 클래스도 추상클래스가 되어야함.
}
===============================================================
package test02;

public class person extends animal{

	@Override
	public void speak() {
		// TODO Auto-generated method stub
		System.out.println("새해 복 많이 받으세요");
	}

}
===============================================================
package test02;

public class test01 {
	public static void main(String[] args) {
		
	}
}
package test03;

//1. 굳이 객체 생성할 필요 없음
//2. 추상 메서드를 갖는 클래스
//3. abstract 키워드
abstract public class animal {
	//추상 메서드 : 
	//1. abstract 키워드
	//2. ;으로 종료 
	//{}이 없음, 내용(구현부)없음
	abstract public void speak();
	//1. 접근제한자: public, (default), protected, private
	//2. 그외제한자(지정예약어) : static, final, abstract
	//3. 1과2의 순서는 상관이 없다.
	
	//추상 클래스는 추상메서드도 가질 수 있지만 일반 메서드도 가질 수 있다.
	public void eat() {

	}
	
	public static int a=10;
	static public int b=20;
}
=============================================================================
package test03;

//일반클래스에서 추상 클래스 상속
public class cat extends animal{
	//추상클래스를 상속 받은 클래스는 추상메서드를 모두 오버라이드(재정의)해야 한다.
	
	@Override
	public void speak() {
		// TODO Auto-generated method stub
		System.out.println("야옹");
	}
	//자식클래스에서 독단적으로 eat메서드 추가
	public void eat() {
		System.out.println("생선을 먹어요");
	}
}
=============================================================================
package test03;

public class dog extends animal{

	@Override
	public void speak() {
		// TODO Auto-generated method stub
		System.out.println("멍멍");
	}
	public void eat() {
		System.out.println("뼈을 먹어요");
	}
}
=============================================================================
package test03;

//mammel은 추상클래스의 자식 클래스이지만
//굳이 객체 생성할 필요가 없음
public abstract class mammel extends animal{
	//자식 클래스도 추상클래스가 되어야함.
}
=============================================================================
package test03;

public class person extends animal{

	@Override
	public void speak() {
		// TODO Auto-generated method stub
		System.out.println("새해 복 많이 받으세요");
	}
	public void eat() {
		System.out.println("밥을 먹어요");
	}
}
=============================================================================
package test03;

public class test01 {
	public static void main(String[] args) {
		//자식 클래스에서 추상클래스에 없는 메서드 추가
		//eat메서드 추가
		animal a1=new cat();
		animal a2=new dog();
		animal a3=new person();
		
		a1.eat();//불가능
		//부모클래스(animal클래스)에 추상메서드 혹은 일반 메서드를 정의해놔야 부모 클래스 타입으로 참조했을 때 메서드 사용 사능
		a1.speak();
		
	}
}
package test04;

//1. 굳이 객체 생성할 필요 없음
//2. 추상 메서드를 갖는 클래스
//3. abstract 키워드
abstract public class animal {
	//추상 메서드 : 
	//1. abstract 키워드
	//2. ;으로 종료 
	//{}이 없음, 내용(구현부)없음
	abstract public void speak();
	//1. 접근제한자: public, (default), protected, private
	//2. 그외제한자(지정예약어) : static, final, abstract
	//3. 1과2의 순서는 상관이 없다.
	
//	public void eat() {
//
//	}
	
	public static int a=10;
	static public int b=20;
}
=====================================================================
package test04;

//일반클래스에서 추상 클래스 상속
public class cat extends animal{
	//추상클래스를 상속 받은 클래스는 추상메서드를 모두 오버라이드(재정의)해야 한다.
	
	@Override
	public void speak() {
		// TODO Auto-generated method stub
		System.out.println("야옹");
	}
	//자식클래스에서 독단적으로 eat메서드 추가
	public void eat() {
		System.out.println("생선을 먹어요");
	}
}
=====================================================================
package test04;

public class dog extends animal{

	@Override
	public void speak() {
		// TODO Auto-generated method stub
		System.out.println("멍멍");
	}
	public void eat() {
		System.out.println("뼈을 먹어요");
	}
}
=====================================================================
package test04;

//mammel은 추상클래스의 자식 클래스이지만
//굳이 객체 생성할 필요가 없음
public abstract class mammel extends animal{
	//자식 클래스도 추상클래스가 되어야함.
}
=====================================================================
package test04;

public class person extends animal{

	@Override
	public void speak() {
		// TODO Auto-generated method stub
		System.out.println("새해 복 많이 받으세요");
	}
	public void eat() {
		System.out.println("밥을 먹어요");
	}
}
=====================================================================
package test04;

public class test01 {
	public static void main(String[] args) {
		// 자식 클래스에서 추상클래스에 없는 메서드 추가
		// eat메서드 추가
		animal a1 = new cat();
		animal a2 = new dog();
		animal a3 = new person();

//		a1.eat();//불가능
		// 1. 부모클래스(animal클래스)에 추상메서드 혹은 일반 메서드를 정의해놔야 부모 클래스 타입으로 참조했을 때 메서드 사용 사능
		// 2. instanceof를 이용하여 형변환
//		a1.speak();

		// instanceof 연산자
		// 객체가 해당 클래스로 만든 객체이거나
		// 객체가 해당 클래스의 조상 클래스로 만든 객체인 경우 true
		// 자식클래스, 전혀 상관 없는 클래스로 만든 객체인 경우 false

		System.out.println(a1 instanceof animal);
		System.out.println(a1 instanceof cat);
		System.out.println(a1 instanceof dog);

		if (a1 instanceof cat) {
			cat c = (cat) a1;
			c.eat();
		}
		if (a2 instanceof dog) {
			dog d = (dog) a2;
			d.eat();
		}
		if (a3 instanceof person) {
			person p = (person) a3;
			p.eat();
		}
	}
}
// 조상 클래스에서 일반 메서드로 만드는 것 vs 추상 클래스
//일반 메서드->상속
//추상 메서드->상속
//(부모클래스에서) 일반 메서드를 사용하는 경우 -> 자식 클래스에서 재정의 안하고 넘어갈 수 있음
//부모클래스에서 일반 메서드, 추상 메서드 둘 다 안 만들고 자식 클래스에서 독립적으로 만들어서 사용하는 경우 -> 다형성 활용 불가능