오늘의 코드
package edu.java.access10;
// 싱글톤 디자인 패턴(singleton design pattern)
// - 클래스의 인스턴스를 오직 하나만 생성할 수 있도록 작성하는 설계 기법
// 1. 클래스 자신 타입의 private static 변수를 선언
// 2. 생성자는 private으로 선언
// 3. public static 메소드를 제공해서 인스턴스를 생성할 수 있도록 설계
// 처음 생성한 인스턴스는 변경이 불가능(주소값이 같음)
public class PublicToilet {
private String location;
// 1. 클래스 자신 타입의 private static 변수를 선언
private static PublicToilet instance = null;
// 2. 생성자는 private으로 선언
private PublicToilet() {}
// 3. public static 메소드를 제공해서 인스턴스를 생성할 수 있도록 설계
public static PublicToilet getInstance() {
if(instance == null) {
instance = new PublicToilet(); // 생성자는 항상 필요
}
return instance;
}
public String getLocation() {
return location;
}
public void setLocation(String location) {
this.location = location;
}
}
package edu.java.access10;
public class AccessMain10 {
public static void main(String[] args) {
PublicToilet toilet1 = PublicToilet.getInstance();
toilet1.setLocation("캠핑장");
System.out.println(toilet1);
System.out.println(toilet1.getLocation());
System.out.println("-------------------");
PublicToilet toilet2 = PublicToilet.getInstance();
System.out.println(toilet2);
System.out.println(toilet2.getLocation());
System.out.println("-------------------");
toilet2.setLocation("공연장");
System.out.println(toilet1.getLocation());
System.out.println(toilet2.getLocation());
} // end main()
} // end AccessMain10
Access 끝 다음챕터로 넘어감
여기서 부턴 묶음 으로 작성
package edu.java.inherit01;
public class BasicTv {
// 멤버 변수(필드, 프로퍼티)
boolean powerOn;
public int channel;
public int volume;
// 생성자
public BasicTv() {}
// 메소드
public void turnOnOff() {
System.out.println("turnOnOff() 메소드");
}
}
package edu.java.inherit01;
public class SmartTv extends BasicTv{
// 멤버 변수
private String ip;
// 생성자
public SmartTv() {}
public String getIp() {
return ip;
}
public void setIp(String ip) {
this.ip = ip;
}
} // end SmartTv
package edu.java.inherit01;
// BasicTv : 상위 클래스(super class), 부모 클래스(parent class), 기본 클래스(base class)
// SmartTv : 하위 클래스(sub class), 자식 클래스(child class), 유도 클래스(derived class)
public class InheritMain01 {
public static void main(String[] args) {
// SmartTv 클래스의 인스턴스 생성
SmartTv tv1 = new SmartTv();
tv1.powerOn = true;
tv1.turnOnOff(); // 자식 클래스는 부모 클래스의 메소드 사용 가능
tv1.setIp("172.16.7.30");
BasicTv tv2 = new BasicTv();
// tv2.setIp(""); // 부모 클래스가 자식 클래스의 메소드를 사용할 수 없음.
} // end main()
} // end InheritMain01
1끝
package edu.java.inherit02;
// * 생성자
// - 자식 클래스의 생성자가 호출되면, 부모 클래스의 생성자가 먼저 호출되어야 함
// - 부모 클래스의 생성자를 명시적으로 호출할 때는 super();
// - 부모 클래스의 생성자를 명시적으로 호출하지 않으면,
// 부모 클래스의 "기본 생성자"가 자동으로 호출됨
// - 부모 클래스의 매개변수가 있는 생성자는 자동으로 호출되지 않기 때문에,
// 필요한 경우는 반드시 명시적으로 호출해야 함
// - 예시) super(name)
// - 자식 클래스의 생성자에서 부모 클래스의 생성자를 호출할 때는
// 다른 어떤 코드보다 먼저 부모 클래스를 호출해야 함
public class BusinessPerson extends Person {
// 멤버 변수
private String company;
public BusinessPerson() {
// super(); // 부모 클래스의 기본 생성자 호출 => 생략 가능
// super() == Person()
System.out.println("BusinessPerson() 생성자");
}
public BusinessPerson(String name) {
super(name);
// 만약 부모 클래스의 매개변수 생성자를
// 명시적으로 호출할 경우 -> 생략 불가
System.out.println("BusinessPerson(name) 생성자");
}
} // end BusinessPerson
package edu.java.inherit02;
public class Person {
// 멤버 변수
private String name;
// 기본 생성자
public Person() {
System.out.println("Person 생성자");
}
public Person(String name) {
this.name = name;
System.out.println("Person(name) 생성자");
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
} // end person
package edu.java.inherit02;
public class InheritMain02 {
public static void main(String[] args) {
// Person 클래스의 인스턴스 생섯
Person p1 = new Person();
// 인스턴스를 생성하면, 생성자가 호출된다.
Person p2 = new Person("솔데스크");
// 인자값을 전달하면, 매개변수가 있는 생성자가 호출된다.
System.out.println("======");
BusinessPerson p3 = new BusinessPerson();
System.out.println("======");
BusinessPerson p4 = new BusinessPerson("구글");
} // end main()
} // end InheritMain02
2끝
package edu.java.inherit03;
public class Phone {
// 멤버 변수
private String number;
// 클래스의 기본 생성자를 생략하면 컴파일러가 기본 생성자를 만들어 줌.
// 생성자를 하나라도 정의한 경우,
// 자바 컴파일러는 기본 생성자를 자동으로 만들어주지 않음.
public Phone(String number) {
this.number = number;
System.out.println("Phone(number) 생성자 호출");
}
public String getNumber() {
return number;
}
public void setNumber(String number) {
this.number = number;
}
}
package edu.java.inherit03;
public class SmartPhone extends Phone { // 부모가 기본 생성자가 없을 경우
// 생성자
// - 자식 클래스의 생성자 호출되면,
// 부모 클래스의 생성자가 먼저 실행된 후에, 자식 클래스의 코드들이 실행됨
// 1) 부모 클래스의 생성자를 명시적으로 호출하지 않을 때는 super()가 자동으로 호출
// 2) 부모 클래스의 생성자를 명시적으로 super(); 또는 super(매개변수);로 호출 가능
// - 만약에 부모 클래스가 기본 생성자를 가지고 있지 않은 경우에는
// super()가 자동으로 호출될 수 없기 때문에,
// 자식 클래스의 생성자에서 super(매개변수)를 호출하는 코드가 반드시 있어야 함
public SmartPhone(String number) {
super(number);
System.out.println("SmartPhone(number) 생성자 호출");
}
}
package edu.java.inherit03;
public class InheritMain03 {
public static void main(String[] args) {
Phone phone1 = new Phone("010");
SmartPhone phone = new SmartPhone("010-1111-1111");
} // end main()
} // end InheritMain03
3끝
아레부턴 상속에 어려운 부분임 중요함
package edu.java.inherit04;
public class Animal {
// 멤버 변수
private String name;
// 생성자
public Animal() {}
public Animal(String name) {
this.name = name;
}
// 메소드
public void speak() {
System.out.println("동물이 말합니다.");
}
}
package edu.java.inherit04;
public class Dog extends Animal {
// 멤버 변수
private String type;
// 생성자 overloading
public Dog() {
}
public Dog(String name, String type) {
super(name);
this.type = type;
}
// 메소드 재정의(override)
// - 부모 클래스가 가지고 있는 메소드를 자식 클래스에서 재정의(다시 정의)
// - 메소드의 리턴 타입, 이름, 매개변수 모두 부모 클래스의 메소드와 일치해야 함
@Override
public void speak() {
System.out.println("멍멍!");
} // end speak()
}
package edu.java.inherit04;
public class Cat extends Animal {
@Override
public void speak() {
System.out.println("야옹");
}
}
package edu.java.inherit04;
public class InheritMain04 {
public static void main(String[] args) {
// 이걸 묶어서 처리한다면 상속이 필요하다.
Animal animal = new Animal("동물");
animal.speak();
System.out.println();
Dog dog = new Dog("토토", "시고르자브종");
dog.speak();
System.out.println();
Cat cat = new Cat();
cat.speak();
// 상속을 사용하는 가장 강력한 기능 중 하나
// 그저 "말해"라고 하면 전부다 말을 한다
// 단. 나오는 내용은 다르게 나온다.
Animal[] a = new Animal[3];
a[0] = animal;
a[1] = dog;
a[2] = cat;
for(int i =0; i < a.length; i++) {
a[i].speak();
}
} // end main()
} // end InheritMain04
4끝
package edu.java.inherit05;
public class Person {
private String name;
public Person() {
}
public Person(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
// 자바의 모든 클래스는 java.lang.Object 클래스를 상속받아서 만들어짐!
// 자바의 모든 클래스는 Object 클래스의 public 메소드들을 사용 가능
// Object 클래스의 toString 메소드 :
// - 패키지이름.클래스이름@참조값(주소값) 리턴
@Override // annotation(어노테이션) : 특정 변수나 함수의 상태를 표시
public String toString() {
return name + "입니다.";
}
}
package edu.java.inherit05;
public class Point {
private double x;
private double y;
public Point() {
super();
}
public Point(double x, double y) {
super();
this.x = x;
this.y = y;
}
public double getX() {
return x;
}
public void setX(double x) {
this.x = x;
}
public double getY() {
return y;
}
public void setY(double y) {
this.y = y;
}
@Override
public String toString() {
return "(" + x + ", " + y + ")";
}
}
package edu.java.inherit05;
public class InheritMain05 {
public static void main(String[] args) {
Person p1 = new Person("둘리");
System.out.println(p1);
// toString() : 객체가 가지고 있는 정보를 문자열로 출력
// Object 클래스의 toString은 모든 클래스에서 사용 가능
// p1과 p1.toString()은 같은 결과를 출력
String str = new String("문자열");
System.out.println(str);
// 즉석 퀴즈)
// 1. Point 클래스 생성
// - 멤버 변수(double x, double y)
// - 기본 생성자
// - 매개변수 생성자
// - toString()을 오버라이드하여 (x,y)형식의 문자열을 리턴하는 메소드 생성
// 2. InheritMain의 main() 메소드에서 Point 인스턴스 생성 및 변수 저장
// 아래와 같이 출력
// - 예시(1.0, 2.0)
// - toString() 메소드를 활용
Point po = new Point(1.0, 2.0);
System.out.println(po.toString());
} // end main()
} // InherMain05
package edu.java.inherit06;
public class Car {
// 멤버 변수
private int fuel;
public Car() {
}
public Car(int fuel) {
super();
this.fuel = fuel;
}
public int getFuel() {
return fuel;
}
public void setFuel(int fuel) {
this.fuel = fuel;
}
@Override
public String toString() {
return "Car [fuel=" + fuel + "]";
}
public void display() {
System.out.println("자동차 연료 : " + fuel);
}
}
package edu.java.inherit06;
public class HybridCar extends Car {
// 멤버 변수
private int battery;
public HybridCar() { }
public HybridCar(int battery) {
super();
this.battery = battery;
}
public int getBattery() {
return battery;
}
public void setBattery(int battery) {
this.battery = battery;
}
@Override
public String toString() {
return "HybridCar [battery=" + battery + "]";
}
@Override
public void display() {
System.out.println("하이브리드 자동차 연로 : " + getFuel());
System.out.println("하이브리드 자동차 배터리 : " + battery);
}
}
package edu.java.inherit06;
// 다형성(Polymorphism)
// - 객체(인스턴스)를 여러 가지 타입으로 호출할 수 있는 것
// - 생성된 인스턴스를 가리키는(참도하는) 참조 변수를 선언할 때
// 생성된 인스턴스의 클래스 타입으로 변수를 선언할 수도 있고
// 그 부모 타입으로 변수를 선언할 수 있는 것
// - 다형성의 장점
// 1. 배열을 사용할 때 부모 타입으로만 선언해도
// 그 배열에는 부모/자식 타입 모두 저장 가능.
// 2. 메소드를 정의할 때 메소드의 매개변수나 리턴타입으로 부모 클래스타입만
// 사용해도 부모/자식 타입 모두 재개변수나 리턴값으로 사용할 수 있음.
public class InheritMain06 {
public static void main(String[] args) {
// Car 클래스의 인스턴스 생성
Car car = new Car();
// HybridCar 클래스의 인스턴스 생성
HybridCar car2 = new HybridCar();
Car car3 = new HybridCar(); // 다형성(polymorphism)
// HybridCar car4 = new Car(); // 자식 클래스에 부모 클래스 객체 저장 불가
Car[] cars = new Car[3];
cars[0] = car; // Car 객체
cars[1] = car2; // HybridCar 객체
cars[2] = car3; // HybridCar 객체
for(Car x : cars) {
x.display();
System.out.println("----------------");
}
} // end main()
} // end InheritMain06
8끝
package edu.java.inherit07;
class ParentClass {
private int x;
public ParentClass(int x) {
this.x = x;
System.out.println("ParentClass(x)생성자");
}
public int getX() {
return x;
}
} // end ParentClass
class ChildClass extends ParentClass {
private int y;
public ChildClass(int x, int y) {
super(x);
this.y = y;
System.out.println("ChildClass(x, y) 생성자");
}
public int getY() {
return y;
}
}
public class InheritMain07 {
public static void main(String[] args) {
ParentClass class1 = new ChildClass(100, 200); // 다형성
ChildClass class2 = new ChildClass(300, 400);
ParentClass class3 = new ParentClass(100);
class2.getX();
class2.getY();
class1.getX();
// class1.getY();
// class1은 ParenClass 타입으로 선언했기 때문에
// ChildClass에서 정의한 getY() 메소드를 사용할 수 없음
// 다만, 실제 인스턴스는 ChildClass 타입이기 째문에
// 강제 형 변환(casthing)을 하면, ChildClass가 가지고 있는 메소드 사용 가능
System.out.println(((ChildClass) class1).getY());
ChildClass c = (ChildClass) class1;
System.out.println(c.getY());
} // end main()
} // end InheritMain07
7끝
package edu.java.inherit08;
public class Employee {
// 멤버 변수
private String name;
public Employee() { }
public Employee(String name) {
super();
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void print() {
System.out.println("직원");
}
}
package edu.java.inherit08;
public class Manager extends Employee {
private String type;
public Manager() {
}
public Manager(String name, String type) {
super(name);
this.type = type;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
@Override
public void print() {
System.out.println("매니저");
}
}
package edu.java.inherit08;
public class EmployeeUtil {
// instanceof
// - 기본 형태
// 참조변수 instanceof 클래스 이름
// - 명시한 클래스 타입의 인스턴스와 갑으면 true, 아니면 false를 리턴하는 키워드
// - 특정 인스턴스가 실제 어떤 클래스인지 확인할 때 사용
public static void prinyEmployeeInfo(Employee[] emps) {
for(Employee e : emps) {
if (e instanceof Manager) {
System.out.println("이름 : " + e.getName());
System.out.println("직책 : " + ((Manager) e).getType());
} else {
System.out.println("이름 : " + e.getName());
System.out.println("직책 : Not specified");
}
}
}
}
package edu.java.inherit08;
public class InheritMain08 {
public static void main(String[] args) {
Employee[] emps = {
new Employee("둘리"),
new Manager("고길동", "과장")
};
emps[0].print();
emps[1].print();
EmployeeUtil.prinyEmployeeInfo(emps);
} // end main()
} // end InheritMain08
package edu.java.inherit09;
public class Test1 {
private int a;
int b;
protected int c;
public int d;
public void display() {
System.out.println("a = " + a);
System.out.println("b = " + b);
System.out.println("c = " + c);
System.out.println("d = " + d);
}
} // end Test1
class Test2 extends Test1{
@Override
public void display() {
// System.out.println("a = " + a);
System.out.println("b = " + b);
System.out.println("c = " + c);
System.out.println("d = " + d);
}
}
package edu.java.inherit10;
import edu.java.inherit09.Test1;
public class Test3 extends Test1{
public void display() {
// System.out.println("a = " + a);
// System.out.println("b = " + b);
System.out.println("c = " + c);
System.out.println("d = " + d);
}
}
package edu.java.inherit09;
public class InheritMain09 {
public static void main(String[] args) {
}
}
9, 10 끝
package edu.java.inherit11;
// final : 최종적인, 변경할 수 없는
// - final + 메소드 : override 할 수 없는 메소드
// - final + 클래스 : 상속을 허용하지 않는 클래스
class SuperClass {
public void test() {
System.out.println("테스트");
}
public final void testFinal() {
System.out.println("파이널 메소드");
}
} // end SuperClass
class SubClass extends SuperClass {
@Override
public void test() {
}
// testFinal() // final으로 선언된 메소드는 override 불가능
} // end SubClass
public class InheritMain11 {
public static void main(String[] args) {
}
}
11끝
package edu.java.inherit12;
//abstract : 추상적인, 실체가 없는
//abstract 메소드(추상 메소드) :
//- 메소드의 원형(prototype : 리턴타입, 이름, 매개변수)만 선언하고
//메소드의 본체(body : {})를 구현하지 않는 메소드
//- {...}이 없음
//- 선언 타입
// abstract 리턴타입 메소드이름(매개변수1, 매개변수2, ...);
//abstract 클래스(추상 클래스) :
//- 추상 메소드를 하나라도 가지고 있는 클래스
//- 선언 타입
//abstract class 클래스이름{..}
//- 추상 클래스는 인스턴스를 생성할 수 없음(생성자를 호출할 수 없음)
//- 상속받는 클래스에서 메소드를 override하면 인스턴스를 생성할 수 있음
abstract class TestAbstract {
public abstract void hello();
} // end TestAbstract
class TestChild extends TestAbstract {
@Override
public void hello() {
}
}
public class InheritMain12 {
public static void main(String[] args) {
}
}
싱글톤 디자인 패턴(singleton design pattern) : 음료수를 마시겠다고 음료수를 계속 사서 페트병을 계속 생성하고 버려지는 것 보다 물통에 음료수를 담아 마시는 것이 자연(메모리)에 좋기 때문이다.
상속 : 부모님이 자식에게 물려주는 여러가지.
그렇기에 자식은 부모님꺼를 맘껏(허락하는것) 사용가능 (단. 부모는 자식이 가지고 있는 것을 사용 불가(돈 100만원 있는 부모가 100원 있는 자식 건들긴 좀;;)).
다형성 : 자식에 얼굴이 부모얼굴이랑 비슷한 걸 이용하여 부모가 자식행세를 하는 것 다만 자식이 된 것은 아님