소개
이 랩에서는 접근 제어자 (access modifiers) 와 상속 (inheritance) 에 대해 배우게 됩니다. 다양한 제어자를 통해 접근 수준이 달라집니다. Java 에서의 상속은 생물학적 상속과 유사하여 자식 클래스가 부모 클래스의 특징을 유지하면서도 어떤 면에서는 다르게 동작할 수 있습니다.
이 랩에서는 접근 제어자 (access modifiers) 와 상속 (inheritance) 에 대해 배우게 됩니다. 다양한 제어자를 통해 접근 수준이 달라집니다. Java 에서의 상속은 생물학적 상속과 유사하여 자식 클래스가 부모 클래스의 특징을 유지하면서도 어떤 면에서는 다르게 동작할 수 있습니다.
지금까지 우리는 이미 몇몇 코드를 작성했습니다. 이전 랩에서는 클래스를 작성했습니다. public 및 private와 같은 몇 가지 제어자가 있습니다. 그렇다면 이 단어들은 무엇을 의미할까요?
Java 는 클래스, 변수, 메서드 및 생성자에 대한 접근 수준을 설정하기 위해 여러 접근 제어자를 제공합니다. 네 가지 접근 수준은 다음과 같습니다.

Java 는 동작을 미세 조정하기 위한 다양한 다른 방법을 달성하기 위해 여러 비 접근 제어자를 제공합니다.
static 변수의 복사본이 하나만 존재합니다.final 변수는 한 번만 명시적으로 초기화할 수 있습니다. final 메서드는 하위 클래스에서 재정의할 수 없습니다. 클래스는 하위 클래스를 방지하기 위해 final로 선언됩니다.abstract 클래스는 인스턴스화될 수 없습니다. abstract 메서드는 구현 없이 선언된 메서드입니다.synchronized 및 volatile 제어자는 스레드와 관련하여 사용됩니다.예시:
/home/labex/project/modifierTest.java 파일에 다음 코드를 작성하십시오.
public class modifierTest {
// static variables are initialized when class is loaded.
public static int i = 10;
public static final int NUM = 5;
// non-static variables are initialized when object is created.
public int j = 1;
/*
* static code block here, this will execute when the class is loaded
* creating new object will not execute the block again, run only once.
*/
static{
System.out.println("this is a class static block.");
}
public static void main(String[] args)
{
System.out.println("this is in main method");
// you can access i and change it
modifierTest.i = 20; //the same with obj.i = 20
System.out.println("Class variable i = " + modifierTest.i);
// you can access NUM, but can't change it
// HelloWorld.NUM = 10; this will cause an error, NUM is final, it's immutable
System.out.println("Class variable NUM = " + modifierTest.NUM);
// create new object
modifierTest obj = new modifierTest();
// we can use both class and object to access static methods and static properties
obj.staticMethod(); // the same with modifierTest.staticMethod()
// you can't access j like this: modifierTest.j
System.out.println("Object variable j = " + obj.j);
}
// the constructor, only new object being created will call this.
public modifierTest(){
System.out.println("this is in object's constructor.");
}
public static void staticMethod(){
System.out.println("this is a static method");
}
}
출력:
다음 명령을 사용하여 modifierTest.java 파일을 실행하십시오.
javac /home/labex/project/modifierTest.java
java modifierTest
출력을 확인하십시오.
this is a class static block.
this is in main method
Class variable i = 20
Class variable NUM = 5
this is in object's constructor.
this is a static method
Object variable j = 1
많은 경우, 우리는 클래스를 작성했습니다. 그리고 이전 클래스 코드를 조금만 수정하기 위해 새로운 클래스를 작성해야 하며, 논리적으로 관련이 있습니다. 여기서 **상속 (inheritance)**을 사용할 수 있습니다. 상속을 구현하기 위해 extends 키워드를 사용합니다. 하위 클래스는 상속을 통해 상위 클래스의 모든 접근 가능한 속성과 메서드를 얻으며, 하위 클래스도 자체적인 특별한 속성과 메서드를 가질 수 있습니다. 하위 클래스에서는 상위 클래스에서 public 또는 protected로 선언된 것들에 접근할 수 있지만, private으로 선언된 것에는 직접 접근할 수 없습니다. 예를 들어, 상속 구조는 그림과 같습니다. 다단계 상속 (수평) 또는 계층적 상속 (수직) 을 구현할 수 있습니다.

예시:
/home/labex/project/inheritanceTest.java 파일에 다음 코드를 작성하십시오.
class Animal{
// what kind of animal i am.
private String species;
private int age = 8;
public Animal(){
System.out.println("Animal's constructor");
}
public void grow(){
// In this class, we can access the private properties directly.
System.out.println("I'm "+ this.age + " years old, " +"I grow up.");
}
}
class Dog extends Animal{
private String color;
// In this class, we can't access superclass private attributes, but grow() is ok.
public Dog(){
System.out.println("Dog's constructor");
}
public void run(){
this.grow();
System.out.println("I'm dog, I can run.");
}
}
class Bird extends Animal{
private double weight;
public Bird(){
// if explicitly invoke superclass constructor, it must be at the first line here.
// super();
System.out.println("Bird's constructor");
}
public void fly(){
this.grow();
System.out.println("I'm bird, I can fly.");
}
}
public class inheritanceTest{
public static void main(String[] args){
Dog dog = new Dog();
dog.run();
Bird bird = new Bird();
bird.fly();
}
}
출력:
다음 명령을 사용하여 inheritanceTest.java 파일을 실행하십시오.
javac /home/labex/project/inheritanceTest.java
java inheritanceTest
출력을 확인하십시오.
Animal's constructor
Dog's constructor
I'm 8 years old, I grow up.
I'm dog, I can run.
Animal's constructor
Bird's constructor
I'm 8 years old, I grow up.
I'm bird, I can fly.
이 출력을 보면 혼란스러울 수 있습니다. 걱정하지 마세요. 그 이유를 설명해 드리겠습니다. new를 사용하여 하위 클래스의 객체를 생성할 때, 기본적으로 먼저 상속 트리 구조에서 "위에서 아래로" 상위 클래스의 기본 생성자를 호출하고 마지막으로 자체 생성자를 실행합니다. super 키워드를 사용하여 상위 클래스 생성자를 명시적으로 호출할 수 있지만, 생성자 내에서 첫 번째 문장이어야 합니다. super 키워드는 계층 구조에서 호출하는 클래스 바로 위에 있는 상위 클래스를 참조합니다.
접근 제어자를 사용하면 안전한 코드를 작성하고, 세부 사항을 숨기고, 접근 제어를 달성할 수 있습니다. 다른 사용자는 메서드의 세부 구현 방식을 알 필요가 없습니다. 우리는 다른 호출자에게 인터페이스를 제공합니다. 접근 제어자의 경우, Java 소스 코드 라이브러리를 읽고 차이점을 이해할 수 있습니다. 상속은 클래스 간의 관계이며, 계층 구조를 염두에 두십시오.