IS-A 관계(상속관계)에 있을 때, 자식 객체는 부모 클래스의 자료형인 것처럼 사용할 수 있음.
예를 들어, Dog는 Animal이기 때문에 IS-A 관계를 충족함.
메소드 오버라이딩 (Method overriding)
부모 클래스의 메소드를 자식 클래스가 재정의하는 행위 (메소드 덮어쓰기)
메소드 오버로딩 (method overloading)
입력 항목이 다른 경우 동일한 이름의 메소드를 만들 수 있음.
💡
상속은 '복사'하여 이루어짐.
인터페이스
인터페이스는 추상메서드의 모음임. 핵심은 의존적인 클래스에서 독립적인 클래스로 만드는 것.
왜 인터페이스를 사용할까?
보안 유지 : 객체의 중요한 점만 보여주고 세부사항은 숨기는 용도.
다중 상속 : 자바는 다중 상속을 지원하지 않음. 하지만 인터페이스는 다중 인터페이스를 implement할 수 있음.
예시
캐릭터 Stat 상속 프로그램
캐릭터가 가지고 있는 능력치를 상속, 배정하는 프로그램.
자산 관리 프로그램
가지고 있는 자산 (현금, 주식 등)을 입력하면 총 자산과 비중을 계산하는 프로그램.
추상 메소드 (abstract method) :
❶ 정의 - 추상적인 개념(새, 포유류)을 구현한 클래스.
❷ 목적 - 상속받는 자식 클래스가 반드시 추상 메소드를 구현하도록 하기 위해 사용.
❸ 방법 - 선언부만 존재, 구현부는 작성하지 않음. 구현부는 자식 클래스에서 오버라이딩하여 사용.
추상 클래스(abstract class) - 하나 이상의 추상 메소드를 포함하는 클래스.
string format : 주어진 매개 변수(locale, format, arguments)에 의해 formatted된 Sting. 포맷 특정자로 %c, %s, %d 등이 있음.
아쉬운 점 : 환율, 주가 등 시시각각 변하는 값을 일일히 입력해주어야 한다는 점에서 한계가 있음.
마치며
자바의 클래스를 작성하는 방법을 파악하기 위해서 가장 검색과 짜증이 뒤섞인 과정이었다. 특히, 객체지향 이론과 실제로 구현하는 코드 사이의 괴리감이 컸다. 그래서 개념을 아무리 읽어도 코드 한 줄 치기가 어려웠다. 그래도 이 과정을 지나고 나니 객체지향이란 것이 이해되는 것 같다.
이 과정을 통해 개념의 중요성을 알았다. 이론과 실제로 구현하는 것의 괴리감이 큰 만큼 개념을 더 파고 들어야 하는 것 같다. 정말 아이러니하지만 사실이라 앞으로 배워야 할 게 산더미라고 느끼는 계기가 되었다.
public class Animal {
String name;
public void setName(String name) {
this.name = name;
}
}
public class Dog extends Animal {
public void sleep() {
System.out.println(name + " zzz");
}
public static void main(String[] args) {
Dog dog = new Dog();
dog.setName("puppy");
dog.sleep();
}
}
Animal dog = new Dog();
Dog dog = new Animal(); // 컴파일 오류: 부모 클래스로 만든 객체는 자식 클래스의 자료형으로 사용할 수 없다.
public class HouseDog extends Dog {
public void sleep() {
System.out.println(name + " zzz in house");
}
public static void main(String[] args) {
HouseDog houseDog = new HouseDog();
houseDog.setName("yellow");
houseDog.sleep();
}
}
//yellow zzz in house
public class HouseDog extends Dog {
public void sleep() {
System.out.println(name + " zzz in house");
} //매개변수를 받지 않는 sleep 메소드
public void sleep(int hour) {
System.out.println(name + " zzz in house " + hour + "hours");
} //매개변수를 받는 sleep 메소드
public static void main(String[] args) {
HouseDog houseDog = new HouseDog();
houseDog.setName("yellow");
houseDog.sleep();
houseDog.sleep(3);
}
}
//yellow zzz in house
//yellow zzz in house 3hours
//왜 되지?
interface Animal {
public void animalSound();
public void sleep();
}
class Pig implements Animal {
public void animalSound() {
System.out.println("pig says Wee Wee");
}
public void sleep() {
System.out.println("Zzz");
}
public static void main(String[] args) {
Pig pig = new Pig();
pig.animalSound();
pig.sleep();
}
}
interface Animal {
public void animalSound();
public void sleep();
}
class Pig implements Animal {
public void animalSound() {
System.out.println("pig says Wee Wee");
}
public void sleep() {
System.out.println("Zzz");
}
}
class Main {
public static void main(String[] args) {
Pig pig = new Pig();
pig.animalSound();
pig.sleep();
}
}
//pig says Wee Wee
//Zzz
public class Main {
public static void main(String[] args) {
Character warrior = new Warrior();
Character magician = new Magician();
warrior.printStat();
magician.printStat();
}
}
public abstract class Character {
protected int HP = 10;
protected int MP = 10;
public void printStat() {
System.out.println(String.format("HP = %d, MP = %d", HP, MP));
};
}
public class Warrior extends Character {
public Warrior() {
HP += 300;
MP += 10;
};
}
public class Main {
public static void main(String[] args) {
Asset[] asset = new Asset[] { new Tesla(), new Samsung(), new KRW(), new USD() };
int totalAsset = 0;
int stockSum = 0;
int cashSum = 0;
for (int i = 0; i < asset.length; i++) {
totalAsset += asset[i].getTotalValue();
if (asset[i] instanceof Stock) {
stockSum += asset[i].getTotalValue();
} else if (asset[i] instanceof Cash) {
cashSum += asset[i].getTotalValue();
}
asset[i].printInfo();
}
System.out.println("stockSum = " + stockSum);
System.out.println("cashSum = " + cashSum);
System.out.println("totalAsset = " + totalAsset);
System.out.println("stockWeight = " + (stockSum / (float) totalAsset * 100) + "%");
System.out.println("cashkWeight = " + (cashSum / (float) totalAsset) * 100 + "%");
}
}
public abstract class Asset {
public abstract int getTotalValue();
public abstract int getCount();
public abstract int getPrice();
public abstract void printInfo();
}
public class USD extends Cash {
private int price = 1100;
private int count = 15;
@Override
public int getCount() {
return count;
}
@Override
public int getPrice() {
return price;
}
@Override
public int getTotalValue() {
return price * count;
}
@Override
public void printInfo() {
System.out
.println(String.format("name = USD, price = %d, count = %d, total = %d", price, count, price * count));
}
}