Language/JAVA [JAVA] 초기화 및 생성자
  • 728x90
    반응형

     

     

     

    Java 초기화 및 생성자

    📌 생성자의 특징

    • 값을 반환하지 않는다.

     

    생성자는 인스턴스를 생성해주는 역할을 하는 특수한 메소드라고 할 수 있다. 그런데 반환 값이 있다면 엉뚱한 객체가 생성될 것이다. 따라서 반환 값을 필요로하는 작업에서는 생성자를 사용하지 않는다.

     

    반환 값이 없기 때문에 return도 사용하지 않고, 반환 값을 메소드 정의에 포함시키지도 않는다.

    • 생성자의 이름은 클래스의 이름과 동일하다.

     

    자바에서 클래스의 이름과 동일한 메소드는 생성자로 사용하기로 약속되어 있다.

    package test;
    
    class Calculator{
        int left, right;
        
        public Calculator(int left, int right) {
            this.left = left;
            this.right = right;
        }
        
        public void sum()
        {
            System.out.println(this.left + this.right);
        }
    
        public void avg()
        {
            System.out.println((this.left + this.right) / 2);
        }
    }
    
    public class Helloworld {
            
        public static void main(String[] args) 
        {
            Calculator c1 = new Calculator(10, 20);
            c1.sum();
            c1.avg();
            
            Calculator c2 = new Calculator(20, 40);
            c2.sum();
            c2.avg();
        }
    }

     

    6행의 클래스 명과 동일한 메소드 이것이 생성자이다.

    26행 및 30행은 생성자를 이용해서 객체를 생성하는 방법을 보여준다.

     

     

     

    상속

    상속(Ingeritance)이란 물려준다는 의미이다. 어떤 객체가 있을 때 그 객체의 필드(변수)와 메소드를 다른 객체가 물려 받을 수 있는 기능을 상속이라고 한다.

     

    아래와 같은 경우에 속한다면 객체에 메소드를 추가하는 것이 어렵다.

     

    1. 객체를 자신이 만들지 않았다. 그래서 소스를 변경할 수 없다. 변경 할 수 있다고 해도 원 소스를 업데이트하면 메소드 substarct가 사라진다. 이러한 문제가 일어나지 않게 하기 위해서는 지속적으로 코드를 관리해야 한다.
    2. 객체가 다양한 곳에서 활용되고 있는ㄴ데 메소드를 추가하면 다른 곳에서는 불필요한 기능이 포함될 수 있다. 이것은 자연스럽게 객체를 사용하는 입장에서 몰라도 되는 것까지 알아야 하는 문제가 된다.
    package test;
    
    class Calculator{
        int left, right;
        
        public void setOperands(int left, int right)
        {
            this.left = left;
            this.right = right;
        }
        
        public void sum()
        {
            System.out.println(this.left + this.right);
        }
    
        public void avg()
        {
            System.out.println((this.left + this.right) / 2);
        }
    }
    
    class Substraction extends Calculator
    {
        public void substraction()
        {
            System.out.println(this.left - this.right);
        }
    }
    
    public class Helloworld {
            
        public static void main(String[] args) 
        {
            Substraction sub = new Substraction();
            
            sub.setOperands(10, 20);
            sub.sum();
            sub.avg();
            sub.substraction();
        }
    }

    23행과 같이 extends키워드로 Calculator 클래스를 상속 받는다.

     

    부모 클래스와 자식 클래스의 관계를 상위(super) 클래스와 하위(sub) 클래스라고 표현하기도 한다.

     

    또한 기초 클래스(base class), 유도 클래스(derived class)라고도 부른다.

     

    상속한 클래스를 다시 상속하는 예제는 아래와 같다.

    package test;
    
    class Calculator{
        int left, right;
        
        public void setOperands(int left, int right)
        {
            this.left = left;
            this.right = right;
        }
        
        public void sum()
        {
            System.out.println(this.left + this.right);
        }
    
        public void avg()
        {
            System.out.println((this.left + this.right) / 2);
        }
    }
    
    class Substraction extends Calculator
    {
        public void substraction()
        {
            System.out.println(this.left - this.right);
        }
    }
    
    class Multiplicationable extends Calculator
    {
        public void multiplicationable()
        {
            System.out.println(this.left * this.right);
        }
    }
    
    class Divisionable extends Multiplicationable
    {
        public void divisionable()
        {
            System.out.println(this.left / this.right);
        }
    }
    
    public class Helloworld {
            
        public static void main(String[] args) 
        {
            Substraction sub = new Substraction();
            
            sub.setOperands(10, 20);
            sub.sum();
            sub.avg();
            sub.substraction();
            
            Divisionable div = new Divisionable();
            
            div.setOperands(10, 20);
            div.sum();
            div.avg();
            div.multiplicationable();
            div.divisionable();
        }
    }

     

     

     

    super

    super는 상위 클래스를 가리키는 키워드다. 예제를 통해서 super의 사용법을 알아보자.

     

    package test;
    
    class Calculator{
        int left, right;
        
        public Calculator() {}
        
        public Calculator(int left, int right) {
            this.left = left;
            this.right = right;
        }
        
        public void setOperands(int left, int right)
        {
            this.left = left;
            this.right = right;
        }
        
        public void sum()
        {
            System.out.println(this.left + this.right);
        }
    
        public void avg()
        {
            System.out.println((this.left + this.right) / 2);
        }
    }
    
    class Substraction extends Calculator
    {
        public Substraction(int left, int right) {
            super (left, right);        
        }
        
        public void substraction()
        {
            System.out.println(this.left - this.right);
        }
    }
    
    class Multiplicationable extends Calculator
    {    
        public void multiplicationable()
        {
            System.out.println(this.left * this.right);
        }
    }
    
    class Divisionable extends Multiplicationable
    {        
        public void divisionable()
        {
            System.out.println(this.left / this.right);
        }
    }
    
    public class Helloworld {
            
        public static void main(String[] args) 
        {
            Substraction sub = new Substraction(10, 20);
    
            sub.sum();
            sub.avg();
            sub.substraction();
            
            Divisionable div = new Divisionable();    
            
            div.setOperands(10, 20);
            div.sum();
            div.avg();
            div.multiplicationable();
            div.divisionable();
        }
    }

     

    super 키워드는 부모 클래스를 의미한다. 여기에 ()를 붙이면 부모 클래스의 생성자를 의미하게 된다.

     

    이렇게 하면 부모 클래스의 기본 생성자가 없어져도 오류가 발생하지 않는다.

     

    하위 클래스의 생성자에서 super를 사용할 때 주의할 점은 super가 가장 먼저 나타나야 한다는 점이다.

     

    즉 부모가 초기화되기 전에 자식이 초기화 되는 일을 방지하기 위한 정책이라고 생각하자.

     

     

     

    overriding

    메소드 sum이 Substraction에 추가 되었다. 실행결과는 sub.sum이 상위 클래스의 메소드가 아니라 하위 클래스의 메소드 sum을 실행하고 있다는 것을 보여준다. 하위 클래스 입장에서 부모 클래스란 말하자면 기본적인 동작 방법을 정의한 것이라고 생각할 수 있다. 하위 클래스에서 상의 클래스와 동일한 메소드를 정의하면 부모 클래스로부터 물려 받은 기본 동작 방법을 변경하는 효과를 갖게 된다. 기본동작은 폭넓게 적용되고, 예외적인 동작은 더 높은 우선순위를 갖게하고 있다.

     

    이것은 공학에서 일반적으로 발견되는 규칙이다. 이것을 메소드 오버라이딩(overriding)이라고 한다.

     

    package test;
    
    class Calculator{
        int left, right;
        
        public Calculator() {}
        
        public Calculator(int left, int right) {
            this.left = left;
            this.right = right;
        }
        
        public void setOperands(int left, int right)
        {
            this.left = left;
            this.right = right;
        }
        
        public void sum()
        {
            System.out.println(this.left + this.right);
        }
    
        public void avg()
        {
            System.out.println((this.left + this.right) / 2);
        }
    }
    
    class Substraction extends Calculator
    {
        public Substraction(int left, int right) {
            super (left, right);        
        }
        
        public void sum() {
            System.out.println("실행 결과는 " + (this.right + this.left) + "입니다.");
        }
        
        public void substraction()
        {
            System.out.println(this.left - this.right);
        }
    }
    
    class Multiplicationable extends Calculator
    {    
        public void multiplicationable()
        {
            System.out.println(this.left * this.right);
        }
    }
    
    class Divisionable extends Multiplicationable
    {        
        public void divisionable()
        {
            System.out.println(this.left / this.right);
        }
    }
    
    public class Helloworld {
            
        public static void main(String[] args) 
        {
            Substraction sub = new Substraction(10, 20);
    
            sub.sum();
        }
    }

     

    실행 결과

    실행 결과는 30입니다.

     

    overriding을 하기 위해서는 메소드의 리턴 형식이 같아야 한다. 오버라이딩을 하기 위해서는 아래의 조건을 충족시켜야 한다.

     

    • 메소드의 이름
    • 메소드 매개변수의 숫자와 데이터 타입 그리고 순서
    • 메소드의 리턴 타입

     

    위와 같이 메소드의 형태를 정의하는 사항들을 통틀어서 메소드의 서명(signature) 라고 한다.

     

     

     

    overloading

    이름은 같지만 시그니처는 다른 메소드를 중복으로 선언 할 수 있는 방법은 메소드 오버로딩(overloding) 이라고 한다.

     

    package test;
    
    class Calculator{
        int left, right; 
        int third = 0;
        
        public Calculator() {}
        
        public Calculator(int left, int right) {
            this.left = left;
            this.right = right;
        }
        
        public void setOperands(int left, int right) {
            this.left = left;
            this.right = right;
        }
        
        public void setOperands(int left, int right, int third) {
            this.setOperands(left, right);        
            this.third = third;
        }
        
        public void sum() {
            System.out.println(this.left + this.right + this.third);
        }
        
        public void avg() {
            System.out.println((this.left + this.right + this.third)/2);
        }
    }
    
    class Substraction extends Calculator
    {
        public Substraction(int left, int right) {
            super (left, right);        
        }
    
        public void substraction()
        {
            System.out.println(this.left - this.right);
        }
    }
    
    public class Helloworld {
            
        public static void main(String[] args) 
        {
            Substraction sub = new Substraction(10, 20);
            sub.setOperands(10, 20);
            sub.sum();
            sub.avg();
            
            sub.setOperands(10, 20, 30);
            sub.sum();
            sub.avg();
        }
    }

     

    실행 결과

    30

    15

    60

    30

     

    메소드 오버로딩은 매개변수를 사용한다. 즉 매개변수가 다르면 이름이 같아도 서로 다른 메소드가 되는 것이다.

     

    반면에 매개변수는 같지만 리턴타입이 다르면 오류가 발생한다. 아래의 코드를 보자.

     

    class OverloadingDemo {
        void A() {
            System.out.println("void A()");
        }
        
        void A(int arg1) {
            System.out.println("void A(int arg1)");
        }
        
        void A(String arg1) {
            System.out.println("void A(String arg1)");
        }
        
        /* Error Code */
        /*int A() {
         * System.out.println("int A()");
        }*/
    }
    
    public class Helloworld {
            
        public static void main(String[] args) 
        {
            OverloadingDemo od = new OverloadingDemo();
            od.A();
            od.A(1);
            od.A("Hello world");
        }
    }
    
    void A()
    void A(int arg1)
    void A(String arg1)

     

    더 많은 값을 대상으로 연산할 수 있는 계산기 코드는 아래와 같다.

    package test;
    
    class Calculator{
        int[] operands;
        
        public Calculator() {}
        
        public void setOperands(int[] operands) {
            this.operands = operands;
        }
        
        public void sum() {
            int total = 0;
            for(int value : this.operands) {
                total += value;
            }
            
            System.out.println(total);
        }
        
        public void avg() {
            int total = 0;
            for(int value : this.operands) {
                total += value;
            }
            System.out.println(total/this.operands.length);
        }
    } 
    
    public class Helloworld {        
        public static void main(String[] args) 
        {
            Calculator ca = new Calculator();
            ca.setOperands(new int[] {10, 20});
            ca.sum();
            ca.avg();    
            ca.setOperands(new int[] {10, 20, 30});
            ca.sum();
            ca.avg();    
        }
    }

     

    실행 결과

    30

    15

    60

    20

     

     

     

    클래스 PATH

    아래의 코드를 javac ClasspathDemo.java 를 통하여 컴파일 후 생성된 ClasspathDemo.classItem.class를 각각

    D:\workspace\JAVA\LAB\ClasspathDemo.class

    D:\workspace\JAVA\LAB\lib\Item.class

     

    위와 같은 경로에 위치 시킨다고 가정한다.

     

    class Item {
        public void print() {
            System.out.println("Hello world");
        }
    }
    
    class ClasspathDemo {
        public static void main(String[] args) {
            Item t = new Item();
            t.print();
        }
    }

     

    위 코드를 실행시키는 콘솔 명령어는 아래와 같다.

    java -classpath ".;lib" ClasspathDemo

     

    리눅스, OSX 와 같은 유닉스 계열의 시스템이라면 아래와 같이 클론을 사용해야한다.

    java -classpath ".:lib" ClasspathDemo

     

    옵션 -classpath 는 자바를 실행할 때 사용할 클래스들의 위치를 가상머신에게 알려주는 역할을 한다.

     

    . 현재 디렉터리에서 클래스를 찾는다는 뜻이다.

     

    ; 경로와 경로를 구분해주는 구분자

     

    lib 현재 디렉터리에 없다면 현제 디렉터리의 하위 디렉터리 중 lib 에서 클래스를 찾는다는 의미다.

     

    위 와 동일한 효과의 경로를 환경변수로 등록하는 방법은 아래와 같다.(windows only)

     

     

     

     

    Package 컴파일

    javac src/test/*.java -d bin

     

    -d bin은 컴파일된 결과를 bin 디렉토리 하위에 위치시킨다는 의미다.

     

    자바 컴파일러는 자동으로 클래스의 패키지에 해당하는 디렉토리를 생성해준다.

     

     

     

    Package 중복의 회피

    package example3;
    import example1.*;
    import example2.*;
    
    public class D {
        public static void main(String[] args) {
            example2.B b = new example2.B();
        }
    }

     

    Package 명을 인스턴스 생성시에 명시해주면 명확한 B 에 대한 인스턴스를 생성할 수 있다.

     

     

     

    API 문서

     

    Java Platform SE 7

     

    docs.oracle.com

     

     

    각 구획 별 의미는 아래와 같다.

    1. 자바에서 기본적으로 제공하는 API 패키지의 리스트
    2. 1번에서 선택한 패키지들만 보여주는 클래스 리스트
    3. 2번에서 선택한 클래스의 맴버들을 보여주는 리스트

     

    자바에서 제공하는 기본 패키지들은 아래와 같은 기능을 담고 있다.

     

    • java.lang

    자바 프로그래밍을 위한 가장 기본적인 패키지와 클래스를 포함하고 있다.

     

    • java.util

    프로그램을 제어하기 위한 클래스와 데이터를 효율적으로 저장하기 위한 클래스들을 담고 있다.

     

    • java.io

    키보드, 모니터, 프린터, 파일등을 제어할 수 있는 클래스들의 모음

     

    • java.net

    통신을 위한 기능들을 담고 있다.

     

     

     

     

     

     

    728x90
    반응형

    'Language > JAVA' 카테고리의 다른 글

    [JAVA] 접근제어자  (0) 2018.06.12
    [JAVA] 기본 문법  (0) 2018.05.31
    [JAVA] 데이터 타입  (0) 2018.05.28
    [JAVA] 설치 및 실행  (0) 2018.05.28
상단으로