상속(Inheritance)
주의사항
메서드 오버라이딩(Method Overriding)
public class InheritanceTest {
public static void main(String[] args) {
ParentsClass parentsClass = new ParentsClass();
FirstClass firstClass = new FirstClass();
SecondClass secondClass = new SecondClass();
// 오버라이딩이 되어 각 줄마다 다른 기능을 함
parentsClass.printClass(); // I'm ParentsClass
firstClass.printClass(); // I'm FirstClass
secondClass.printClass(); // I'm SecondClass
// 오버라이딩 되지 않은 부분은 상위 클래스의 값을 가지고 있음
System.out.println(firstClass.commonPoint); // 100
}
}
class ParentsClass {
int commonPoint = 100;
void printClass() {
System.out.println("I'm ParentsClass");
}
}
class FirstClass extends ParentsClass{
void printClass(){
System.out.println("I'm FirstClass");
}
}
class SecondClass extends ParentsClass{
void printClass(){
System.out.println("I'm SecondClass");
}
}
super 키워드
public class Super {
public static void main(String[] args) {
Lower lower = new Lower();
lower.callNum();
// count = 15 // this.count = 15 // super.count = 20
}
}
class Upper {
int count = 20; // super.count
}
class Lower extends Upper {
int count = 15; // this.count
void callNum() {
// Upper의 count 와 Lower의 count 를 구분하기 위해 this. super.을 사용
System.out.println("count = " + count);
System.out.println("this.count = " + this.count);
System.out.println("super.count = " + super.count);
}
}
super()
public class superTest {
public static void main(String[] args) {
Lower lower = new Lower();
lower.callNum();
// count = 100
// this.count = 100
// super.count = 100 / 상위 클래스의 생성자를 사용해서 상위 클래스의 field값도 설정되어 있음
}
}
class Upper {
int count = 10;
Upper(int count){this.count = count;}
}
class Lower extends Upper {
Lower(){super(100);}
void callNum() {
// Upper의 count 와 Lower의 count 를 구분하기 위해 this. super.을 사용
System.out.println("count = " + count);
System.out.println("this.count = " + this.count);
System.out.println("super.count = " + super.count);
}
}
캡슐화(Encapsulation)
패키지
Import 문
다른 패키지 내의 클래스를 사용하기 위해 사용, 패키지 구문과 클래스 구문 사이에 작성
컴파일시에 import문이 처리되므로 프로그램의 성능에는 영향을 주지 않는다.
package practicepack.test2;
import practicepack.test.ExampleImp // import문 작성
public class PackageImp {
public static void main(String[] args) {
ExampleImp x = new ExampleImp(); // 이제 패키지명을 생략 가능
}
}
접근 제어자(Access Modifier)
getter와 setter
public class EncapsulationTest {
public static void main(String[] args) {
GetterSetter getterSetter = new GetterSetter(10);
// getterSetter.data // 에러 발생
System.out.println(getterSetter.getData()); // 10
getterSetter.setData(100);
System.out.println(getterSetter.getData()); // 100
}
}
class GetterSetter{
private int data;
// 생성자
GetterSetter(int data){
this.data = data;
}
// Getter, 네이밍 규칙 : get-
public int getData(){
return this.data;
}
// Setter, 네이밍 규칙 : set-
public void setData(int data){
this.data = data;
}
}
다형성(Polymorphism)
public class Main {
public static void main(String[] args) {
// 상위 클래스 (PeoPle) 가 하위 클래스 (Man)를 참조 가능
People ManOfPerson = new Man();
// 반대는 불가능 ( 일반적으로 하위 클래스(Man)의 기능이 더 많으므로)
// Man PersonOfMan = new Person();
}
}
참조변수의 타입 변환
public class Main {
public static void main(String[] args) {
FirstClass firstClass = new FirstClass();
ParentClass parentClass = new ParentClass();
ParentClass example1_1 = firstClass; // OK
ParentClass example1_2 = (ParentClass) firstClass; // OK
// FirstClass example2_1 = parentClass; // 형변환 연산자 생략 불가 (Incompatable Type)
FirstClass example2_2 = (FirstClass) parentClass; // ClassCastException 발생
}
}
instanceof
public class Main {
public static void main(String[] args) {
ParentClass parentClass = new ParentClass();
FirstClass firstClass = new FirstClass();
// 모든 객체는 Object 를 확장함
System.out.println(parentClass instanceof Object); // true
// 자기 자신으로 형변환은 true
System.out.println(parentClass instanceof ParentClass); // true
// 하위 클래스로 형변환은 불가 (형변환 연산자 사용하면 가능)
System.out.println(parentClass instanceof FirstClass); // false
// 상위 클래스로 형변환 가능
System.out.println(firstClass instanceof ParentClass); // true
// 형제 클래스로 형변환 불가
System.out.println(firstClass instanceof SecondClass); // false
// 상위 클래스가 하위 클래스를 참조한 경우
ParentClass firstParentClass = new FirstClass();
System.out.println(firstParentClass instanceof ParentClass); // true
System.out.println(firstParentClass instanceof FirstClass); // true
System.out.println(firstParentClass instanceof SecondClass); // false
}
}
다형성 활용예제
class UtilizePolymorphism {
// 매개변수를 상위 클래스로 선언시, 하위 클래스로 넣을 수 있음
static void checkOrder(ParentClass parentClass){
System.out.print(parentClass.order + " ");
}
}
public class Main {
public static void main(String[] args) {
FirstClass firstClass = new FirstClass();
SecondClass secondClass = new SecondClass();
ThirdClass thirdClass = new ThirdClass();
// 서로 다른 하위 클래스들을 상위 클래스의 배열로 선언 및 초기화 가능
ParentClass[] classArray = {firstClass, secondClass, thirdClass};
// 서로 다른 클래스의 같은 필드나 매서드를 보여주거나 실행하는데 용이함
for (ParentClass orderclass : classArray){
UtilizePolymorphism.checkOrder(orderclass);
} // 1 2 3
}
}
class ParentClass {
int order;
void CheckMethod() {System.out.println("I'm ParentClass Method");}
}
class FirstClass extends ParentClass {
FirstClass() {this.order = 1;}
void CheckMethod() {System.out.println("I'm FirstClass Method");}
}
class SecondClass extends ParentClass{
SecondClass(){this.order = 2;}
void CheckMethod() {System.out.println("I'm SecondClass Method");}
}
class ThirdClass extends ParentClass{
ThirdClass(){this.order = 3;}
void CheckMethod() {System.out.println("I'm ThirdClass Method");}
}
추상화(Abstraction)
abstract 제어자
public class AbstractionTest {
public static void main(String[] args) {
// AbstractExample abstractExample = new AbstractExample();
}
}
abstract class AbstractExample { // 추상 메서드가 최소 하나 이상 포함돼있는 추상 클래스
abstract void start(); // 메서드 바디가 없는 추상메서드
}
추상 클래스 필요성
abstract class AbstractClass {
int order;
abstract void showOrder(); // 하위 클래스에서는 반드시 showOrder Method를 만들어야 함
}
class FirstClass extends AbstractClass {
FirstClass() {this.order = 1;}
void showOrder() {System.out.println("My order: 1");}
}
class SecondClass extends AbstractClass {
SecondClass() {this.order = 1;}
void showOrder() {System.out.println("My order: 2");}
}
Interface
Interface 구현 ( 하위 객체를 만들어 구현함 )
public class InterfaceTest {
public static void main(String[] args) {
// Camera camera = new Camera(); // Interface는 직접 객체를 만들 수 없다.
Owner owner = new Owner();
SmartPhone smartPhone = new SmartPhone();
DigitalCamera digitalCamera = new DigitalCamera();
owner.takePhoto(smartPhone); // 사진 찍는다 찰칵!
owner.takePhoto(digitalCamera); // 사진 찍는다 고급지게 찰칵!
owner.callSomeone(smartPhone, "이충안"); // 이충안에게 전화를 건다.
}
}
interface Camera {public abstract void takePhoto();}
interface Phone {
public static final String mic = "normal mic";
String speaker = "normal speaker"; // public static final 생략 (일부 생략도 가능)
void callSomeone(String person);
}
class SmartPhone implements Camera, Phone {
// speaker = "upgrade"; // 수정하려 하면 에러 발생
public void takePhoto(){
System.out.println("사진 찍는다 찰칵!");
}
public void callSomeone(String person){
System.out.println(person + "에게 전화를 건다.");
}
}
class DigitalCamera implements Camera{
public void takePhoto() {
System.out.println("사진 찍는다 고급지게 찰칵!");
}
}
class Owner {
static void takePhoto(Camera camera) { // Inerface의 이름으로 매개변수를 선언해 구현한 모든 클래스의 객체를 넣을 수 있다.
camera.takePhoto(); // Interface를 구현한 모든 객체에 같은 이름의 메서드로 사용할 수 있다.
}
static void callSomeone(Phone phone, String person){
phone.callSomeone(person);
}
}
final 키워드