2008. 8. 13. 13:58

Part 4. 상속 III 추상 클래스와 Final

추상 클래스는 동일한 메서드로 접근 가능한 서브 클래스들을 설계하도록 하기 위해서이다.

추상 클래스는 객체를 생성할 수 없다.
정의
abstract class 클래스명 {
  abstract void 메서드명();
}
추상 메서드를 하나라도 가지면 추상 클래스로 설계해야 한다.
추상 메서드는 추상 클래스의 상속을 받는 서브 클래스에서 어떻게 동작할지 반드시 구현 되어야 한다.
===================================================================================
package training;
// 추상클래스 : 한개 이상의 추상메소드를 갖는 객체 생성을 못함
abstract class AbstractClass {
// 몸체가 없는 메소드 : 추상 메소드
 abstract void Method01();
}
// 서브클래스 : 슈퍼클래스로 추상클래스가 사용됨
// 추상 클래스를 슈퍼클래스로 갖는 서브클래스에서는
// 추상메소드를 오버라이딩 해야 한다는 강제성을 부여 받게 된다.
class SubClass extends AbstractClass{
 void Method01(){
  System.out.println("Method01");
 }
}
public class Ex01 {
 public static void main(String[] args) {
  AbstractClass ac=null; // 레퍼런스 변수 선언은 가능
  // ac=new AbstractClass(); // 객체 생성을 못함
  ac=new SubClass(); // 업캐스팅
  ac.Method01(); // 업캐스팅 후에는 서브클래스에서 오버라이딩된 메소드가 호출 됨
 }
}
===================================================================================
// 추상 클래스를 이용한 다형성 : 구체적인 동작은 다르더라도 접근방식은 동일하게
package training;
abstract class Shape{
 public abstract void draw(); // 동일해야하는 접근 방식을 추상메소드로
}
class Circ extends Shape{
 public void draw(){
  System.out.println("원을 그리다");
 }
}
class Rect extends Shape{
 public void draw(){
  System.out.println("사각형을 그리다");
 }
}
class Tri extends Shape{
 public void draw(){
  System.out.println("삼각형을 그리다");
 }
}
public class Ex02 {
 public static void poly(Shape s){
  s.draw();
  // 3 객체 모두에 적용될 공통적인 로직을 기술한다. (길면 길수록 유용)
 }
 public static void main(String[] args) {
  poly(new Circ());
  poly(new Rect());
  poly(new Tri());
  /*Shape s=null; // 객체는 생성하지 못하더라도 레퍼런스 변수 선언은 가능하다.
  s=new Circ();
  s.draw();
  s=new Rect();
  s.draw();
  s=new Tri()
  s.draw();*/
 }
}
===================================================================================
final
사용 범위 : 변수, 메서드, 클래스
final 변수 : 변수를 상수화 시켜서 저장된 값이 변하지 않는다.
final 메서드 : 서브클래스에서 오버라이딩을 허용하지 않는다.
final 클래스 : 상속이 허용되지 않는다.

===================================================================================
package training;
class FinalTest{
 final int A=10; // 이름이 있는 상수
 // int a=10; // a는 변수
 final public int getA(){
  return A;
 }
}
final class SubTest extends FinalTest{
 // FinalTest 클래스의 final getA() 메소드는 오버라이딩이 불가능
 /*public int getA(){
  return A;
 }*/
}
/*class SubEx extends Subtest{ // final SubTest는 서브클래스를 만들 수 없다.
 
}*/
public class Ex04 {
 
 public static void main(String[] args) {
  FinalTest ft=new FinalTest();
  // ft.a=20; // final로 선언된 변수는 상수화되어 값을 변경할 수 없기에 대입연산자 왼쪽에 못옴
  // 10=20; // 상수는 값이 변할수 없기에 대입연산자 왼쪽에 못옴
  System.out.println(ft.A);
 }
}
===================================================================================