C++은 객체지향 언어지만 C언어의 특징을 모두 갖고 있어 전역변수, 일반함수도 존재하고 이로인해 순수한 객체지향 언어라고 볼 수 없다.

JAVA는 C++과 달리 전역변수, 일반함수를 사용하지 않으며 항상 클래스를 작성하여 프로그래밍 한다.C언어의 특징을 버릴 수 있어 순수한 객체지향 언어가 되었다.

JAVA의 클래스는 멤버 변수와 method로 구성된 사용자 정의 타입이라고 볼 수 있다.
클래스는 멤버 변수와 메서드로 구성된다. 일반적인 구조는 다음과 같다.
public과 같은 지시자, 키워드인 class, 클래스의 이름 차례로 오고 내부에 클래스의 멤버인 변수(속성)와 메서드들이 작성된다.
public class 클래스이름{ 클래스의 멤버 변수 리스트; 클래스의 멤버 메서드01 { ... } 클래스의 멤버 메서드02 { ... } }
JAVA언어 프로그램의 클래스 앞에 public이란 지시자를 반드시 붙일 필요는 없지만 클래스 앞에 public 지시자를 이용했다면 Java 언어 소스 프로그램의 이름은 반드시 public 클래스의 이름과 같이 만들어져야 한다. 하나의 파일에 여러 가지 클래스를 정의하는 경우 public 지시자를 가지는 클래스는 하나 이하여야 한다.
하나의 Java 언어 프로그램 내에 여러 개의 클래스를 정의한 경우 컴파일 햇을 때 각각 클래스의 이름으로 바이트 코드가 만들어지는 것을 알 수 있다. 결국 각 클래스들을 별도의 파일에 작성한 것고 차이가 없다.
클래스에 의해 정의된 변수를 객체라고 한다.
타입은 변수의 유형을 결젇하는 것으로 프리미티브(primitive) 타입과 레퍼런스(reference)타입이 있다.
생성자(constructor)는 클래스의 이름과 같고, 리턴 타입을 가지지 않는 메서드로 new 키워드로 클래스의 인스턴스(instance) 또는 객체(object)를 만들 때 자동으로 초기화하는데 사용된다.
생성자의 이름은 같으나, 파라미터가 다르면 서로 다른 생성자로 인정된다.
this키워드는 객체 자신에 대한 참조로 생성자 중복 정의시 사용된다.
this는 생성자의 첫 줄에 작성되어야 한다.
public class Test {
int x;
public Test() {
this(5);
}
public Test(int x) {
this.x = x;
}
public int f1() {
return f2(x) +1;
}
public int f2(int x) {
return x * 2;
}
public static void main(String[] args) {
Test test = new Test();
System.out.println(test.f1());
Test test2 = new Test(3);
System.out.println(test2.f1());
}
}
11
7
static 멤버는 클래스 변수나 메서드 앞에 static이 있는 멤버를 말한다.
static 멤버는 클래스에서 생성된 객체에 의존하지 않고 독립적으로 사용 가능하다. 즉, 클래스에서 생성된 객체에 대한 참조 없이 바로 사용될 수 있다.
static 변수는 메모리의 static 영역 또는 데이터 세그먼트 영역에 위치하여 클래스의 범위에 따라 참조가 가능하고, 따라서 클래스의 인스턴스 사이에서는 모두 같은 갑을 가지는 변수이다.
static 메서드는 메모리의 static 영역 또는 데이터 세그먼트 영역에 위치하여 클래스의 범위에 다라 참조가 가능한 메서드이다. 따라서 클래스의 인스턴스를 만들지 않아도 접근이 가능한 메서트를 필요로 할 때 정의한다. static 메서드에서는 static 변수만을 사용할 수 있으나, 일반 메서드에서는 static 변수와 일반 변수를 모두 사용할 수 있다.
한 클래스에서 만들어진 모든 객체는 static 변수를 공유한다. static 블록을 작성하여 static 변수를 선언 할 수 있다. static 블록은 클래스가 처음 호출될 떄 한 번만 수행된다.
public class Test {
static int y = 3;
static int z;
static {
System.out.println("static 초기화 블록");
z = y * 3;
}
static void execute(int x)
{
System.out.println("x = " + x);
System.out.println("y = " + y);
System.out.println("z = " + z);
}
public static void main(String[] args) {
Test.execute(15);
Test.execute(10);
}
}
static 초기화 블록
x = 15
y = 3
z = 9
x = 10
y = 3
z = 9
public class StaticTest {
static int version = 10;
int ordinaryVariable;
static void method1() {
//static 메서드에서 일반 변수 호출 에러
//System.out.println("method1 : " + ordinaryVariable++);
//ordinaryVariable++;
}
static void method2() {
//static 메서드에서 static 변수 호출 가능
System.out.println("method2 : " + version++);
}
void method3() {
//일반 메서드에서 일반 변수, static 변수 호출 가능
System.out.println("method3 : " + ordinaryVariable++);
System.out.println("method3 : " + version++);
}
}
public class Test {
public static void main(String[] args) {
//static 변수는 클래스에 의해 접근 가능
StaticTest.version++;
StaticTest st = new StaticTest();
//인스턴스는 static 변수, 일반 변수 접근 가능
st.version = 10;
//일반 변수는 클래스에 의해 접근 불가
//StaticTest.ordinaryVariable = 10;
//static 메서드 접근 가능
StaticTest.method1();
StaticTest.method2();
//일반 메서드 접근 불가
//StaticTest.method3();
//인스턴스는 static 메서드, 일반 메서드 접근 가능
st.method2();
st.method3();
}
}
method2 : 10
method2 : 11
method3 : 0
method3 : 12
main() 메서드에 static 키워드가 있는 것은 main() 메서드가 클래스의 인스턴스 없이도 프로그램이 실행될 수 있도록 하기 위함이다.
main() 메서드는 Java 인터프리터가 처음 수행될 진입점을 나타낸다.
main() 메서드에는 실행 시 명령라인의 인수 값을 받을 수 있도록 String 타입의 배열로 파라미터가 전달된다.
public static void main(String args[])
public : Java 언어 인터프리터를 포함하여 어디에서든 수행 가능한 메서드를 나타낸다.
static : 클래스의 인스턴스를 만들지 않고서도 프로그램이 시작할 수 있도록 하기 위함이다. static으로 선언된 메서드는 재정의 될 수 없다.
(main() 메서드가 클래스의 참조를 받는 것이지 객체의 참조를 받는 것이 아님을 알려준다. static 메서드는 메모리 영역 주에서 데이터 세그먼트 또는 staitc 영역에 자리 잡게 되고 프로그램이 수행 될 때 제일 먼저 호출 되어 런타임 시에 실체화되어 사용된다.)
void : main() 메서드가 아무것도 리턴하지 않음을 나타낸다. Java 언어의 타입 검사는 매우 강력하기 때문에 리턴 타입을 정확히 명시할 필요가 있다.
args[] : 스트링의 배열로 명령어 라인에서 입력되는 인수를 받게 된다.
(String 타입은 바꾸면 안되지만 args란 변수명은 바꿔도 상관 없음)
final 키워드는 변수 앞에 사용되어 상수를 만들 때 사용하며 선언 될 때 초기화가 이루어져야 한다.
변수를 상수처럼 사용한다는 점은 비슷하지만 차이가 있다.
final 메소드의 재정의(overriding)와 클래스의 상속(inheritance)이 허용되지 않지만,
const 는 재정의와 상속에는 영향을 주지 않고 데이터 값의 변경만 허용하지 않도록 한다.
public class Test {
final int NUM = 5;
final int MAX = 99;
public static void main(String[] args) {
Test test = new Test();
// test.NUM = 7; //error : The final field Test.NUM cannot be assigned
System.out.println(test.NUM);
//test.MAX = 999; //error : The final field Test.MAX cannot be assigned
System.out.println(test.MAX);
}
}
5
99
class Base{
final void execute() { //final이 있는 method는 재정의 불가
System.out.println("This is a final mehtod.");
}
}
public class Test extends Base {
final int NUM = 5;
final int MAX = 99;
void execute() { //ERROR!!!!! 재정의 할 경우 에러 발생
System.out.println("Illegal!");
}
public static void main(String[] args) {
Test test = new Test();
test.execute();
}
}
final class Base{ //final 클래스는 상속 불가
void execute() {
System.out.println("This is a mehtod.");
}
}
public class Test extends Base { //final 클래스를 상속할 때 에러 발생
final int NUM = 5;
final int MAX = 99;
public static void main(String[] args) {
Test test = new Test();
}
}
객체도 배열로 사용할 수 있다.
class TestObject{
int value;
public TestObject(int val) {
value = val;
}
public void setValue(int val) {
value = val;
}
public int getValue() {
return value;
}
}
public class Test {
public static void main(String[] args) {
TestObject array[] = new TestObject[5];
for(int i=0; i<5; i++)
{
array[i] = new TestObject(i);
}
for(int i=0; i<5; i++)
{
System.out.println("array["+i+"]=" + array[i].getValue());
}
}
}
array[0]=0
array[1]=1
array[2]=2
array[3]=3
array[4]=4