반응형

package com.strict;


/*

 * 우리가 부동 소수점 변수를 연산 수행하였을 떄, 

 * 어떠한 플렛폼에서든 동일한 결과를 얻을수있도 지켜주는 고마운 키워드가

 * 바로, 이번 시간에 다뤄볼  Java Strictfp Keyword이다.!

 * 

 * (구)플렛폼에서 (신)플렛폼으로 옴겨서 실행할 경우 정확성이 차이가날 수 가 있다.

 *  그 말인 즉슨, 큰 값을 계산할수록 오차범위가 커진다는것이다.

 *  게다가 오차범위가 크다는것은 혼란과 재앙을 야기하는데 충분한 요소인데 특히 

 *  건축, 의료 분야에서는 진짜로 Catastrophe!가 될 수가 있고 이는 

 *  충분히 인명사고로 이어질 수 있으며 금융에서는 인플레, 디플레, 등등 인류에게 영향을 

 *  미칠 수도 있다.( 물론 그럴일은 없겠지만)

 *  그래서 자바는 strictfp키워드를 지원함으로서 플렛폼마다 차이가 날 수 있는 오차범위를

 *  잡고자 꾀했다. 부동소수점의 고질적 문제가 해결된것이다.

 *  

 */

public class strict {


public strictfp class A { // 클래스에 사용가능하고,

private strictfp void A_Method() {

}// 메소드에 사용이가능하며,

}


protected strictfp interface B { // 인터페이스에도 사용할 수 있다.

}


}


class B {

// strictfp abstract void m(){ } 추상메소드에 사용이 불가하며,

// strictfp int da = 10; 변수에 붙을 수 없고

// strictfp B(){} 생성자에 붙을 수 읍당.


}



반응형
by 발전소장 에르 :) 2017. 9. 25. 17:40
반응형

package com.example.recursive;

/*

 * 재귀(귀납) - Recursive

 * 메소드가 자기 스스로를 끊임없이 호출하는 과정을 의미한다.

 * 그것을 재귀메소드라 칭한다.

 * 

 * syntax

 * 

 * returntype methodname(){

 * methodname();

 *  

 */


public class RecursiveExample {

static void p() {

System.out.println("P has called");

p();

}


public static void main(String[] args) {

p();

}

}  

몇번돌다가 에러를 뱉을겁니다.. 재귀하면 떠오르는 StackOverFlow!!

///////////////////////////////////////////////////////////////


package com.example.recursive;



public class RecursiveExample2 {


static int factorial(int n) {

// static method

if (n == 1)

return 1;

else

return (n * factorial(n - 1));

// 2이상의 값이 들어올 경우 위 구문이 진행된다./

//그리고 n-1한 값을 다시 factorial에 넣고 돌린다.

// 그러다 n이 1이 되면 1을 리턴합니다.

// 원리는 아래와 같습니다.

// factorial(5) 

                       factorial(4) 

                             factorial(3) 

                                 factorial(2) 

                                        factorial(1) 

                                               return 1 

                                    return 2*1 = 2 

                             return 3*2 = 6 

                             return 4*6 = 24 

                       return 5*24 = 120

//return안에서 factorial메소드가 파라미터가 1이 될때까지

//돌고난 후 return을 통해 값이 출력되는데 태엽을 상상하시면 이해가

// 쉬울것같습니다.

}


public static void main(String[] args) {

System.out.println("Factorial of 5 is: " + factorial(5));


}

}

//////////////////////////////////////////////////////////////////

public class RecursiveExample3 {


static int count = 0;


static void p() {

count++;

if (count <= 9) {

System.out.println("hello " + count);

p();

}

}


public static void main(String[] args) {

p();

}

}

result = 

hello 1

hello 2

hello 3

hello 4

hello 5

hello 6

hello 7

hello 8

hello 9


//////////////////////////////////////////////////////////////////

// 파보나치 수열!

public class RecursiveExample4 {

static int n1 = 0, n2 = 1, n3 = 0;


static void printFibo(int count) {

if (count > 0) {

n3 = n1 + n2;

n1 = n2;

n2 = n3;

System.out.print(" " + n3);

printFibo(count - 1);

}

}


public static void main(String[] args) {

int count = 15;

System.out.print(n1 + " " + n2);// printing 0 and 1

printFibo(count - 2);// n-2 because 2 numbers are already printed

}

}

result = 0 1 1 2 3 5 8 13 21 34 55 89 144 233 377




반응형
by 발전소장 에르 :) 2017. 9. 25. 17:37
반응형

package com.access.array;


/*

 * 일반적으로 배열은 연속된 메모리 위치를 가진 비슷한 타입을 가진 요소의 집합(Collection)을 의미한다.

 * 자바에서의 배열은 유사한 데이터타입의 요소를 가지고있는 객체라 얘기한다.

 * 배열을 초기화할때 정해진 범위를 늘이거나 줄일 수 없다.

 * 한마디로 한번 생성되면 고정된 크기를 가진다.

 * 

 * 배열은 인덱스를 기초로 0번부터 시작한다. 물론 갯수를 셀 떄는 1번부터 시작한다.

 * 

 * 배열의 이점:

 * -코드의 간소화, 어떤 인덱스 위치에 있는 어떤 데이타든 접근이 가능하다.

 * 

 * 배열의 단점:

 * - 제한된 크기: 위에서도 언급했다싶이 한번 초기화할때 정해진 크기를 가지며 수정은 불가하다.

 * 이 문제를 해결하기위해서 Collection FrameWork가 사용되었다.

 *

 *  -1차원 배열, 다차원 배열으로 2가지 타입의 배열이있다.

 *  

 *  1차원 배열의 구문은 이렇다.

 *  dataType[] arr; (or)  

 *  dataType []arr; (or)  

 *  dataType arr[];  

 *  

 *  초기화는 이렇게한다.

 *  arrayRefVar=new datatype[size];  

 * 

 */

public class TestArray {

public static void main(String args[]) {


int a[] = new int[5];// 배열 선억식.

a[0] = 10;// 각 인덱스에 번호를 직접 지정하여 값을 넣을 수 있다.

a[1] = 20;

a[2] = 70;

a[3] = 40;

a[4] = 50;


// 그럼 이렇게 만든 배열을 출력해보자.

for (int i = 0; i < a.length; i++)// a.lenght는 배열의 길이를 나타낸다 (중요 많이사용함)

System.out.println(a[i]);


int[] b = { 1, 2, 3 };

int c[] = { 3, 2, 1 };

// 하지만 간편하게 이렇게 선언할수도있다.


for (int i = 0; i < b.length; i++) {

System.out.println(b[i]);

System.out.println(c[i]);

}

}

}

//////////////////////////////////////////

package com.access.array;


public class TestArray2 {


static void min(int arr[]) {

// 파리미터로 int타입 배열을 가지고있고,무엇보다 static이다.

int min = arr[0];

// 다른값들과 비교할 값이 필요함으로

// 입력으로 들어올 배열의 0번째 인덱스를 int min값에 집어넣는다.


for (int i = 1; i < arr.length; i++)

if (min > arr[i])

// 만약 min이 arr[1]보다 크면 min을 대신하고 배열의 길이만큼 반복한다.

min = arr[i];// 최종적으로 비교되 제일 낮은값이 min에 저장되게된다.

System.out.println(min);

// 프린트로 찍는다!.

}


public static void main(String args[]) {


int a[] = { 33, 3, 4, 5 };

min(a);// 이 부분 때문에 static을 선언한거라고 볼 수 있는데

// static은 최상위 우위로 로딩되기때문에 메인에서도 접근할 수가 있다.

// int a 배열을 min메소드의 파라미터로 넣는다.

// 그럼 그 값을 5번 라인으로 넘긴다.


}

}

//////////////////////////////////////////

package com.access.array;


/*  다차원 배열.

 * 매트릭스 형태로 컬럼과 로우로 구성된 배열을 일컫는다.

 * 구문은 아래와 같이 사용하여 정의할 수 있다.

 * 

 *  dataType[][] arrayRefVar; (or)  

dataType [][]arrayRefVar; (or)  

dataType arrayRefVar[][]; (or)  

dataType []arrayRefVar[];   

 *  

 *  3개의 로우와 3개의 컬럼을 가진 다차원 배열을 예로 만들어보자

 */

public class TestArray3 {


public static void main(String[] args) {


int[][] arr = { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 },{10,11,12}};

for (int i = 0; i < 4; i++) { //칼럼의 갯수만큼 돌려주고,

for (int j = 0; j < 3; j++) { // 로우의 갯수만큼 돌려주

System.out.print(arr[i][j]+" ");

} //arr

System.out.println();

}

}


}

//////////////////////////////////////////

package com.access.array;

/*

 * java array의 클래스 이름은 무엇인가요?

 * 

 * 자바에서 배열은 객체입니다.

 * 

 */

public class TestArray4 {

public static void main(String args[]) {


int arr[] = { 4, 4, 5 };

// 배열을 하나 생성해주고,


Class c = arr.getClass();

// 클래스 타입 변수 c에 .getClass()메소드를 이용해서 리턴값인 클래스를 넣어주고, 

String name = c.getName(); 

// c의 이름을 가져와 스트링 변수에 담아서 출력하면,

System.out.println(arr); 

// 그냥 arr을 찍으면 저장된 주소값이 출력됩니다.

System.out.println(c);

System.out.println(name);

// int arr[]의 클래스이름을 알아낼수있답니다.

}

}

//////////////////////////////////////////

package com.access.array;


/*

 * 배열복사하기.

 * System class의 arraycopy 메소드를 이용해서, 배열을 복사할수있다.!

 * arraycopy메소드의 구문은 아래와 같은데, 

 * 

 * public static void arraycopy(  

Object src, int srcPos,Object dest, int destPos, int length  

)   

꼭 메소드를 통해서만 복사가 가능한걸까?

 */

public class TestArrayCopyDemo {

public static void main(String[] args) {

char[] copyForm = { 'd', 'e', 'c', 'a', 'f', 'f', 'e', 'i', 'n', 'd' };

// 문자열 타입 배열을 만들고 안에 값을 집어넣느다.

char[] copyTo = new char[7];

// 그리고 복제가 될 배열 하나를 만든다.


System.arraycopy(copyForm, 2, copyTo, 0, 7);

// System의 메소드인 arraycopy를 타이핑 후 적절히 파라미터를 준다.

/*

* @param src 소스를 줄 배열

* 

* @param srcPos 소스 배열에서 복제하기 시작할 인덱스 번호

* 

* @param dest 소스를 받게 될 배

* 

* @param destPos 몇번인덱스에서부터 소스를 받을 것인가.

* 

* @param length destPos에서부터 얼마만큼 길이의 데이터를 받을 것인가.

* 

*/

System.out.println(copyTo);


int[] a = { 1, 2, 3 };

int[] b = a;

char[] c = { 'a', 'b', 'c' };

char[] d = c;


for (int e = 0; e < a.length; e++) {

System.out.print(a[e]);

System.out.print(b[e]);

}

System.out.println();

for (int e = 0; e < a.length; e++) {

System.out.print(c[e]);

System.out.print(d[e]);

}

}

}

//////////////////////////////////////////

package com.access.array;


/*

 *  다른 두 배열을 더할 수도 있을까?

 *  복제를 보아하니, 왠지 가능할거같다. 

 *  

 */

class TestArray5 {

public static void main(String args[]) {

// 일단 재료가 될 두 행렬을 생성해주자.

int a[][] = { { 1, 3, 4 }, { 3, 4, 5 } };

int b[][] = { { 1, 3, 4 }, { 3, 4, 5 } };

// 2, 6, 8 6, 8, 10이 되어야한다.


// 두 배열의 합을 저장할 배열을 만들어주자.

int c[][] = new int[2][3];


// 그리고는 반복문을 통해 두 배열을 c로 집어넣어주자.

for (int i = 0; i < 2; i++) {

for (int j = 0; j < 3; j++) {

c[i][j] = a[i][j] + b[i][j];

System.out.print(c[i][j] + " ");

}

System.out.println();// new line

// 딱히 설명할게 없다.

}

}

}




반응형
by 발전소장 에르 :) 2017. 9. 25. 00:30
반응형

package com.example.call;


/*

 * Call by Value and Call by Reference In Java.

 * 자바 호출에는 값을 호출할 순 있지만 참조객체를 직접 호출할 수는 없다.

 * 이게 무슨말이고하면!

 * 값을 전달하는 메소드를 호출한면, 값호출(Call Of Value)을 수행한것이고,

 * 호출된 메소드에서 변경된 값은 적용되지가않는다.

 * 무슨 말인지 살짝 모호할텐데, 예제를 보자 

 */

public class Operation {

int data = 50; // field


void change(int data) { // method

data = data + 100;

// this.data = data + 100 이 아니다.

// 오해하지말

// 메소드 내부의 변수 값은 변하지않고, 오직 로컬변수의 변경될 수 있다.

// 호출된 메소드의 파라미터인 data를 넘겨받아 그 값에 100을 더하여 초기화하는데

// 지켜볼건 이렇게해서 data가 가지고있는값이 바뀌느냐?

}


public static void main(String args[]) {

Operation op = new Operation();

// 객체를 만들어주자.

System.out.println("before change " + op.data);

// 변경전


op.change(500);

// 파라미터를 통해 필드값 50을 무시하고 값을 집어넣었을

System.out.println("after change " + op.data);


op.data = 99; // 로컬 변수에 직 접근하였을때

System.out.println("aproaching to local var " + op.data);


}

}

before change 50

after change 50

aproaching to local var 99


package com.example.call;


/*

 * 참조호출의 경우에 호출된 메소드를 변경한다면, 원래 값이 변경될 수 있다.

 * 어떤 원시타입 값을 주는대신에 객체를 전달한다면! 원래값이 바뀌게되는데

 * 밑에 예제에서는 값을 대신해 객체를 전달하였다.

 * 

 *

 */

class Operation2 {

int data = 50;


void change(Operation2 op) {

op.data = op.data + 100;

// op의 타입을 보자, 객체 Operation2이 타입으로 선언되있다는 말은

// 원시타입이 아닌 참조타입이라는 얘기이다. 

// 참조호출을 통해 로컬변수로 접근할 수 있게된다.

}


public static void main(String args[]) {

Operation2 op = new Operation2();


System.out.println("before change " + op.data); //50

op.change(op);// 50 + 100

System.out.println("after change " + op.data);


}

}

before change 50

after change 150



반응형
by 발전소장 에르 :) 2017. 9. 20. 02:35
반응형

/*

 * 1. 자바에서 Encapsulation이란 데이터와 코드를 단일 유닛에 포장하는 과정을 의미한다.

 * 애초에 캡슐 자체 다양한 종류의 약을 위까지 안적하게 이동시키기 위해 만들어졌기때문에 일맥상통한다고 볼 수 있다.

 * 우리는 완벽히 캡슐화된 클래스를 private class를 통해 만들 수 있다.

 * 그리고는 Getter&Setter를 통해 안전히 접근할 수 있다.

 * 

 * 2. 캡슐화의 장점.

 * Getter&Setter를 통해서 클래스를 Read-Only 혹은 Write-Only로 만들 수 있다.

 * 일단 게터와 세터를 통하면 근본 데이터의 오염을 방지할 수 있으며 다형성의 원리에 매우 부합하여

 * 나중에 유지보수성성이 높아진다는 의미이니 생활화하도록하고, 나중에는 프레임워크로 대체할테니

 * 개념과 실습으로 마무리 지어놓자

 */


package com.encapsulation;


public class Student {

private String name;


public String getName() {

return name;

}


public void setName(String name){  

this.name=name ;

}

}




package com.encapsulation;


class Test {

public static void main(String[] args) {

Student s = new Student();

s.setName("vijay");

System.out.println(s.getName());

}

}


// vj jay라는 결과값이 나온다. 직접 Student의 필드값에 접근하지않고 setter를 통하여

// 필드의 값을 초기화한 후 getter를 통해 가져왔다. 이 과정은 모두 간접적으로 이루어졌다는걸 명시하자.

// 딱히 더 설명할게 없지만 객체지향프로그맹에서 핵심 이론을 맡고있다.

// 자세한 내용은 추후에 구글링으로 더 덧붙이도록 하겠다.


반응형
by 발전소장 에르 :) 2017. 9. 15. 14:27
반응형

반갑습니다. 발전소장 에르입니다 :) 이번 시간에 다뤄볼 주제는 '접근 제한자' 요놈인데요.

쉽게 말하면 기숙사의 방마다에 위치한 '도어락'같은 아이입니다.

자바에서는 '접근 제한자'와 '비-접근 제한자'로 두가지 타입이 존재합니다.

데이터 멤버, 메소드, 생성자, 클래스들의 스코프를 지정해주는 접근제한자로는 4가지가 있는데

1. private

2. default

3.protected

4.public 

위와 같이 되어있으며, 특히 4번쨰 public은 매우 익숙하리라 단언합니다.

그리고 비-접근 제어자로는 static, abstract, synchronized, native, volatile, transient 등이 있습니다만, 

우리가 오늘 메인으로 다룰 주제는 위에서도 언급했다싶이 ' 접근 제한자' 입니다.

1) private access modifier

클래스 내부에서만 공유할 수 있는 제한자입니다.

package com.access.modifier;


class A

// private 필드와 메소드를 가진 A라는 클래스가 있고,

private int data = 40;


private void msg() {

System.out.println("Hello java");

}

}


public class Simple {

//메인메소드를 가지고있는 Simple클래스

public static void main(String args[]) {

A obj = new A();

//A 인스턴스를 만들어 A가 가지고있는 필드와 메소드에 접근하고자합니다만.!!

System.out.println(obj.data);// Compile Time Error

obj.msg();// Compile Time Error

}

}


Exception in thread "main" java.lang.Error: Unresolved compilation problems: 

The field A.data is not visible

The method msg() from the type A is not visible


at com.access.modifier.Simple.main(Simple.java:18)

라는 에러를 뱉어주는데요, 다른 방 학생이 옆 방에서 물건을 가지고 갈려는데 비밀번호가 걸려있어서 못들어가는거라고

보시면 되실거같네요.



다음엔 private 생성자의 역할을 알아봅시다.

만약 private 생성자를 가진 클래스가 있다고 가정할때, 다른 클래스에서는 해당 클래스를 생성할 수가 없게됩니다.

class A {

private A() {

}// private 생성자


void msg() {

System.out.println("Hello java");

}

}


public class Simple {

public static void main(String args[]) {

A obj = new A();// Compile Time Error

}

}

Exception in thread "main" java.lang.Error: Unresolved compilation problem: 

The constructor A() is not visible


at com.access.modifier.Simple.main(Simple.java:12)



라고 뜨네요, 왜냐면 인스턴스를 만들때 필요한건 생성자인데 이 생성자에 접근을 할 수 없으니 만들 수가 없는거죠.

물과 냉장고는 있는데 각얼음을 만들기위한 틀이 없다고나할까나..


2) default access modifier

아무 접근 제한자를 명시하지않으면 자바는 알아서 '뭐야? 아무것도 안붙힘? 그럼 내가 붙여줌' 하면서
default제한자를 붙여줄겁니다. default제한자는 같은 패키지끼리만 접근이 가능하단걸 의미합니다.
같은 동에 사는 학생들만 그 동에 출입할 수 있는거죠.

//save by A.java  

package com.access.modifier;


class A {

void msg() {

System.out.println("Hello");

}

}

=====================================================

package com.access1.modifier;


//save by B.java  

import com.access.*;


class B {

public static void main(String args[]) {

A obj = new A();// Compile Time Error

obj.msg();// Compile Time Error

}

}


class A의 제한자가 default이기때문에 같은 패키지에서만 호출이 가능한데

class B에서 다른 패키지에 있는 A를 호출할려고했기떄문에 자바가 '안되, 돌아가'하며 컴파일 에러를 뱉은 상황입니다.

3) protected access modifier

가장 모호한 놈입니다..
dafault에 상속개념을 더하여, 같은 패키지와 다른 패키지에서도 접근이 가능하게하지만
다른 패키지에서 접근하고자한다면 상속관계에 있어야합니다.
(protected 제한자는 데이터멤버, 메소드, 생서자에 사용될 수 있지만 클래스에는 사용할 수 없습니다.

//save by A.java  

package com.access.modifier;


public class A{  

protected void msg(){System.out.println("Hello");}  

}  

======================================================

package com.access1.modifier;


import com.access.modifier.*;


class B extends A {

public static void main(String args[]) {

B obj = new B();

obj.msg();

}

}


Hello


비록 A,B의 패키지는 서로 다르지만, B가 A를 상속했기 때문에 A의 method를 호출할 수 있었습니다.


4) public access modifier

public 얘는 너무 열려있는 아이입니다. 그래서 너무 남발하다간 보안에 취약점이...
//save by A.java  

package com.access.modifier;


public class A {

public void msg() {

System.out.println("Hello");

}

}

===================================================

package com.access1.modifier;


import com.access.modifier.*;


class B {

public static void main(String args[]) {

A obj = new A();

obj.msg();

}

}


Hello

..뭐 설명할게 없는 관계로 패스..! 

밑에 정리표를 마지막으로 마무리하겠습니다:)






반응형
by 발전소장 에르 :) 2017. 9. 13. 00:29
반응형

표지모습 코뿔소가 매우 매력적임..솔직히 표지디자인 잘빠진듯.

한빛미디어 책들만 몇 권이있는지 저기에 하둡이랑 오라클도 있음..ㅋㅋㅋㅋㅋ


==============본격 후기 =============

JSP를 포함한 많은 웹개발에 대한 심리적인 압박을 가지고 있던차에,

 웹프로그램밍을 공부하고자 마음먹었고 HTML, CSS, JSP 등등 공부하는 과정에서

 특히.. jsp에서만 큰 어렴움을 겪고 있었다.  JS에 대해서는 어렴풋이 알고있었는데 

상세히 들여다본적이 없기 때문에 무엇인지 감이 전혀 잡히지가 않았었다.


그런데 요번에 카카오뱅크 홈페이지가 자바스크립트로 만들어졌단 얘기를 듣고, 막상 까보니 진짜 JS로 만들어졌었고, 궁금하던차에 구매해서 제대로 공부하고자 마음먹었다.

책을 고르던 차에  자바스크립트 최신판이 출간된것을발견했다.( 최신판 중에서 최신판!!)
냉큼 고르고 첫페이지를 펴보니, 
초심자에게 어려울 수 있는 내용을 포함하고 있으니 추천드리지않습니다...
 이 얼마나 솔직하고 친절한가?!

내 기준에 초심자 책은 독자를 어루고 달래서
 "우쮸쮸~ 입벌려 코드들어간다~"하는 책들 밖에 없었는데.
 이 책은 "이해가 안되? 다시 봐봐 .. 그래도 모르겠어? 
그럼 더 읽지말고 그전꺼부터 공부 더 하고와 그럼 이해됨.
 스스로 노력 좀해봐 평생 코더만 할레? " 이런 느낌이었고. 
나 스스로 생각을 할 수 있게끔해주는 방식이 너무 마음에 들었다.

게다가 결정적으로는 본인도 영어를 퍽 한다고 생각하지만, 몇번의 번역 경험을 미루어보았을때 영어를 한국말로 번역하며 말투를 어떻게해야할지.. 정말 어려웠다. 막상 결과본을 보면 구글번역기가 한듯한 착각을 불러일으키게하곤했는데

번역자분이 번역이 완전 최적화시키셔서 하셨기 때문에 한국인이 저자인가? 
라는 듯한 착각을 들게한다.
이제 더 이상 구구절절하게 일기를 쓰는 것 보다는 간략히 적도록 하겠다.

장점 : 옮긴이가 데드풀 번역가 급임.
현역들과 경험자들을 기준으로 책을 지었기 때문에 더 이해가 잘됨.( 초심자에게는 부적합)
최신판 중에서도 최신판. <<< 가장 중요하다고생각함.
책 재질이 말랑말랑거리고 부드러워서 지하철에서 읽어도 손이 편함.
상당히 섬세하게 되있어 컴파일러 책속에 들어있는 느낌.


 


반응형
by 발전소장 에르 :) 2017. 8. 16. 18:00
반응형

Java) Static Binding 과 Dynamic Binding


메소드 바디에 메소드 호출을 연결하는 것을 " 바인딩 " 이라고 합니다.

두 가지 타입이 바인딩이 있는데요.


1) static binding   (정적 바인딩)

2) dynamic binding (동적 바인딩)


일단 타입을 이해해봅시다.


1) 변수 타입

int data = 30;

각 각의 변수들은 타입을 가지고있고 primitive 타입이거나 아닐 수 있습니다. 

정수 타입의 데이터 변수가 있고 30이란 정수값을 가지고있네요.



2) 참조 타입 

class Dog{  

 public static void main(String args[]){  

  Dog d1;//Here d1 is a type of Dog  

 }  

 



d1 객체는 Dog타입을 가지고있습니다.


3) 객체 타입

class Animal{}  


class Dog extends Animal 

 public static void main(String args[]){  

  Dog d1=new Dog();  

  

}  

Object는 특이한 자바 클래스의 인스턴스입니다.

하지만 Object 또한 부모 인스턴스이기도하죠. 

d1은 Dog클래스의 인스턴스입니다만, Animal의 인스턴스이기도하지요.


이제 스태틱 바인딩을 알아봅시다.


객체의 타입이 컴파일러에 의해서 컴파일시 정해지는것을 스태틱 바인딩이라고합니다.

만약 private, final, static method가 클래스 내부에 있다면 스태틱 바인딩입니다.




//스태틱바인딩의 예입니다.


2 ) Dynamic binding


 class Animal{  

 void eat(){System.out.println("animal is eating...");}  

 

  

class Dog extends Animal{  

 void eat(){System.out.println("dog is eating...");}  

  

 public static void main(String args[]){  

  Animal a=new Dog();  

  a.eat();  

 }  

}  

Run-time시에 객체의 타입이 결정된다면동적 바인딩입니다. 

객체타입은 컴파일러에 의해 결정될  없습니다.

Dog 인스턴스의 또한 Animal 인스턴스이기 때문이죠.

그래서 컴파일러는 기본유형만 알고 제대로된 a 타입을 모릅니다.



반응형
by 발전소장 에르 :) 2017. 8. 11. 00:55
반응형

다형성 Polymorphism 

자바에서 다형성이란 하나의 동작을 여러 방식으로 할 수 있게해주는 개념으로 정의하고있습니다.

 Polymorphism(폴리모피즘)는 그리스어 poly와 morphs는 그리스어에서 파생되어 만들어진 단어입니다. poly는 다수를 의미하고 morphs는 형태를 의미합니다.

그래서 폴리모피즘의 뜻이 다형성이 되는거라고 하네요.(이하 polymorphism)

자바에는 두가지 타입의 polymorphism이 존재하는데, 컴파일타임 polymorphism과 런타임 polymorphism이 있습니다. 

그리고 우리는 오버로딩과 오버로드를 통해 polymorphism을 구현할 수 있습니다!

만약 우리가 static method를 오버로드했다면 컴파일타임 polymorphism의 예입니다.

런타임 polymorphism의 예를 살펴봅시다.


1) Runtime Polymorphism in JAVA.

Runtime Polymorphism 혹은 Dynamic Method Dispatch 는

오러라이드된 메소드를 컴파일에서보다는 런타임에서 해결하는 프로세스입니다.

이 과정에서, 오버라이드된 메소드는 superClass의 변수 참조를 통해 호출됩니다.

메소드가 호출되는 결정은 참조 변수가 참조하는 객체에 기반합니다.


Upcasting(자동타입변환) 

부모클래스 참조 변수가 자식 클래스 객체를 참조할 때 이를, 업 캐스팅! 이라고 합니다.

왜 갑자기 업캐스팅 얘기냐구요? 런타임 다형성을 이해하기위해서 필요하니까요!


런타입 다형성 얘제를 살펴볼게요.

class Bike{  

  void run(){System.out.println("running");}  

}  

class Splender extends Bike{  

  void run(){System.out.println("running safely with 60km");}  

  

  public static void main(String args[]){  

    Bike b = new Splender();  

    b.run();  

  }  

}

output = running safely with 60km

 

Bike와 Splender라는 클래스를 만들고 Splender 클래스가 Bike를 상속했고 run()메소드를 오버라이드했습니다.

여기서 오버라이드된 run()메소드를 부모 클래스의 참조변수라고 부릅니다.

하위 클래스 객체를 참조하고 하위 클래스 메소드가 상위 클래스 메소드를 무시하므로 

런타임에 하위 클래스 메소드가 호출됩니다.

은행 예를 들어볼까요? 

package polymorphism;

class Bank{  

float getRateOfInterest(){return 0;}  

}  

class SBI extends Bank{  

float getRateOfInterest(){return 8.4f;}  

}  

class ICICI extends Bank{  

float getRateOfInterest(){return 7.3f;}  

}  

class AXIS extends Bank{  

float getRateOfInterest(){return 9.7f;}  

}  

class TestPolymorphism{  

public static void main(String args[]){  

Bank b;  

b=new SBI();  

System.out.println("SBI Rate of Interest: "+b.getRateOfInterest());  

b=new ICICI();  

System.out.println("ICICI Rate of Interest: "+b.getRateOfInterest());  

b=new AXIS();  

System.out.println("AXIS Rate of Interest: "+b.getRateOfInterest());  

}  

}

output = 

SBI Rate of Interest: 8.4

ICICI Rate of Interest: 7.3

AXIS Rate of Interest: 9.7

 

이자율을 가져오는 Bank라는 클래스가 있다고 가정합시다.

하지만 은행마다 이자율이 조금씨 다를수도 있습니다. (카뱅이 그리 좋다죠..?)

도형을 예로 들면 이렇게 됩니다.

package polymorphism;

class Shape{  

void draw(){System.out.println("drawing...");}  

}  

class Rectangle extends Shape{  

void draw(){System.out.println("drawing rectangle...");}  

}  

class Circle extends Shape{  

void draw(){System.out.println("drawing circle...");}  

}  

class Triangle extends Shape{  

void draw(){System.out.println("drawing triangle...");}  

}  

class TestPolymorphism2{  

public static void main(String args[]){  

Shape s;  

s=new Rectangle();  

s.draw();  

s=new Circle();  

s.draw();  

s=new Triangle();  

s.draw();  

}  

}

output = 

drawing rectangle...

drawing circle...

drawing triangle...



 

JAVA Runtime Polymorphism with DataMember

오버라이드된 메소드는 데이터멤버가 아닙니다. 그래서 런타임 다형성은 데이터 멤버로 만들어질 수 없습니다.

아래의 예제를 보면 두개의 클래스가 speedlimit이라는 데이터멤버를 가지고있고 

자식객체를 참조하고있는 부모클래스 참조변수를 통해 데이터멤버에 접근해볼겁니다.

오버라이드되지않은 데이터멤버에 접근한다면, 부모클래스의 데이터멤버에 접근하게될겁니다. 

왜냐면 재정의되지않았기 떄문에 순수호출이 되는거니까요.


package polymorphism;


class Bike{  

 int speedlimit=90;  

}  

class Honda3 extends Bike{  

 int speedlimit=150;  

  

 public static void main(String args[]){  

  Bike obj=new Honda3();  

  System.out.println(obj.speedlimit);  

}

 }

output = 90.  


Java Runtime Polymorphism with Multilevel Inheritance.

다중레벨상속과 런타임 다형성에 대해서 간단하게 알아봅시다.

package polymorphism;


class Animal {

void eat() {

System.out.println("Animal: eating");

}

}


class Dog extends Animal {

void eat() {

System.out.println("Dog: eating fruits");

}

}


class BabyDog extends Dog {

void eat() {

System.out.println("BabyDog: drinking milk");

}


public static void main(String args[]) {

Animal a1, a2, a3;

a1 = new Animal();

a2 = new Dog();

a3 = new BabyDog();

a1.eat();

a2.eat();

a3.eat();

}

} output =

Animal: eating

Dog: eating fruits

BabyDog: drinking milk

감이 오시나요?

BabyDog이 Dog를 상속하고 Dog가 Animal을 상속합니다.

BabyDog이 가지고있는 오버라이드 메소드는 없기때문에 부모클래스의 eat()메소드를 가져옵니다.



반응형
by 발전소장 에르 :) 2017. 8. 9. 10:18
반응형

자바 Final Keyword 1편 보기. http://loganstory.com/229 

정리해보자면,

final 키워드는 변수,메소드,클래스에 사용될 수 있는데,

final은 오버로드와 오버라이드 그리고 상속이 제한된다는 점

하지만 순수호출은 가능하다는 점!

기억하고 계시나요?

그렇다면 맨 처음에 설명드렸던 초기화되지않은 파이널 변수에 대해서 알아보도록하죠.

Q) Blank or Uninitialized final variable이 무엇인가요?

A)선언되었을떄 초기화되지않은 파이널 변수를 Blank final variable이라고합니다.

만약, 여러분이 객체가 생성될 때 값이 초기화되고 바뀌지않는 변수를 만들고자 할 때 Blank final variable을 사용하시게 될텐데요.

(직원 고유번호, PIN번호 같은 곳에 쓰일 수 있다고합니다)

Blank final variable은 생성자 안에서만 초기화될수 있습니다.

이해를 도울 예제를 살펴보시죠.

blank final variable( 빈 파이널 변수)는 이렇게 생겼습니다.

          1. class Student{  
          2. int id;  
          3. String name;  
          4. final String PAN_CARD_NUMBER;  
          5. ...  
          6. }  

 

그럼 빈 파이널 변수를 초기화시킬 수 있을까요?

 생성자를 통해서만 가능합니다.

package fianl_keyword;


class Bike10{  

  final int speedlimit;//blank final variable  

   

  Bike10(){  

  speedlimit=70;  

  System.out.println(speedlimit);  

  }  

 

  public static void main(String args[]){  

    new Bike10();  

}  

}  

자. 살펴봅시다!

필드에 blank final variable을 선언해줬고,

생성자에서 speedlimit의 값을 70으로 초기화했습니다.

그리곤 메인메소드에서 찍어봤는데요.

70이 뙇!

그렇단 말은 생성자의 변수 초기화구문이 적용됬다는게 증명이 된거겠죠.

그리고 final 키워드앞에 static이 올수도있습니다.

그렇다면 static blank final variable을 생성할수도있다는 말이되지요.

허나, static block에서만 초기화가 가능합니다.

예제를 살펴보시죠.

package fianl_keyword;

class A{  

  static final int data;//static blank final variable  

  static{ data=50;}  

  public static void main(String args[]){  

    System.out.println(A.data);  

 }  

}

result = 50  

필드에 static blank final variable 생성해주고,

static{} 블럭안에서 해당 필드를 초기화해줍니다.

그리고 메인메소드에서 접근자 .(dot)을 통해서 호출을 해보면

50이라는 결과값이 나옵니다.

Q)  final 매개변수는 뭐에요..?

A) 쉽습니다. 메소드의 매개변수에 final키워드를 사용해주시면됩니다.

그럼 한번 입력받은 매개변수는 변경할 수 없는 상수가 되버리죠.


cube 메소드의 매게변수에 final int n 을 줍니다. 그리고 

연산식으로 n 변수를 연산해봅시다.


그리고 메인메소드에서 객체를 생성하고 매개변수로 5를 주면?


컴파일러 에러가 두둥!

에러를 해석해봅시다.package fianl_keyword;


class Bike11{  

  int cube(final int n){  

  n=n+2;//can't be changed as n is final  

  n= n*n;  

  }  

  public static void main(String args[]){  

    Bike11 b=new Bike11();  

    b.cube(5);  

}  

}  


Exception in thread "main" java.lang.Error: Unresolved compilation problems: 

This method must return a result of type int

The final local variable n cannot be assigned. It must be blank and not using a compound assignment

The final local variable n cannot be assigned. It must be blank and not using a compound assignment


at fianl_keyword.Bike11.cube(Bike11.java:4)

at fianl_keyword.Bike11.main(Bike11.java:10)



두둥... 에러내용을 해석해보자면 이렇습니다

"야, 사용자야 생각을 해보자.. 니가 매개변수에 final 줬지?

니가 값 바뀌는게 싫어서 매개변수를 상수로 정의했으면서 왜

그 상수로 연산식을 포함한 메소드를 실행시키는건데? 

돌아가 안되" 라고 하네요..

그럼 생성자에 final 키워드를 사용할 수 있을까요?

생성자는 상속되지않기때문에 final키워드를 사용할 수 없습니다..!!

모르시는 부분이나 애매한 부분은 댓글남겨주시면 감사하겠습니다 :)





반응형
by 발전소장 에르 :) 2017. 8. 8. 01:08
| 1 2 3 4 5 6 |