ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • static, final, abstract 무엇일까?
    Java 2018. 7. 19. 18:43
    반응형



    static, final, abstract 에 대한 각 용어의 개념과 실제 사용 예를 살펴봅니다.





    1. static

       - 정적이며 클래스 영역에 저장됩니다.

       - static member ( variable, method ) 를 class member라고도 표현한다.

       - 일반적으로 static modifier 는 method와 variable 앞에 명시된다.

       - 객체의 생성 없이 클래스 로딩만으로 메모리에 적재되므로 클래스명, 변수, 메소드로 접근해서 사용할 수 있다.

       - static 에서는 non-static으로 직접 접근이 불가합니다. 접근을 위해서는 반드시 객체 생성을 해야합니다.

       - non-static 에서 static 으로는 직접 접근이 가능합니다. 

          * java는 class loading ▶ bytecode 검증 ▶ 실행 단계인데요.  class loading 단계에서 static 변수와 메서드 정보가 메모리에 적재됩니다. 

          ** java memory 구조에서 설명하였듯이 class area(method area)에 class meta 정보가 적재되고, 또한 static member정보 또한 적재됩니다.

        

       ▶ Test 클래스 안의 count는 객체가 가지는 변수라 객체를 생성할 때마다 새로 만들어지지만 scount변수는 static이라 모두에게 공유하고 있습니다.

             ① 코드에서 에러가 나는 이유는 main이 static이기 때문에 같은 클래스라도 접근이 불가능합니다.

              코드에서 Test.sCount는 따로 객체를 생성하지 않았지만 static 변수에게 접근이 가능합니다.

             ③ 코드도 Test2라는 static method에 Test라는 객체를 생성하지 않았지만 접근이 가능합니다.

             ④ 코드에서 객체를 생성하였기에 Test1()이라는 메소드에 접근할 수 있습니다. 이건 너무 당연하죠?!

    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
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    class Test {
        // 인스턴스 변수이기 때문에 명시적 초기화를 안해도 0으로 초기화 된다.
        int count;
        static int sCount;
     
        public Test() {
            count++;
            sCount++;
        }
     
        // Object member 즉 객체 생성 후에 사용가능한 메소드
        public void Test1() {
            System.out.println("Test1");
        }
        // static(or class) memeber 즉 클래스 로딩만 되면 사용가능한 메서드
        public static void Test2() {
            System.out.println("Test2");
        }
    }
     
    public class TestStatic3 {
        public void test() {
     
        }
     
        public static void main(String[] args) {
            test(); Error!! static 이므로 같은 클래스내에서라도 객체 생성 필요
            // static method 에서 non-static method 로 접근하기 위해서는 같은 클래스라도 객체 생성이 필요하다.
    new TestStatic3().test(); 
             System.out.println("scount : " + Test.sCount); // 객체 생성없이 클래스 로딩만으로 사용 가능
            ③ Test.Test2();
            
            Test t = new Test();
            ④ t.Test1();
            System.out.println("count : " + t.count);
            System.out.println("scount : " + t.sCount);
     
            Test t2 = new Test();
            System.out.println("count : " + t.count);
            System.out.println("scount : " + Test.sCount);

        }
    }
     
    cs


       ▶  결과화면

           





    2. final

       1)  final variable 

           - final로 선언된 변수는 상수가 되고, 값을 변경할 수 없습니다. 

           - final로 선어된 변수는 보통 대문자로 작성하고, 합성어는 _로 연결합니다.



       2)  final method

           - final로 선언된 메소드는 자식클래스에서 해당 메소드를 오버라이드 할 수 없습니다.



       3)  final class

          - final로 선언된 클래스는 상속이 불가능 합니다. 


        ▶ ① 코드에서 MAX_PRICE라는 final variable은 재할당이 불가능합니다.

             ② 코드에서 void test2() 라는 메소드는 final method 이므로 오바리이드할 수 없습니다.

             ③ 코드에서 SubTestFinal 클래스는 TestFinalMain이라는 final class를 상속 받을 수 없습니다.  

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    class FinalTest {
        final int MAX_PRICE = 100;  // final 이 명시되어 있으므로 상수 ( 재할당 불가 )
        void test() {
            MAX_PRICE = 200;  Error!! 상수이므로 재할당 불가
        }
        final void test2() {
            
        }
    }
     
    class SubFinalTest extends FinalTest {
        void test2() {}  Error!! final 메소드이므로 오버라이딩 불가
    }
    public final class FinalTestMain {
     
    }
    //final class는 상속 받을 수 없다.
     
    class SubTestFinal extends TestFinalMain{}  Error!!! final class는 상속받을 수 없다.
     
    cs





    3. abstract

       1) abstract class 

            - abstract 로 class를 선언하면 해당 클래스는 직접 객체화가 될 수 없습니다.

            - 자식 클래스의 생성자 내에서 super()로 인해 객체 생성은 이루어집니다.

            - class 안에 abstract method가 하나 이상 존재한다면 해당 class는 abstract로 선언되어야 합니다.

       2) abstract method      

           - abstract로 선언된 method는 구현부가 없습니다.

           - abstract로 선언된 method는 자식클래스에서 반드시 구현되어야 합니다. 그렇지 않으면 자식클래스 또한 abstract로 선언되어야 합니다.

           - abstrcat는 자식클래스에게 구현을 강제하기 위해 사용됩니다.


       ▶  ① 코드는 abstract이기 때문에 구현부 없이 선언해야하고, 자식클래스에게 구현을 강제합니다.

             ② 코드에서 Parent 클래스는 abstract이기 때문에 new Parent()라고 객체를 생성할 수 없다.

    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
    31
    abstract class Parent {
        int money = 100// instance variable
     
        public void eat() {
            System.out.println("먹다");
        }
         public abstract void study(); 
    }
    ChildOne extends Parent {
        Child() { super(); } // abstract class는 자식의 생성자를 통해 객체가 만들어 진다.
        public void study() { // 부모가 선언한 abstract method를 구현한다.
            System.out.println("공부하다");
        }
    }
    // 부모의 absract method를 구현하지 않고 abstarct class로 선언하는 방법도 있다. 하지만 직접 객체화 될 수 없는 제약이 있다. 
    abstract class ChildTwo extends Parent{} // 객체로서 존재할 수 없다.
     
    public class TestAbstract1 {
        public static void main(String[] args) {
            new Parent(); abstract class 는 직접 객체 생성될 수 없다.
            Parent p = new ChildOne();
            System.out.println(p.money);
            p.eat();
            p.study();
            
        }
    }
     
    cs


    반응형
Designed by Tistory.