안녕하세요, 여행벌입니다.

오늘은 자바의 인터페이스(interface) 가 무엇인지, 문법 구조가 어떻게 되는지, 언제 사용하는지 알아보겠습니다.


인터페이스(interface)

 인터페이스의 사전적 의미는 "연결점" 또는 "접점"으로

자바에서는 둘 사이를 연결하는 매개체의 역할을 합니다.

인터페이스(interface) 기본 문법

 인터페이스는 문법적인 면에서 클래스와 굉장히 비슷합니다.

interface 인터페이스이름{
	// 변수들
	// 메소드들
}

 class 대신 interface 선언이 붙어있고, 마찬가지로 안에는 각종 변수와 메소드가 존재합니다. 하지만, 기본적으로 메소드는 몸체가 비어 있는 "추상 메소드" 입니다.  아래와 같이 몸체가 비어 있는 메소드를 추상 메소드라고 합니다.

public void example(int a);

 그럼 인터페이스의 메소드는 몸체가 비어 있는데 어떤 기능을 할까요?? 클래스에서 인터페이스를 '상속' 이 아닌 "구현"을 하고, 이때 비어있는 메소드인 "추상 메소드" 를 클래스에서 구현해서 사용합니다. 즉, 저번 포스팅에서 다룬 오버라이딩을 통해 추상 메소드를 이용할 수 있습니다.

 

인터페이스에는 다음과 같은 특징이 있습니다.

 

● 인터페이스는 인스턴스 생성이 불가능하다.

● 인터페이스형을 대상으로 참조 변수 선언은 가능하다.

● 인터페이스는 클래스가 "상속" 하는게 아닌 "구현"을 하고 implements 키워드를 사용한다.

● 한 클래스가 둘 이상의 인터페이스를 동시에 구현할 수 있다.

● 추상메소드와 이를 구현하는 메소드 사이에 오버라이딩이 성립하고, @Override 어노테이션을 사용할 수 있다.

● 인터페이스 안에 있는 모든 "추상 메소드"를 구현하지 않으면, 해당 클래스를 대상으로 인스턴스 생성은 불가능하다.

 

 그럼 간단한 예시를 통해서 인터페이스의 특징을 살펴보겠습니다.

package Hello;

interface print{
	public void print(String name);
}

class printName implements print{
	@Override
	public void print(String name) {
		System.out.println(name + "님 환영합니다.");
	}
}

public class test{
	public static void main(String args[]) {
		printName ex1 = new printName();
		ex1.print("travelbeeee");
		
		print ex2 = new printName();
		ex2.print("travelbeeee2");
		
	}
}
[Output]
travelbeeee님 환영합니다.
travelbeeee2님 환영합니다.

 printName 이라는 클래스에서 print 인터페이스를 구현해, 추상 메소드를 사용하는 모습을 볼 수 있습니다. 또, 인터페이스 형을 대상으로 참조 변수 선언을 하고 메소드를 이용하는 모습도 볼 수 있습니다.

인터페이스 변수

 인터페이스 안에도 변수를 선언할 수 있습니다. 클래스와는 다르게 변수는 다음과 같은 특징을 가집니다.

 

● 선언과 동시에 값을 초기화 해야 한다.

● 모든 변수는 public, static, final 이 선언된 것으로 간주한다. 즉, 고정된 값 "상수" 가 된다.

 

 인터페이스 변수는 "상수"로 선언되므로, 인터페이스 변수명은 관례적으로 대문자로 짓습니다.

interface print{
	string INTERFACE_NAME = "print_Interface";
	int INTERFACE_AGE = 9999;
	public void print(String name);
}

인터페이스 메소드

 인터페이스 안에는 "추상 메소드" / "디폴트(default) 메소드" / "클래스(static) 메소드" 를 선언할 수 있습니다.

 추상 메소드는 위에서 다뤘듯이 몸체가 비어 있는 메소드를 의미하고, 추상 메소드는 기본적으로 public이 선언된 것으로 간주합니다. 추상 메소드는 인터페이스를 구현하는 클래스 내에서 오버라이딩을 통해 전부 구현해줘야하고, 구현하지 않은 추상 메소드가 존재하면 안됩니다.

 

 디폴트 메소드는 자바8에서 처음 소개된 기능입니다. 추상 메소드와 다르게 자체로 완전한 메소드이고, 이를 구현하는 클래스가 오버라이딩 하지 않아도 됩니다. 이미 기존에 구현한 인터페이스에 메소드를 추가해야되는 경우에 디폴트 메소드를 이용하면, 이를 구현하고 있는 모든 클래스들에게 영향을 주지 않고 메소드를 추가할 수 있습니다.

 

 클래스 메소드도 자바8에서 처음 소개된 기능입니다. 클래스에 정의하는 static 메소드와 유사하게, 자체로 완전한 메소드이고 따로 구현하지 않아도 되고, 클래스의 static 메소드 호출 방법과 동일합니다.

package Hello;

interface print{
	public void print1( ); // 추상메소드
	default void print2() { // 디폴트메소드
		System.out.println("디폴트메소드입니다.");
	}
	public static void print3() { // 클래스 메소드
		System.out.println("클래스메소드입니다.");
	}
}

class printName implements print{
	@Override
	public void print1() {
		System.out.println("추상메소드입니다.");
	}
}

public class test{
	public static void main(String args[]) {
		print.print3();
		printName ex1 = new printName();
		ex1.print1();
		ex1.print2();
	}
}
[Output]
클래스메소드입니다.
추상메소드입니다.
디폴트메소드입니다.

 클래스 메소드는 인스턴스 생성 없이도 사용이 가능하고, 디폴트 메소드는 클래스 내에서 따로 구현하지 않고 사용하는 것을 볼 수 있습니다.

인터페이스 상속

 인터페이스도 클래스처럼 서로 상속이 가능합니다. extends 키워드를 사용해야하고, 클래스의 상속과 동일하게 작동합니다.

interface print{
	public void print1( ); // 추상메소드
	default void print2() { // 디폴트메소드
		System.out.println("디폴트메소드입니다.");
	}
	public static void print3() { // 클래스 메소드
		System.out.println("클래스메소드입니다.");
	}
}

interface colorPrint extends print{
	public void colorPrint1();
	default void colorPrint2() {
		System.out.println("칼라프린트의 디폴트메소드");
	}
	public static void colorPrint3() {
		System.out.println("칼라프린트의 클래스메소드");
	}
}

class printName implements colorPrint{
	@Override
	public void print1() {
		System.out.println("추상메소드입니다.");
	}
	@Override
	public void colorPrint1() {
		System.out.println("칼라프린트의 추상메소드");
	}
}

 마찬가지로 추상 메소드는 클래스에서 모두 구현해줘야합니다.


인터페이스를 사용하면 서로 다른 클래스에게 접점을 만들어 줄 수 있습니다.

다르지만 공통된 기능이 필요한 경우에 인터페이스를 만들고,

클래스마다 구현해 사용한다면 훨씬 효율적으로 코드를 구현할 수 있습니다.

이처럼, 인터페이스는 자바에서 많은 역할을 해줍니다.

 

 

 

 

안녕하세요, 여행벌입니다.

오늘은 저번 포스팅 상속에 이어서 오버라이딩에 대해서 포스팅해보겠습니다.


메소드 오버라이딩(Overriding)

메소드 오버라이딩은 상위 클래스에 정의된 메소드를 하위 클래스에서 다시 정의하는 것을 뜻합니다.

 

 오버라이딩을 위해서는 메소드의 이름, 메소드의 반환형, 메소드의 매개변수 선언이 모두 같아야 합니다. 메소드 오버라이딩이 발생하면 자바는 상위 클래스의 메소드를 무효화시키고, 하위 클래스의 메소드를 살려둡니다.

 예시를 통해서 익혀보겠습니다.

package Hello;

class supClass{
	public supClass() {}; //생성자
	void sayHello() {
		System.out.println("supClass Hello");
	}
}

class subClass extends supClass{
	public subClass() {}; // 생성자
	void sayHello() {
		System.out.println("subClass Hello!!");
	}
}

public class test{
	public static void main(String args[]) {
		// supClass 참조변수가 supClass 인스턴스 --> 오버라이딩 X
		supClass class1 = new supClass();
		class1.sayHello();
		
		// supClass 참조변수가 subCLass 인스턴스 --> 오버라이딩 O
		supClass class2 = new subClass();
		class2.sayHello();
		
		// subClass 참조변수가 subClass 인스턴스 --> 오버라이딩 O
		subClass class3 = new subClass();
		class3.sayHello();
	}
}

 상위 클래스와 그 클래스를 상속하는 하위 클래스를 만들었습니다. 하지만, 상위 클래스와 하위 클래스에  반환형 / 메소드의 이름 / 메소드의 매개 변수가 모두 같은 sayHello 라는 메소드가 존재합니다. 

 

 저번 포스팅에서 상속을 진행하면 상위 클래스의 변수, 메소드가 모두 하위 클래스에게 전달된다고 얘기했습니다. 따라서, 같은 메소드가 동시에 2개 존재하는 상황이 발생합니다. 이때, 자바에서는 메소드 오버라이딩을 통해 상위 클래스의 메소드를 무효화시키고, 하위 클래스의 메소드만 남겨둡니다.

[Output]
supClass Hello
subClass Hello!!
subClass Hello!!

 그럼, 상위 클래스 메소드를 하위 클래스에서 사용하고 싶다면 어떻게 해야될까요? super 키워드를 이용하면 사용할 수 있습니다.

package Hello;

class supClass{
	public supClass() {}; //생성자
	void sayHello() {
		System.out.println("supClass Hello");
	}
}

class subClass extends supClass{
	public subClass() {}; // 생성자
	void sayHello() {
		super.sayHello();
		System.out.println("subClass Hello!!");
	}
}

public class test{
	public static void main(String args[]) {
		// subClass 참조변수가 subClass 인스턴스 --> 오버라이딩 O
		subClass class1 = new subClass();
		class1.sayHello();
	}
}

 다음과 같이 super 키워드를 이용하면 상위 클래스의 메소드 또한 이용할 수 있습니다.

인스턴스 변수, 클래스 변수, 클래스 메소드의 오버 라이딩

 그럼 인스턴스 메소드가 아닌 인스턴스 변수와 클래스 변수, 클래스 메소드도 오버 라이딩이 될까요?? 결론부터 얘기하면 오버라이딩 대상이 아닙니다.

 자바는 '참조변수의 형' 에 따라서 접근하는 변수가 결정되므로 클래스 변수, 클래스 메소드, 인스턴스 변수는 오버라이딩 되지 않습니다.

package Hello;

class supClass{
	int a = 1;
	static int b = 2;
	static void sayBye() {
		System.out.println("supClass Bye!!");
	}
	public supClass() {}; //생성자
	void sayHello() {
		System.out.println("supClass Hello");
	}
}

class subClass extends supClass{
	int a = -1;
	static int b = -2;
	static void sayBye() {
		System.out.println("subClass Bye!!");
	}
	
	public subClass() {}; // 생성자
	void sayHello() {
		super.sayHello();
		System.out.println("subClass Hello!!");
	}
}

public class test{
	public static void main(String args[]) {
		//supClass 참조변수가 supClass 인스턴스 참조
		supClass class1 = new supClass();
		System.out.println(class1.a + " " +  class1.b);
		class1.sayBye();
		
		// supClass 참조변수가 subClass 인스턴스 참조
		// 인스턴스 메소드였으면 원래 오버라이딩 되는 상황
		supClass class2 = new subClass();
		System.out.println(class2.a + " " + class2.b);
		class2.sayBye();
	}
}

 동일한 이름의 인스턴스 변수(a), 클래스 변수(b), 클래스 메소드(sayBye) 를 상위 클래스와 하위 클래스에서 모두 선언했습니다. 하지만, 오버라이딩 대상이 아니므로 결과는 다음과 같이 참조변수의 형에 따라서 supClass의 인스턴스 변수, 클래스 변수, 클래스 메소드를 참조하는 것을 알 수 있습니다.

[Output]
1 2
supClass Bye!!
1 2
supClass Bye!!

클래스와 메소드의 final 선언

 클래스와 메소드에 final 선언을 추가하면 해당 클래스 혹은 해당 메소드를 다른 클래스가 상속, 오버라이딩 하지 못하게 막을 수 있습니다. 대표적인 final 클래스로 String 클래스가 있습니다. 따라서, 우리는 String 클래스를 상속할 수 없습니다.

final class myClass { } // 다른 클래스가 상속할 수 없는 클래스

class myClass2{
	final void func(){ } // 메소드 오버라이딩을 할 수 없는 메소드
}

@Override

 자바 5에서 '어노테이션' 이 소개되었습니다. 그 중, 메소드 오버라이딩과 관련된 @Override 어노테이션에 대해서 알아보겠습니다.

 우리는 메소드 오버라이딩을 의도하고 코드를 구현했지만, 개발자의 실수로 오버라이딩 조건을 만족하지 못해서 오버라이딩이 진행되지 않는 상황이 발생할 수 있습니다.

package Hello;

class supClass{
	public supClass() {}; //생성자
	void add(int a, int b) {
		System.out.println(a + b);
	}
}

class subClass extends supClass{
	public subClass() {}; // 생성자
	// 메소드 오버라이딩
	void add(double a, double b) {
		System.out.println(a + b);
	}
	
}

public class test{
	public static void main(String args[]) {
		subClass class1 = new subClass();
		class1.add(5, 7);
	}
}

subClass 에서 supClass의 add 메소드를 오버라이딩 하려고 하였으나, 매개변수형이 int 형이 아닌 double 형이라 오버라이딩이 발생하지 않은 상황입니다. 이런 상황을 @Override 어노테이션을 통해서 해결할 수 있습니다.

class supClass{
	public supClass() {}; //생성자
	void add(int a, int b) {
		System.out.println(a + b);
	}
}

class subClass extends supClass{
	public subClass() {}; // 생성자
	// 메소드 오버라이딩
	@Override
	void add(double a, double b) {
		System.out.println(a + b);
	}
}

 @Override 어노테이션을 사용하면 자바 컴파일러에게 메시지를 전달할 수 있습니다. 즉, 나는 메소드 오버라이딩을 하고 싶어요! 라고 자바 컴파일러에게 전달하는 메시지입니다. 따라서, @Override 어노테이션을 오버라이딩을 원하는 메소드 위에 선언하면 반환형, 메소드의 이름, 매개 변수가 모두 같은 오버라이딩 가능한 메소드가 없다면 자바 컴파일러가 코드가 잘못 구현되었다고 알려줍니다.


 

안녕하세요, 여행벌입니다.

오늘은 객체지향 언어인 자바의 중요한 문법, 상속에 대해서 포스팅해보겠습니다.


상속(Inheritance) 의 객체지향적 역할

"상속이란 연관된 일련의 클래스들에 대해 공통적인 규약을 정의해준다."

 

 상속이란 문법의 가장 큰 역할은 위와 같습니다. 그럼 어떻게 상속을 사용하고, 상속의 특징으로는 어떤 특징들이 있는지 알아보겠습니다.

상속(Inheritance) 이란

 상속은 쉽게 얘기하면 이미 기존에 정의된 클래스에 메소드와 변수를 추가하여 새로운 클래스를 정의하는 것을 의미합니다. 즉, 이미 만들어진 클래스에 우리가 원하는 기능과 데이터를 추가해서 새로운 클래스를 만드는 행위입니다.

 extends 키워드를 이용해 상속을 활용할 수 있습니다.

 

 그럼, 간단하게 이름을 가지고 있는 사람이라는 클래스에 핸드폰 번호도 추가해서 새롭게 클래스를 만들어보겠습니다.

class people{
	String name;
    void tellYourName(){}
}

class richPeople extends people{
	String phoneNum;
    void tellYourPhontNum(){}
}

 people이라는 클래스를 extends 상속해서 richPeople이라는 새로운 클래스를 만들었습니다.

그럼, richPeople 이라는 새로운 클래스는 people 클래스에 있는 변수와 메소드를 가져와 사용할 수 있습니다. 즉, richPeople이라는 클래스는 실제로 아래 그림과 같습니다.

이처럼

● 상속을 하는 클래스를 하위 클래스, 자식 클래스

상속을 당하는 클래스를 상위 클래스, 부모클래스  라고 부릅니다.  

상속(Inheritance) 과 생성자

 모든 클래스는 생성자 메소드가 존재한다고 앞의 포스팅에서 얘기했습니다. 그러면, 상속 관계에서는 생성자 호출이 어떤 식으로 진행될까요??

 다음 예제를 통해서 하위 클래스 인스턴스를 생성하면 생성자 호출이 어떻게 진행되는지 보겠습니다.

package Hello;

class people{
	String name;
	public people() {
		System.out.println("상위클래스생성사호출");
	}
}

class richPeople extends people{
	String phoneNum;
	public richPeople() {
		System.out.println("하위클래스생성자호출");
	}
}

public class test{
	public static void main(String args[]) {
		new richPeople();
	}
}
[Output]
상위클래스생성사호출
하위클래스생성자호출

 예시를 통해 아래와 같은 두 가지 사실을 알 수 있습니다.

 

● 하위 클래스의 인스턴스 생성 시 상위 클래스, 하위 클래스의 생성자가 모두 호출된다.

● 하위 클래스의 인스턴스 생성 시 상위 클래스의 생성자가 먼저 호출된다.

 

 즉, 하위 클래스의 인스턴스를 생성할 때 상위 클래스의 생성자를 먼저 호출해줘야 한다는 것을 알 수 있습니다. 따라서, 다음과 같이 클래스의 생성자를 구현할 수 있습니다.

package Hello;

class people{
	String name;
	public people(String name) {
		this.name = name;
	}
}

class richPeople extends people{
	String phoneNum;
	public richPeople(String name, String phoneNum) {
		super(name);
		this.phoneNum = phoneNum;
	}
}

public class test{
	public static void main(String args[]) {
		new richPeople();
	}
}

키워드 super 를 이용하면 '상위 클래스의 생성자 호출' 을 할 수 있습니다.

클래스 변수, 클래스 메소드의 상속

 static 선언이 붙는 클래스 변수와 클래스 메소드는 인스턴스 생성과 상관 없이 유일하게 존재한다고 앞에서 배웠습니다. 따라서, 클래스 변수와 클래스 메소드는 상속의 대상이 아닙니다. 그러면, 상위클래스의 클래스 변수와 클래스 메소드는 하위 클래스에서 이용할 수 있을까요?? 

 접근 수준 지시자가 접근을 허용하면 하위 클래스에서도 상위 클래스의 클래스 변수와 클래스 메소드에 접근이 가능합니다.

package Hello;

class people{
	// 클래스 변수와 메소드
	static int num = 9999;
	static void showNum() {
		System.out.println(num);
	}
	
	String name;
	public people(String name) {
		this.name = name;
	}
}

class richPeople extends people{
	String phoneNum;
	public richPeople(String name, String phoneNum) {
		super(name);
		this.phoneNum = phoneNum;
	}
}

public class test{
	public static void main(String args[]) {
		richPeople ex1 = new richPeople("travlebeee", "010-0000-0000");
		ex1.showNum();
		ex1.num++;
		ex1.showNum();
	}
}
[Output]
9999
10000

 private 접근 수준 지시자로 선언이 되어있다면, 하위 클래스에서 접근할 수 없지만 다른 접근 수준 지시자들은 접근이 가능합니다.

상속과 참조변수

 하위 클래스는 상위 클래스의 특징을 다 가지고 있다고 했습니다. 그러면, 하위 클래스의 참조 변수로 상위 클래스를 참조하거나 상위 클래스의 참조 변수로 하위 클래스를 참조하는 게 가능할까요??

 예시를 통해서 자세히 알아보겠습니다.

class people{
	String name;
	public people(String name) {
		this.name = name;
	}
	
	void showYourName() {
		System.out.println("내이름은 : " + name);
	}
}

class richPeople extends people{
	String phoneNum;
	public richPeople(String name, String phoneNum) {
		super(name);
		this.phoneNum = phoneNum;
	}
	void showYourPhone() {
		System.out.println("내 번호는 : " + phoneNum);
	}
}

 위와 마찬가지로 people 클래스를 richPeople이 상속하고 있는 경우입니다.

 먼저, 상위 클래스의 참조 변수로 하위 클래스를 참조해보겠습니다.

public class test{
	public static void main(String args[]) {
		// 상위 클래스 참조 변수로 하위 클래스 참조
		people p1 = new richPeople("travelbeeee", "010-0000-0000");
		p1.showYourName(); // 가능
		p1.showYourPhone(); // 불가능
	}
}

 richPeople은 people 클래스의 자식이기 때문에, 상위 클래스의 참조 변수로도 하위 클래스의 인스턴스를 참조할 수 있습니다. 하지만, 자바는 참조 변수를 기준으로 판단하기 때문에, people 클래스의 참조 변수 p1은 people 클래스의 메소드인 showYourName() 메소드는 호출이 가능하나 showYourPhone() 메소드는 호출이 불가능합니다.

 

 반대 상황도 보겠습니다.

public class test{
	public static void main(String args[]) {
		// 하위 클래스 참조 변수로 상위 클래스 참조
		richPeople p1 = new people("travelbeeee"); // 불가능
	}
}

 이번에는 하위 클래스 참조 변수로 상위 클래스를 참조하고 있기 때문에, 애초에 참조가 불가능합니다.

 

 상위 클래스가 부모이므로 부모가 자식을 참조할 수는 있으나 하위 클래스인 자식이 부모를 참조할 수는 없다! 라고 외우시면 편할 것 같습니다.


이상으로, 상속에 대한 기본 정리를 마무리해보겠습니다.

다음 포스팅에서는 메소드 오버라이딩을 추가로 정리해보도록 하겠습니다.

 안녕하세요, 여행벌입니다.

 오늘은 가장 많이 사용하는 자료구조인 배열을 생성하는 방법, 데이터를 저장 및 참조하는 방법, 특성에 대해서 알아보겠습니다.


배열 (Array)

 배열은 '자료형이 같은 둘 이상의 값'을 저장할 수 있는 메모리 공간을 의미합니다.

, 자료형이 같은 여러 가지 값들을 모아서 저장할 때 사용하는 자료구조입니다.

 

 자바에서의 배열은 클래스로 정의되어있으므로, 우리는 인스턴스를 생성해서 배열을 이용할 수 있습니다. 또, length 라는 인스턴스 변수를 지원해줘서 배열의 길이도 쉽게 알 수 있습니다.

배열의 선언 및 초기화

자료형[ ] 변수명 = new 자료형[크기];    // 더 선호하는 방식
자료형 변수명[ ] = new 자료형[크기];
package Hello;

public class test{
	public static void main(String args[]) {
		int[] list = new int[5];
		int list2[] = new int[5];
	}
}

  두 가지 방법으로 선언할 수 있고, list과 list2 모두 자료형 int 를 5개 저장할 수 있는 배열을 선언했습니다. 배열의 길이는 고정되어 있으므로, 처음에 선언할 때 배열의 크기를 자바에게 알려줘야 됩니다.

package Hello;

public class test{
	public static void main(String args[]) {
		int[] list = new int[] {1,2,3,4,5};
		int[] list2 = {1,2,3,4,5};
	}
}

 배열을 선언과 동시에 초기화할 수도 있습니다.

 위와 같이 배열을 선언하면서 동시에 초기화할 수 있습니다. 자바에서 배열의 크기를 5로 자동으로 인식하므로 크기를 전달하지 않아도 문제가 없습니다.

배열의 값 저장, 참조

  그럼 이렇게 선언한 배열에 값을 저장하거나 참조하려면 어떻게 해야 될까요?

 

 배열은 인덱스를 이용해서 참조할 수 있고, 인덱스는 0번 부터 시작합니다!

 

 즉, 5개를 저장할 수 있는 배열을 선언하면 5개의 메모리 공간이 생기고 인덱스로 참조할 수 있습니다. 이때, 인덱스는 0번부터 시작해 4번에서 끝이 납니다.

package Hello;

public class test{
	public static void main(String args[]) {
		int[] list = new int[5];
		list[0] = 1;
		list[1] = 2;
		list[2] = 3;
		list[3] = 4;
		list[4] = 5;
	}
}

 크기가 5인 배열을 선언해 맨 앞부터 1, 2, 3, 4, 5를 저장했습니다.

 배열은 0번 인덱스부터 시작하므로, 다음과 같이 메모리 공간에 데이터들이 위치하고 있는 것을 예측할 수 있습니다.

 

 그러면, 2차원 혹은 3차원 배열은 어떻게 선언할까요? 1차원 배열과 크게 다르지 않습니다.

package Hello;

public class test{
	public static void main(String args[]) {
		int[][] list = new int[2][3];
	}
}

 2차원 배열은 위의 그림과 같이 2행 3열로 이루어졌습니다. 마찬가지로 데이터를 참조할 때는 인덱스를 이용해 다음과 같이 참조할 수 있습니다.

package Hello;

public class test{
	public static void main(String args[]) {
		int[][] list = new int[2][3];
		list[0][0] = 1;
		list[0][1] = 2;
		list[0][2] = 3;
		list[1][0] = 4;
		list[1][1] = 5;
		list[1][2] = 6;
	}
}

 자바는 다른 언어와 달리 다음과 같은 배열 특성을 가지고 있습니다.

package Hello;

public class test{
	public static void main(String args[]) {
		int[][] list = { { 1, 2, 3}, { 4, 5}, {6} };
	}
}

 다음과 같이 2차원 배열을 선언하면 3행 3열의 배열이 선언될까요?? 아니면 채워지지 않은 공간은 메모리가 할당되지 않을까요??

 정답은 오른쪽 그림입니다!  자바는 배열의 가로길이가 행 별로 다른 2차원 배열을 생성할 수 있습니다. 즉, 초기화를 잘못하여 예상과는 다른 길이의 배열이 만들어지지 않도록 주의해야 합니다.

배열의 참조 값과 메소드

 위에서 우리는 배열 인스턴스를 생성해 사용한다고 말씀드렸습니다. 따라서, 당연히 메소드 호출 시 참조 값으로 배열을 전달할 수 있습니다. int 형 배열을 전달받아 합을 구하는 메소드를 만들어보겠습니다.

	int sumOfAry(int[] list) {
		int result = 0;
		for(int i = 0; i < list.length; i++)
			result += list[i];
		return result;
	}

 배열은 인스턴스 이므로 메소드 호출 시 전달할 수 있고, 자바에서 지원해주는 다양한 메소드에 인자로 전달해 다양한 기능을 사용할 수 있습니다.


 

+ Recent posts