반응형

package com.access.string;


/*

 * 자바에서 String이란,  문자값들의 연속을 나타내는 객체이다.

 * 문자의 배열도 String과 똑같이 작동한다.

 * 

 *  compare(),concat(),equals(),split(),

 *  length(),replace(),compareTo(),intern(),substring()... 등 다양한 메소드를 지원한다.

 *  

 *  게다가 String은 아래의 3개 메소드를 구현하고있다.

 *  - Serializable

 *  - Comparable

 *  - CharSequence 

 *  

 *   

 */

public class StringTest {

public static void main(String[] args) {

//test1( );

//test2();

test3();

}


public void test() {

char[] ch = { 'j', 'a', 'v', 'a', 't', 'p', 'o', 'i', 'n', 't' };

String s = new String(ch);

System.out.println(s);

}


/*

* CharSequence Interface 는 문자의 연속을 나타내기위해 사용하는 인터페이스인데, 

* String, StringBuffer,StringBuilder 클래스들이 구현하고있다.

* String 객체를 만드는 2가지 방법이 있다. 

* 1. string literal 2. new keyword

* 1.쌍따옴표를 사용해서 객체를 생성한다. 

* String s = "welcome"; 과 같이 ""로 감싸서 String임을 JVM한테 알려준다. 

* 매번 String 문자를 만들때마다 JVM은 string contant pool을 체크한다.

*  만약 pool에 해당 string이

* 이미 존재한다면 pooling 인스턴스를 참조하여 리턴한다.

*/

public static void test2() {

String s1 = "Welcome";

String s2 = "Weclome"; // 새로운 인스턴스를 만들지않음.

/*

* 1번 방법으로 String 객체를 만들어봅시다.

*  먼저, "Welcome"이란 값을 가진 String객체를 string constant pool에서 JVM은 찾지않습니다. 

* s1 객체가 생성되면 그 다음 pool에서 "Welcome"이라는 값을 가진 string을 찾기

* 시작할겁니다.

* 그리고 pool에서 "Welcome"을 찾으면 새로 인스턴스를 생성하지않고 참조하고있는 인스턴스를 리턴하죠.

* 한마디로 이미 생성된 string에 대해서는 중복 인스턴스를 허용하지않고

*  효율적으로 같은 값을 가진 동일한 인스턴스를 리턴하게됩니다. 

*  (게다가, String object는 string constant pool이라는 특별한 메모리에 저장됩니다.)

* 그럼 자바는 왜 string literal 개념을 사용하는가? 

* 메모리를 효율적으로 관리하기위해서 위 개념을 사용하고있습니다. 

* 중복은 숙적이니까요.

*/


}


public static void test3() {

String s1 = "java";

char[] ch = { 's', 't', 'r', 'i', 'n', 'g', 's' };

String s2 = new String(ch); // new keyword로 string 객체를 생성.

String s3 = new String("example");

System.out.println(s1);

System.out.println(s2);

System.out.println(s3);

}

}


// String 객체의 메소드들은 나중에 한번에 정리해서 올리겠습니다~


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

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
반응형

Final Keyword In Java!!


fianl은 유저에게 엄격할 뿐더러 오직  변수, 메소드,  클래스총 3곳에 사용될 수 있습니다!

final 키워드는 변수와 함께 사용될 수 있고, 

값이 없는 빈 변수 혹은 초기화되지않은 빈 파이널 변수에 사용될 수 있습니다.

파이널 변수는 생성자에서만 초기화시킬 수 있고, 

빈 파이널 변수(Blank Final Variable)은 static이 될 수 있고 static 블럭안에서 초기화 될 수 있습니다.

감이 안오신다면 더 자세히 알아보도록할까요.

1) FINAL VARIABLE 

한번 선언하면 값을 바꿀 수 없습니다.

SWIFT에서 let의 역할을 하고있는것같네요.

예제를 한번 살펴봅시다.

Bike9클래스를 만든 후 필드에 speedlimit란 정수타입 변수에게 90의 초기값과 final키워드를 붙여줍니다.

그리고 run() 메소드에 위에서 초기화했던 speedlimit값을 재초기화하는 구문을 넣습니다.

Bike9클래스안에 main메소드를 넣고 인스턴스를 생성하고 매소드를 실행해봅시다.

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

The final field Bike9.speedlimit cannot be assigned


at fianl_keyword.Bike9.run(Bike9.java:7)

at fianl_keyword.Bike9.main(Bike9.java:12)


2번째 줄 보이시나요?  BIke9.speedlimit는 재정의될 수 없습니다.!

네, 맞아요 final이 걸리면 게다가 초기화가 된 채로 선언되면 바꿀수없어요.. 생성자도 아닌 메소드에선 더더욱..

2) Final Method

Bike클래스를 정의하고 final 메소드를 선언한다음에 

메인 메소드에서 자식 객체를 생성하여 

자식객체가 부모객체를 오버라이드한 메소드를 실행시켜볼 예정입니다.


Bike클래스를 상속받고 부모클래스의 메소드를 오버라이드했습니다.

그리고 실행해보지요.

두둥..


Exception in thread "main" java.lang.VerifyError: class fianl_keyword.Honda overrides final method run.()V





에러 덩어리네요.

중요한건 맨 위 2줄이라 나머지는 잘랐습니다만,

2번쨰 줄이 가장 중요하네요.

  final 메소드 run()을 오버라이드할 수 없습니다.!

슬슬 이해가 되시나요?

3) final class 

final키워드를 붙힌 Bike클래스를 만들고

final클래스인 Bike를 상속합니다(에러)


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

Honda cannot be resolved to a type


at fianl_keyword.Bike.main


final클래스를 상속하려고하니 

자바 컴파일러가 " 야, 이거 final이야 상속못해. 돌아가."

라고 합니다. 

Q)그럼, 메소드를 오버라이드하지 못해도 상속받는건 가능한가요?

A)네 가능합니다.!



fianl메소드를 오버라이드하는 건 불가능하지만, 순수 호출은 가능하다는거! 중요하겠지요?

정리해보자면,

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

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

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

2편에서 봐요~:)



반응형
by 발전소장 에르 :) 2017. 8. 7. 01:47
반응형

빈도가 되게 높다고는 할 수 없는 부분이지만, 

빼놓을 수도 없는 부분인 인스턴스 초기화 블럭 파트입니다.!

일단 , 쓰임새에 대해서 알아볼까요?


1)     인스턴스 데이터 멤버를 초기화 인스턴스 초기화 블록을 사용합니다.

2)    클래스의 객체가 생성될 마다 인스턴스 초기화 블록이 실행됩니다.


초기화 블럭의 정의 아래와 같습니다.

 

초기화 블럭(initialization block)

클래스 초기화 블럭 : 클래스 변수의 복잡한 초기화에 사용된다. 클래스가 처음 로딩될 한번만 수행된다.

인스턴스 초기화 블럭 : 인스턴스 변수의 복잡한 초기화에 사용된다. 인스턴스가 생성될때 마다 수행된다. (생성자보다 먼저 수행된다.)


Q)아래 코드처럼 개발자 직접 인스턴스 데이터 멤버에 값을 있는데,

굳이 인스턴스 초기화 블럭을 사용하나요?


class bike {

int speed = 100;

}



A) 인스턴스 초기화 블럭을 사용하는가?


인스터스 데이터 멤버에 값을 할당하면서 for 반복문으로 복잡한 배열이나 에러 처리 같은 어떤

작을 수행해야한다고 가정해봅시다.


package instance_initialize_block;


public class InstanceTest01 {

public static void main(String[] args) {

bike7 b1 = new bike7();

bike7 b2 = new bike7();

}


}


class bike7{

int speed;

public bike7() {

System.out.println("speed = " + speed);

// TODO Auto-generated constructor stub

}

{speed = 100;}

}

output=

speed = 100

speed = 100


여기서보면, 

bike7 클래스안에 별도의 {}블럭이 생성되어있고 

 speed = 100;으로 초기화시켜주고있네요.

일단 인스턴스 초기화 블럭의 모양이 저런 모양이구나 하고 넘어가봅시다.

자바에서 동작을 수행할 있는 곳은 세 곳이 있습니다.

  1. 메소드
  2. 생성자
  3. 블럭<<<<

그렇다면, 블럭이 위치한 로컬에 있는 변수의 초기값을 블럭의 내용대로 적용이 된것을 알 수가 있겠죠?

———————

 그렇다면, 인스턴스 블럭과 생성자 중에 무엇이 먼저 실행 될까요?


예제를 살펴보죠,

package instance_initialize_block;


public class InstanceTest02 {

public static void main(String[] args) {

bike8 b1 = new bike8();

bike8 b2 = new bike8();

}

}


class bike8{

int speed;

public bike8() {

System.out.println("생성자가 호출되었습니다.");

//생성자 

}

{System.out.println("인스턴스 초기 블럭이 호출되었습니다.");}

// 인스턴스블럭 

}




bike8이라는 테스트용 클래스를 만든 후 

생성자에 프린트를 찍어줍니다.

그리고 블럭을 삽입해 둘 중 누가 먼저 실행될지에 대해서 테스트해보도록하죠.


메인 메소드를 가지고있는 InstanceTest02 클래스에

bike8클래스 객체를 만들어서 테스트해보도록하겠습니다.

위 상태로 실행시키면, b1이 실행되고 b2가 실행되겠죠.

이때 생성자가 먼저 호출이 될건지, 블럭이 먼저 호출이 될건지 봅시다.



의외로 생성자가 먼저 호출이 된 결과값이네요.

왜그런지 알아볼까요?


실은, 인스턴스 초기화 블럭이 먼저 호출이 되는 것처럼보이지만은,

객체가 생성될때 인스턴스 초기화 블럭이 호출됩니다. ( 거의 동시에)

자바 컴파일러는 첫 문장 super() 키워드 이후에 생성자 안에 있는 인스터스 초기화 블럭을 카피합니다.

그래서 결과값과는 살짝 다르게 생성자를 먼저 호출하는 셈이죠.

아래에 이해를 돕는 예제와 표를 첨부했습니다.

위에 표에서는 숨어있던 super()가 나오네요 !

실행 순서는

super() > instance initialize block > constructor of local 순서가 되겠네요.

bike클래스가 상속받을 parentOfBike클래스를 만들어주고

생성자에 프린트문으로 찍어줍니다.(누가 먼저 호출되는지 구분하기위해서)

별 다른 설명이 없습니다.

실행하였을때 

super()로 부모클래스의 생성자가 호출되고

인스턴스 초기화 블럭에 있던 구문이 실행되고

로컬 클래스에 생성자가 호출되었네요.

이제 이해가 가시나요?

안가신다면 잠시 여유를 가져보는 건 어떨까요?

인스턴스 초기화 블럭은 주된 3가지 규칙에 의해 사용되는데 

아래와 같습니다.

1) 인스턴스 초기화 블럭은 클래스의 인스턴스가 생성될 때 생성됩니다.

2)부모 클래스 생성자를 호출한 후 인스턴스 초기화 블럭이 호출됩니다.

3) 인스턴스 초기화 블럭은 기술된 순서대로 나타납니다.

마지막 예제를 보시죠!

부모 클래스를 만들고~

A를 상속할 B3클래스를 만들어주고~

생성자에 super()키워드를 넣어줍니다.

오버로드한 생성자에 int a라는 매개 변수를 삽입하고

B3클래스 최하단에 인스턴스 초기화 블럭을 선언해줍니다.

그리고는 객체를 만들 때 매개변수를 준 객체와 안준 객체를 

생성하면 어떻게 될까요?

결과값을 보면 이해가 잘 되시나요?

다시한번 되짚어보자면

super() > instance initializer block > constructor of local class.

꼭 기억하시고 열공하시길 바랍니다 :)


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

자바 - super키워드의 마지막 장입니다.

super 키워드의 3개가지 쓰임새를 알아봤었는데요.

1)  super키워드를 이용해서 부모클래스 객체의 변수를 참조하고자할때

2)  super키워드를 이용하여 부모클래스의 메소드를 실행하고자할떄

3) super 키워드는 부모클래스의 생성자를 호출하는데 사용됩니다.


3) super 키워드는 부모클래스의 생성자를 호출하는데 사용됩니다.<<

이제 시작해보죠,


package super_keyword;


public class SuperTest03 {

public static void main(String[] args) {

Dog3 d3 = new Dog3();

}

}

// 여러분이 머릿속으로 컴파일하였을때의 실행값은 어떨거같나요?


class Animal03{

//Animal03-Con

Animal03(){

System.out.println("Animal03 is created");

}

}

// 이전 예제들과의 중복을 피하기위해 Animal03이라는 부모가 클래스를 생성하고

생성자를 줍니다.


class Dog3 extends Animal03{

//Dog-Con

Dog3(){

super();

System.out.println("Dog is created");

}

}

//위와 동일합니다.


그리곤 SuperTest03 통해 실행시켜보기로하죠.



네 맞습니다.

Dog3(){

super();

System.out.println("Dog is created"); }

우리는 Dog3생성자에서 super(); 를 먼저 썻기때문에

우리는 컴파일러한테 

" 야 컴파일러야 내가 Dog3 클래스에 생성자를 니가 자동으로 만들어주지만,

이번엔 내가 따로 명시해서 만들거야. 근데, super();를 넣을거야 

무슨 말인지 알지?"

뭐 대충 이런 뜻입니다.

쉽지요?ㅎㅎㅎㅎㅎㅎ

super()나 this()가 명시되지않았다면, 컴파일러는 자동으로 각 클래스의 생성자에 super()를 자동으로 삽입합니다. 허나, 우리가 못볼뿐!

이번에는 우리가 명시해줬던 super(); 키워드를 빼고!

기본으로 Dog클래스의 객체만 만들어서 실행해봅시다.

잉?! 결과가 똑같네요.

그말인 즉슨 우리가 명시를 하든안하든 컴파일러는 자동으로 명시해준단 말이죠.

다만 에디터에서 안보일 뿐이랍니다.!


그럼 주로 쓰이는 super 키워드의 형태를 한번 알아볼까요?

package super_keyword;


public class SuperTest04 {

public static void main(String[] args) {

EMP emp = new EMP(1, "신입", 2200f);

emp.display();

}

}


class person{

int id;

String name;

person(int id, String name){

this.id = id;

this.name = name;

}

}


class EMP extends person{

float salary;

EMP(int id, String name , float salary){

super(id,name); // 부모의 생성자를 재사용!

this.salary = salary;

}

void display(){

System.out.println("id = " + id + ", name = " + name + ", salary = " + salary);

}

}

부모클래스가 될 person 클래스를 만들고 

필드와 생성자를 만들어줍니다.

person(int idString name){

this.id = id;

this.name = name;

} 여기서 this.를 주는 이유는 person클래스 내의 id를 사용하는거니까 

헷갈려하지마 컴파일러야~ 라고 알려주는 겁니다.

this.를 안붙히면 이클립스는 int id라는 다른 변수를 생성해버리기 때문에

결론적으론 두개의 id가 person클래스 내의 존재하게되는겁니다.

물론 스코프 범위가 다르기 때문에 서로의 충동들 없습니다.


class EMP extends person{

float salary;

EMP(int idString name , float salary){

super(id,name); // 부모의 생성자를 재사용!

                // 코드의 중복을 최소화시키는 것을 늘 고려하기 때문에,

                 //우리는 EMP에서 다시 새로운 변수를 만들지않았습니다.

this.salary = salary;

}

void display(){

System.out.println("id = " + id + ", name = " + name + ", salary = " + salary);

} 어떤값이 나오나 한번 출력해보도록 하죠.


보신바와 같이 id, name은 부모클래스의 필드값들입니다.

코드의 중복을 최소화하고, 손쉽게 재사용할 수 있으며 다형성을 유지하기 위해서 

좀 과장해서말하면 완소키워드라고 할 수 있겠습니다 ㅎㅎㅎ


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

저번에는 super키워드를 이용해 부모클래스의 필드에 접근하면 방법에 대해 다뤄보았습니다.

이번에는 super키워드로 부모클래스의 메소드에 접근하는 방법을 다뤄보도록 합시다.



2) super 키워드는 부모클래스 메소드를 실행할때 사용될 있습니다.


사용하기에 앞서 몇가진 선행조건이 있는데 아래와 같습니다.


 super 키워드는 부모 클래스의 메소드를 실행하기위해 사용될때에는 

자식 클래스와 부모클래스와 똑같은 메소드를 가지고 있어야하고,

부모크래스의 메소드가 자식클래스에서 오버라이드 되어있어야합니다.






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

자바의 SUPER KEYWORD


자바에서 super키워드는 부모 클래스 객체를 참조하는 변수를 참조합니다.

 

하위 클래스의 인스턴스를 생성 때마다, 부모 클래스의 인스턴스가 잠적으로 만들어지며 이는 super 참조 변수에 의해 참조됩니다.



  Super Keyword 쓰임새

  

1.super 부모클래스의 인스턴스 변수로 참조 있습니다.

2.super 부모클래스 메소드를 바로 사용하기위해 사용될 있습니다.

3. super() 부모클래스 생성자를 바로 사용하기위해 사용될 있습니다.


  1. super 부모 클래스 인스턴스 변수를 참조하기위해 사용될


super keyword 부모클래스의 필드나 데이터 멤버에 접근하기 위해 사용할 있는데,

부모클래스와 자식클래스가 같은 이름의 필드를 가질 사용됩니다. 


SuperTest01이라는 클래스를 만들어주세요.


Animal이라는 부모가 될 클래스르 만들고 


자식클래스가될 Dog클래스를 만들고 Animal을 상속합시다.

그리고 찍어볼수있게 리턴 타입이 void인 메소드를 만듭니다.



그리고 메인 메소드를 가진  SuperTest01객체에서

Dog클래스를 생성하고 Dog 객체의 메소드를 호출하고 결과값을 봅시다.!



결과값이 보이시죠? 예상했던 결과인가요?



자세히 들여야본다면,  Animal클래스과 Dog클래스 모두 color라는 공통된 필드가 있는데,

아무런 키워드없이 Dog객체를 생성하고 color 필드를 그냥 찍는다면,

 Dog color값만 나오게될테죠


그렇다고 일일이 Animal클래스를 객체생성하여 사용하기에는 상속의 의미가 없어지고

이를 해결하기위해     super.이라는 키워드를 사용하여

별다른 절차없이 바로 부모클래스의 필드값으로 접근할 있습니다

자바에서는 다중 상속을 막아놨기 때문에 헷갈릴 필요도 없지요.

정말로 진짜 진심으로 다중상속이 필요하다면 인터페이스를 이용하면됩니다.

그리고,  



이해가 잘 되셨나요? 

계속 super keyword의 쓰임새를 알아보도록 하지요!


반응형
by 발전소장 에르 :) 2017. 8. 2. 12:16
| 1 2 |