try~catch

자바는 예외처리를 위해서 try~catch 문을 제공하고 있다. try와 catch는 하나의 문장을 구성하지만

각각의 중괄호를 이용한 별도의 영역을 형성하게 된다.

try 는 예외상황이 발생할 만한 영역을 감싸는 용도로 사용이 되고 

catch는 발생한 예외의 처리를 위한 코드를 묶어두기 위한 용도로 사용이 된다.

catch 영역에서 예외상황이 처리되기 때문에 소스코드상에서 예외상황의 처리를 위한 코드를 아주 쉽게 구분할수 있다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import java.util.Scanner;
 
public class DivideByZero {
    public static void main(String[] args){
        System.out.print("두개의 정수 입력");
        Scanner sc= new Scanner(System.in);
        int num1 = sc.nextInt();
        int num2 = sc.nextInt();
        
        try{
            System.out.println("나눗셈 결과의 몫 : "+(num1/num2));
            System.out.println("나눗셈 결과의 나머지 : "+(num1%num2));
        }catch(ArithmeticException e){
            System.out.println("나눗셈 불가능");
            System.out.println(e.getMessage());
        }
        System.out.println("프로그램 종료");
    }
}
cs


자바 가상머신이 예외상황이 발생한것을 인식하면 이상황을 위해 정의된 ArithmeticException 클래스의 인스턴스를 생성하고

생성된 인스턴스의 참조 값을 catch 영역에 선언된 매개변수에 전달한다.


예외클래스

ArithmeticException 과 같이 예외상황을 알리기 위해 정의된 클래스들을 가리켜 '예외 클래스' 라 한다.

e.getMessage() 메서드는 예외상황을 알리기 위해 정의된 모든 예외 클래스들이 상속하는 

Throwable 클래스에 정의된 메소드이다. 모든 예외 클래스는 Throwable 클래스를 상속한다.


finally

예외상황의 발생여부와 상관없이 항상 실행되는 영역

finally 영역은 try~catch 문의 마지막에 삽입되어 예외상황의 발생 여부와 상관없이 실행된다.

try 영역에 들어가면 무조건 실행된다 실행의 흐름 중간에 return을 하더라도 finally영역은 실행되고 나서 빠져나가게 된다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class FinallyTest {
    public static void main(String[] args){
        
        
        try{
            
        }catch(Throwable e){
            
        }finally{
            System.out.println("예외상황 발생과 상관없이 실행되는 영역");
        }
        
    }
}
cs






 

'Java' 카테고리의 다른 글

자바 메모리 모델  (0) 2017.02.25
예외클래스 정의 / throw / throws  (0) 2017.02.25
인터페이스 interface  (0) 2017.02.25
abstract 클래스 (추상 클래스)  (0) 2017.02.25
final 클래스/final 메소드  (0) 2017.02.25

인터페이스는 상속과 메소드 오버라이딩을 기반으로 메소드에 대한 약속을 프로그램 코드상에서 규정하는 것이다.

객체가 인터페이스를 구현하면 그 객체는 인터페이스의 메소드를 반드시 구현해야 한다.


일반적으로 클래스가 인터페이스를 상속하는 경우에는 상속 이라는 표현을 쓰지않고 구현 이라는 표현을 쓴다.

하위클래스에서 인터페이스에 정의된 텅 빈 메소드(abstract 메소드) 를 구현해서 채워 넣어야 하기 때문이다.

그래서 인터페이스를 구현 할 때에는 키워드 extends를 사용하지 않고 키워드 implements 를 사용한다.

그리고 인터페이스 내에 정의되는 메소드는 무조건 public abstract 로 선언되기 

때문에 이에대한 선언을 별도로 해줄 필요가 없지만 많은 개발자들이 명확히 표현하는 경우가 많다.


인터페이스의 규칙

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

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

인터페이스는 참조변수의 선언이 가능하고 메소드의 오버라이딩도 가능하다.

인터페이스도 오버라이딩과 마찬가지로 하위클래스에서 

접근제어 지시자의 허용범위를 좁히는 방식으로는 접근제어 지시자를 변경할수 없다.

인터페이스 간에도 상속 관계를 형성할수 있다. 상속을 표현하는데에 있어서는 implements가 아닌 extends가 사용된다.


1
2
3
4
5
6
7
public interface MyInterface{ //인터페이스는 public 으로 선언하는것이 일반적이다.
    public void myMethod(); //public이 아니더라도 public 으로 선언된다.
}
 
public interface YourInterface{
    public void yourMethod();
}
cs


위와같이 두개의 인터페이스가 정의되어 있을때 클래스는 위의 두 메소드를 동시에 구현 할수 있다.


1
2
3
4
Class OurClass implements Myinterface, YourInterface{
    public void myMethod(){...}
    public void yourMethod(){...}
}
cs




abstract interface 차이

인터페이스와 추상 클래스는 서로 비슷한 듯 다른 기능이다.

인터페이스는 클래스가 아닌 인터페이스라는 고유한 형태를 가지고 있는 반면추상 클래스는 일반적인 클래스다. 

또 인터페이스는 구체적인 로직이나 상태를 가지고 있을 수 없고추상 클래스는 구체적인 로직이나 상태를 가지고 있을 수 있다.



'Java' 카테고리의 다른 글

예외클래스 정의 / throw / throws  (0) 2017.02.25
예외처리 try~catch /finally  (0) 2017.02.25
abstract 클래스 (추상 클래스)  (0) 2017.02.25
final 클래스/final 메소드  (0) 2017.02.25
instance of 연산자  (0) 2017.02.25
1
2
3
4
5
6
7
8
9
10
abstract class Friend
{
    ...
    public void showData()
    {
        ...
    }
    
    public abstract class void showBasicInfo();
}
cs



abstract 클래스는 완전하지 않은 클래스를 의미한다. 따라서 인스턴스의 생성이 불가능한 클래스이다.


메서드의 몸체 부분이 존재하지 않는 메서드를 abstract 메서드 (추상 메서드)라고 한다.

abstract 메서드는 클래스를 상속하는 하위 클래스의 메서드와 오버라이딩의 관계를 형성하기 위해 정의된 메서드이다.

abstract 메서드가 정의되어 있는 클래스는 인스턴스의 생성이 불가능하기 때문에

클래스 역시 abstract 키워드가 선언되어야 한다.


abstract 메소드가 없어도 인스턴스의 생성을 원하지 않으면 클래스를 abstract 로 선언할수 있다.

그러나 abstract 메서드가 하나라도 있으면 그 클래스는 반드시 abstract 로 선언해야 한다.


abstract 클래스를 상속받는 하위 클래스는 abstract 메서드를 반드시 오버라이딩 해야 컴파일이 가능하다.​

'Java' 카테고리의 다른 글

예외처리 try~catch /finally  (0) 2017.02.25
인터페이스 interface  (0) 2017.02.25
final 클래스/final 메소드  (0) 2017.02.25
instance of 연산자  (0) 2017.02.25
다형성  (0) 2017.02.25

final 키워드를 변수의 앞에다 선언하면 값의 변경이 불가능한 상수가된다.


1
final int num
cs




클래스의 정의에 final 선언을하면 "이 클래스를 상속하는 것을 허용하지 않겠다." 는 의미이다.


1
2
3
4
final class MyClass
{
    ...
}
cs





메소드가 final 로 선언되면 "이 메소드의 오버라이딩을 허용하지 않겠다." 라는 의미이다.

클래스는 상속이 가능하되 final 선언이된 메서드는 오버라이딩이 불가능하다.


1
2
3
4
5
6
7
class YourClass
{
    final void yourFunc(int n)
    {
        ...
    }
}
cs


'Java' 카테고리의 다른 글

인터페이스 interface  (0) 2017.02.25
abstract 클래스 (추상 클래스)  (0) 2017.02.25
instance of 연산자  (0) 2017.02.25
다형성  (0) 2017.02.25
오버라이딩  (0) 2017.02.25

instance of 연산자 연산자는 상속관계를 바탕으로 형변환이 가능한지를 묻는 연산자이다.

그결과로 true 또는 false 를 반환하는 연산자이다.


1
2
3
4
5
6
7
8
9
10
11
 //instanceof 연산자
 
//객체 instanceof 클래스이름 : 객체가(객체변수, 참조변수) 뒤의 클래스형으로 참조가 가능하면 true 불가능하면 false
 
Car c = new Car();
Ray r= new Ray();
if( c instanceof Ray){....} // if조건 false
if( r instanceof Car){....} // if조건 true
 instanceof 연산자
 
[출처] [27] OOP - 다형성(polymorphism) (JAVA, JAVASCRIPT 개발자 (자바, 자바스크립트)) |작성자 zeroDay
cs


'Java' 카테고리의 다른 글

abstract 클래스 (추상 클래스)  (0) 2017.02.25
final 클래스/final 메소드  (0) 2017.02.25
다형성  (0) 2017.02.25
오버라이딩  (0) 2017.02.25
상속  (0) 2017.02.25

다형성이란 하나의 메소드나 클래스가 있을 때 이것들이 다양한 방법으로 동작하는 것을 의미한다.



 카페 > JAVA, JAVASCRIP..  zeroDay

 http://cafe.naver.com/jjdev/2991. 다형성(polymorphism)

 

다형성이란 상위 클래스의 타입의 참조변수로 하위클래스의 객체를 참조하는 것을 말한다.

※ 추상클래스나 인터페이스도 상위클래스에 해당한다. 

추상클래스를 상속한 클래스의 객체나 인터페이스를 구현한 클래스의 객체를 상위 추상클래스 형이나 

인터페이스 형 변수로 참조 가능하다. 추상클래스와 인터페이스는 뒤에 단원에서 설명한다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class Person
{
int x;
}
 
class Student extends Person
{
int y;
}
 
 
Person p = new Student(); // 다형성
// p가 참조할 수 있는 멤버는 Student가 다 가지고 있기에 문제가 없다.
Student s = new Person(); // X compile error!
// s가 참조할 수 있는 멤버가 Person보다 많기에 에러 발생
cs



2. 참조변수의 형변환

 

(데이터타입) : 형변환 연산자

ex) (String)s, .....

※ 형변환 연산자는 기본타입에서도 사용가능하다.  ex) (int)2.3 



모든 참조변수는 변수에 객체의 참조값이 들어오기에 자식타입(서브타입)으로 강제 형변환이 가능하다. 

강제형변환을 하여도 변수가 변한 것이지 객체자체가 변화한 것이 아니므로 실행시 예외가 발생할 수도 있다. 

1
2
3
4
Person p = new Person();
Student s = (Student)p; // p변수를 강제로  Student로 형변환 , 정상적으로 컴파일
s.y = 10;
// 실행시 에러! , s가 가르키는 실체 객체는 new Person()으로 만들어 졌기때문에 y가 없다.
cs



3. 매개변수의 다형성


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class Car{
    void powerOn(){}
}
 
class Spark extends Car{
    void powerOn(){
        System.out.println("스파크 시동켜다");
    }
}
 
class Morning extends Car{
    void powerOn(){
        System.out.println("모닝 시동켜다");
    }
}
 
class Ray extends Car{
    void powerOn(){
        System.out.println("레이 시동켜다");
    }
}
cs


운전자는 위의 차들을 움직이기 위해서는 오버로딩된 메서드 3개가 필요하다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Driver{
 
    void carMove(Spark spark){
        spark.powerOn();
    }
 
    void carMove(Morning morning){
        morning .powerOn();
    }
 
    void carMove(Ray ray){
        ray.powerOn();
    }
}
cs


하지만 다형성을 이용하면 다음과 같이 하나의 메서드로 가능하다.


1
2
3
4
5
6
class Driver
{
    void carMove(Car car){
        car.powerOn();
    }
}
cs


Car형 car변수는 Spark, Morning, Ray 객체를 다 참조 가능하다. 

다형성을 활용하면 새로운 하위클래스 형식을 프로그램에 추가 하더라도 코드를 굳이 바꿀 필요가 없다. 




※ 메모리 생성 형태로 다형성 이해하기



다형성을 의미론적으로 설명하면 위의 예에서 "학생은 사람이다"와 "사람은 학생이다"에서 문맥상 앞의 문장이 맞는 표현이다.

(부모형에 자식형이 들어가는게 맞는 표현이다) 



그럼 메모리에 생성되는 형태로는 어떻게 설명되는가?



다음과 같은 상속관계의 클래스가 있다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
class A{
    int x;
    int y;
    void testOne(){}
    void testTwo(){}
}
 
 
class B extends A{
    int y;
    int z;
    void testTwo(){}
    void testThree(){}
}
cs



new A() 실행시 메모리에 참조될 수 있는 A객체의 멤버는 다음과 같다.(최상위 클래스인 Object클래스의 멤버는 당연히 참조되지만 이 설명에서는 생략한다 )


1
2
3
4
this.x
this.y
this.testOne()
this.testTwo()
cs



new B() 실행시 메모리 참조될 수 있는 B객체의 멤버는 다음과 같다.

(하위클래스의 생성자에서 상위 클래스의 생성자를 호출한다고 생성자 부분에서 설명했다. 그 의미를 알고 있다면 아래의 결과가 이해하기 쉬울것이다)


1
2
3
4
5
6
7
8
super.x
super.y
super.testOne()
super.testTwo()
this.y
this.z
this.testTwo()
this.testThree()
cs



B클래스의 내부에서는 super, this키워드를 이용하여 동일한 x변수나 testTwo()메서드를 구분하여 호출이 가능하겠지만, B클래스 아닌 다음과 같은 예에서는 B클래스의 객체에 대해서 super나 this같은 키워드 사용이 불가하다.


1
2
3
4
5
6
7
8
class C{
    B b = new B();
    // b.super.testTwo(); //이런 형태의 호출은 자바 문법에서는 제공하지 않는다. 
    // b.this.testTwo(); //이런 형태의 호출은 자바 문법에서는 제공하지 않는다.  
    // 만약에 위와 같은 형태의 표현을 자바언어가 지원했다면 자바언어가 좀더 유연해졌을까?
    // 아님 그냥 좀더 배우기 힘든 언어가 되었을까?
    b.testTwo();
}
cs
 

그럼 위의 testTwo()는 둘중 어떤 메서드를 호출하는가? 

자바언어는 다른클래스에서 객체를 생성후 멤버메서드 호출시 this.메서드가 있으면 this.메서드를 호출하고, 

없을때만 super.메서드를 호출한다. -> 오버라이딩 



A a = new B(); 되는 이유는 a변수가 참조할 수 있는 x, y, testOne(), testTwo()를 

new B()객체(super.x, super.y, this,y, super.testOne(), super.testTwo()(존재는 하지만 오버라이딩때문에 외부에서는 호출불가능) ,

this.testTwo())가 다 가지고 있기에 가능한 것이고(다형성), 

B b = new A();의 경우는 b변수가 참조할 수 있는 x, y, z, testOne(), testTwo(), testThree()를 

new A()객체가 다 가지고 있지 않기때문에 오류가 발생한다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class A{
    int x = 1;
    void test(){System.out.println("A실행")}
}
 
class B extends A{
    int x = 2;
    void test(){System.out.println("B실행")};
}
 
class MainTest{
    public static void main(String[] args){
        A a = new B();
        System.out.println(a.x); // 1출력 - 변수는 오버라이딩이 안된다. 부모참조변수로 호출하면 super.x가 호출된다.
                                    // 변수는 오버라이딩 대상이 아니니 부모와 동일한 이름의 변수는 사용금지!
        a.test(); // "B실행"출력 -  메서드 오버라이딩에 의해 super.test()가 아닌 this.test()가 호출된다.  
}
cs

 


 - 부모와 동일한 이름의 변수이름을 사용하는 것 -> 잘못된 습관

- 부모와 동일한 이름의 메서드 이름을 사용하는 것(구현기능이 유사할때) -> 잘된 습관(객체지향의 오버라이딩을 사용하는 습관)

 


 

* 다형성은 객체지향언어에서 가장 중요한 부분이여서 설명하는데 조심스럽기도 하지만, 특성상 "글 보다는 말", "말 보다는 그림"으로 설명하는 것이 이해가 빠른데... 글로 표현할려니 힘이 드네요 ㅠㅠ...  

'Java' 카테고리의 다른 글

final 클래스/final 메소드  (0) 2017.02.25
instance of 연산자  (0) 2017.02.25
오버라이딩  (0) 2017.02.25
상속  (0) 2017.02.25
캡슐화  (0) 2017.02.25

상속은 상위 클래스의 기능을 하위 클래스에게 물려주는 기능이다. 

그렇다면 하위 클래스는 상위 클래스의 메소드를 주어진 그대로 사용해야 할까? 

만약 그래야 한다면 제약이 상당할 것이다. 이런 제약을 벗어나려면 하위 클래스가 

부모 클래스의 기본적인 동작방법을 변경할 수 있어야 한다. 

이런 맥락에서 도입된 기능이 메소드 오버라이딩(overriding)이다.

상속 시간의 예제를 살펴보자. 이 예제는 클래스 Calculator의 

기본적인 동작 방법을 상속 받은 SubstractionableCalculator에 빼기 기능을 추가하고 있다. 

이것은 상위 클래스의 기능에 새로운 기능을 추가한 것이다. 

만약 상위 클래스에서 물려 받은 메소드 sum을 호출했을 때 아래와 같이 

그 결과를 좀 더 친절하게 알려줘야 한다면 어떻게 해야할까?


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
class Calculator {
    int left, right;
 
    public void setOprands(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 SubstractionableCalculator extends Calculator {
     
    public void sum() { //
        System.out.println("실행 결과는 " +(this.left + this.right)+"입니다.");
    }
     
    public void substract() {
        System.out.println(this.left - this.right);
    }
}
 
public class CalculatorDemo {
    public static void main(String[] args) {
        SubstractionableCalculator c1 = new SubstractionableCalculator();
        c1.setOprands(1020);
        c1.sum();
        c1.avg();
        c1.substract();
    }
}
cs


메소드 sum이  SubstractionableCalculator에 추가 되었다. 

실행결과는 c1.sum이 상위 클래스의 메소드가 아니라 하위 클래스의 메소드 sum을 실행하고 있다는 것을 보여준다. 

하위 클래스 입장에서 부모 클래스란 말하자면 기본적인 동작 방법을 정의한 것이라고 생각할 수 있다. 

하위 클래스에서 상의 클래스와 동일한 메소드를 정의하면 부모 클래스로부터 물려 받은 

기본 동작 방법을 변경하는 효과를 갖게 된다. 기본동작은 폭넓게 적용되고, 

예외적인 동작은 더 높은 우선순위를 갖게하고 있다. 이것은 공학에서 일반적으로 발견되는 규칙이다. 

이것을 메소드 오버라이딩(overriding)이라고 한다.



오버라이딩의 조건


overriding을 하기 위해서는 메소드의 리턴 형식이 같아야 한다.

오버라이딩을 하기 위해서는 아래의 조건을 충족시켜야 한다.

메소드의 이름

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

메소드의 리턴 타입

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

 

https://opentutorials.org/course/1223/6090

'Java' 카테고리의 다른 글

instance of 연산자  (0) 2017.02.25
다형성  (0) 2017.02.25
상속  (0) 2017.02.25
캡슐화  (0) 2017.02.25
접근제어자  (0) 2017.02.25

상속의 기본적인 특성


기존의 정의된 클래스에 메소드와 변수를 추가하여 새로운 클래스를 정의하는것이다.

상속을 받은 클래스의 인스턴스에는 상속의 대상인 클래스의 정의된 메소드와 변수가 존재한다.


상속관계에서 상속을 받은 클래스를 가르켜 '하위클래스(sub class)'

상속의 대상이 된 클래스를 '상위클래스(super class)' 라 부른다.


상위클래스로부터 상속받는 하위클래스가 확장(extends) 하는것이다.


상속의 장점은 코드의 중복을 줄일수있고 , 유지보수 또는 재활용이 용이하다.


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
//상위클래스 (super class)
public class A {
    int a = 0;
    public static void A(){
        
    }
}
 
//하위클래스 (sub class)
public class B extends A {
}
 
public class MainDemo {
    public static void main(String[] args){
        
        B b = new B();
        b.A(); 
        //상속을받음으로써
        //B클래스에 정의되지않은 메서드인A();를 호출이가능하다.
 
        System.out.println(b.a);
        //상속을받음으로써
        //B클래스에 선언되지않은 변수 a를 사용할수있다.
    }
}
 
cs
 



상속과 생성자


하위클래스의 생성자 내에서는 반드시 상위클래스의 생성자가 호출되어야 한다.

만일 상위클래스의 생성자를 호출할수없는 구조로 하위 클래스의 생성자가 정의된다면,

하위클래스의 인스턴스 생성은 불가능하다.



1
2
3
4
5
6
public class B extends A {
    
    public B(){
        super();
    };
}
cs


하위클래스 내의 생성자에는 상위클래스를 가르키는 키워드인 super 를 사용해

상위클래스의 생성자를 호출하고있다. 이부분은 생략해도 자동으로 삽입된다.




1
2
3
4
5
6
7
8
9
10
package java01;
 
public class A extends Object { //extends Object생략
    int a;
    
    public A(){
        super(); //상위클래스 생성자 호출 
        a=0;
    }
}
cs


 

자바의 모든 클래스는 상위클래스가 있어야한다 상위클래스가 없는경우 

자동으로 Object 클래스를 상속받는다. 코드는 생략되있다.




'Java' 카테고리의 다른 글

다형성  (0) 2017.02.25
오버라이딩  (0) 2017.02.25
캡슐화  (0) 2017.02.25
접근제어자  (0) 2017.02.25
static  (0) 2017.02.25

+ Recent posts