1. 싱글톤 패턴
2. 상속
(1) 상속
- 기존 클래스의 기능을 그대로 사용하면서 새로운 기능이 추가된 클래스를 만들고 싶을때 사용함.
- Child 클래스는 Parent클래스를 extends로 상속받는 예제
class Parent {
public void print() {
System.out.println("I am the parent.");
}
}
class Child extends Parent { }
public class Main {
public static void main(String[] args) {
Child child = new Child();
child.print();
}
}
- 부모에 있는 메소드를 자식이 재정의하면 자식 클래스의 인스턴스는 재정의된 메소드가 출력
- 즉, 우리는 그것을 메소드 오버라이딩이라고 한다.
class Animal {
private String name = "";
public Animal(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void speak() {
System.out.println("The animal speaks");
}
}
class Dog extends Animal {
public Dog(String name) {
super(name);
}
@Override
public void speak() {
System.out.println("The dog barks");
}
}
public class Main {
public static void main(String[] args) {
Animal animal = new Animal("Animal");
System.out.println(animal.getName());
animal.speak();
Dog dog = new Dog("Dog");
System.out.println(dog.getName());
dog.speak();
}
}
- super을 이용해서 부모 생성자 접근.
class Person {
private String name = "";
private int age = 0;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
public void introduce() {
System.out.println("name: " + name + ", age: " + age);
}
}
class Student extends Person {
private int grade = 0;
public Student(String name, int age, int grade) {
super(name,age);
this.grade = grade;
}
public int getGrade() {
return grade;
}
public void study() {
System.out.println("I am studying");
}
}
class Teacher extends Person {
private String subject = "";
public Teacher(String name, int age, String subject) {
super(name,age);
this.subject = subject;
}
public String getSubject() {
return subject;
}
public void teach() {
System.out.println("I am teaching");
}
}
public class Main {
public staic void main(String[] args) {
Person person = new Person("John", 30);
person.introduce();
Student student = new Student("John", 20, 3);
student.introduce();
student.study();
Teacher teacher = new Teacher("Smith", 40, "Math");
teacher.introduce();
teacher.teach();
}
}
- p.325) 상속을 이용하여 사각형의 넓이, 부피를 구현하시오.
class Rectangle() {
public double width = 1;
public double depth = 1;
public double area() {
return width * depth;
}
public Rectangle() { }
public Rectangle(double width) {
this(width,width);
}
public Rectangle(double width, double depth) {
super();
this.width = width;
this.depth = depth;
}
}
class RectanglePillar extends Rectangle {
public double height = 0;
public double volume() {
return area() * height;
}
public RectanglePillar() { }
public RectanglePillar(double width, double depth, double height) {
super(width, depth);
this.height = height;
}
}
public class JavaEx01 {
public static void main(String[] args) {
Rectangle r = new Rectangle(5);
System.out.println("사각형의 넓이: " + r.area());
RectanglePillar rp = new RectanglePillar(3,4,5);
System.out.println("사각형의 넓이: " + rp.area());
System.out.println("사각형의 부피: " + rp.volume());
}
}
3. 오버라이드
public class Animal {
public void move() {
System.out.println("동물이 움직입니다.");
}
}
public class Dog extends Animal {
@Override
public void move() {
System.out.println("강아지가 네 발로 걸어다닙니다");
}
}
public class Cat extends Animal {
@Override
public void move() {
System.out.println("고양이가 네 발로 걸어다닙니다");
}
}
public class Main {
public static void main(String[] args) {
Animal animal1 = new Animal();
Dog dog2 = new Dog();
Cat cat3 = new Cat();
animal1.move();
dog2.move();
cat3.move();
}
}
++ 면접에서 잘 물어봄 ++
오버로딩: 메소드명은 같지만 매개변수가 서로 다를때 식별가능한 것
오버라이딩: 부모클래스의 메소드를 자식클래스의 이름을 같게하여 재정의함.
4. 다형성
- 하나의 클래스 변수에 다양한 클래스를 넣는 것
- 상속을 통해서 부모 자식 클래스가 만들어지면 부모 클래스 변수를 자식 클래스에 넣을 수 있음.
public class Animal {
public void makeSound() {
System.out.println("동물이 소리를 냅니다");
}
}
public class Dog extends Animal {
@Override
public void makeSound() {
System.out.println("멍멍!");
}
}
public class Cat extends Animal {
@Override
public void makeSound() {
System.out.println("야옹~");
}
}
public class Main {
public static void main(String[] args) {
Animal animal1 = new Dog();
Animal animal2 = new Cat();
Animal animal3 = new Animal();
animal1.makeSound();
animal2.makeSound();
animal3.makeSound();
Animal[] animals = new Animal[3];
animals[0] = new Dog();
animals[1] = new Cat();
animals[2] = new Animal();
for(Animal animal : animals) {
animal.makeSound();
}
Animal a1 = new Dog();
Animal a2 = new Cat();
Animal a3 = new Animal();
ArrayList<Animal> animals = new ArrayList<>();
animals.add(a1);
animals.add(a2);
animals.add(a3);
for (Animal animal : animals) {
animal.makeSound();
}
}
}
=========================================
<예시: 또 다른 예시>
class Shape {
void drow1() {
System.out.println("Shape:drow1");
}
void drow2() {
System.out.println("Shape:drow2");
}
}
class Triangle extends Shape {
@Override
void drow2() {
System.out.println("Triangle-drow2");
}
void drow3() {
System.out.println("Triangle-drow3");
}
}
public class JavaEx02 {
public static void main(String[] args) {
System.out.println("Shape에 Shape를 넣어 출력------------------------");
Shape s1 = new Shape();
s1.drow1();
s1.drow2();
System.out.println("s1.drow3() Shape에 없는 메소드여서 접근 불가");
System.out.println("Triangle에 Triangle(자식)를 넣어 출력 -------------");
Triangle t1 = new Triangle();
t1.drow1();
t1.drow2();
t1.drow3();
System.out.println("Shape(부모)에 Triangle(자식)을 넣어 출력------------");
Shape s2 = new Triangle();
s2.drow1();
s2.drow2();
Triangle t2 = (Triangle)s2;
t2.drow3();
}
}
1. 또 다른 예
class Pet {
public void eat() {
System.out.println("Pet이 밥을 먹는다.");
}
public void move() {
System.out.println("Pet이 움직인다.");
}
}
class Cat extends Pet {
@Override
public void eat() {
System.out.println("Cat이 밥을 먹는다.");
}
public void work() {
System.out.println("고양이가 쥐를 잡는다.");
}
}
class Dog extends Pet {
@Override
public void eat() {
System.out.println("Dog가 뼈다귀를 먹는다. 육식");
}
public void hunting() {
System.out.println("Dog가 꿩을 사냥한다.");
}
}
public class JavaEx03 {
public static void main(String[] args) {
Pet a0 = new Pet();
Pet a1 = new Cat();
Pet a2 = new Dog();
a0.eat();
a1.eat();
a2.eat();
}
}
- 배열을 이용한 다형성
class Student {
public void information() {
System.out.println("학생의 정보를 출력");
};
}
class HSchoolStudent extends Student {
public void information() {
System.out.println("고등학생의 정보를 출력");
System.out.println("원하는 진로정보 출력");
};
}
class UniversityStudent extends Student {
public void information() {
System.out.println("대학생의 정보를 출력");
System.out.println("원하는 취업처 정보 출력");
}
}
public class JavaEx04 {
public static void main(String[] args) {
Student[] sts = {
new Student(), new HSchoolStudent(), new UniversityStudent()
};
for(Student st : sts) {
System.out.println("---------------------------");
st.information();
}
}
}
(1) 다형성 예제
- 9/5 기준 실습용도로 학습
- 9/6 기준 복습하기
1. 제품 종류로 TV, 컴퓨터가 있음. 제품마다 5% 10% 할인
TV에는 inch, 컴퓨터에는 RAM크기와 같은 특별한 속성
두 제품 다 최종가격을 리턴하는 getPrice 메소드
TV의 경우 10인치가 넘어가면 가격에 배송료 만원 추가
RAM 같은 경우 1GB당 2만원을 가격에 추가
1] 부모 클래스로 Product 클래스를 만들어서 모든 제품이 가지고 있는 필드와 메소드를 구현하자.
class Product {
public String id = "";
public double price = 0;
public double discountRate = 0;
public Product(String id, double price, double discountRate) {
this.id = id;
this.price = price;
this.discountRate = discountRate;
}
public double getPrice() {
return price-price * (discountRate/100);
}
}
2] TV제품만 있는 필드와 TV에만 적용되는 계산 방법을 이용해서 TV클래스를 만들었다.
가격 계산 방법이 달라 getPrice 재정의함.
class TV extends Product {
public double inch = 0;
public TV(String id, double price, double discountRate, double inch) {
super(id,price,discountRate);
this.inch = inch;
}
@Override
public void getPrice() {
return inch > 10 ? super.getPrice+10000 : super.getPrice
}
}
3] Computer 제품만 있는 필드와 Computer에만 적용되는 계산 방법을 이용해서 Computer 클래스 만듬
가격 계산 방법이 달라 getPrice 재정의
class Computer extends Product {
public double Ram = 0;
public Computer(String id, double price, double discountRate, double Ram) {
super(id,price,discountRate);
this.Ram = Ram;
}
@Override
public void getPrice() {
return super.getPrice+Ram*2;
}
}
2. 고객은 VIP고객과 일반고객이 있음.
VIP고객은 구매 요금 2%, 일반고객은 구매요금에 1% 포인트 적립.
VIP고객만 특별히 제품가격 5% 할인.
포인트는 모든 물건 할인 후 최종 결제 금액으로 포인트 추가
정보를 출력할 수 있도록 toString 구현
1] 일반 고객을 표현할 수 있는 Customer 클래스 만들기
아이디, 보유 포인트, 물건 구매시 포인트 취득비율을 넣을 수 있는 필드와
point를 구하는 setPoint 메소드를 가지고 있음.
class Customer {
public String id = "";
public int point = 0;
public double pointRate = 0;
public void setPoint(Product p) {
this.point = (int) (p.getPrice() * (pointRate/100));
public Customer(String id, int point, double pointRate) {
this.id = id;
this.point = point;
this.pointRate = pointRate;
}
@Override
public String toString() {
return "Customer [id = " + id + ", point=" + point + ", pointRate=" + pointRate + "]";
}
}
2] VIP고객을 표현할 수 있는 VIPCustomer 클래스 만들기.
아이디, 보유 포인트, 물건 구매시 포인트 취득비율을 넣을 수 있는 필드와
point를 구하는 setPoint 메소드 가짐
class VIPCustomer extends Customer {
public double priceRate = 0;
public VIPCustomer(String id, int point, double pointRate, double priceRate) {
super(id,point,pointRate);
this.priceRate = priceRate;
}
public void setPoint(Product p) {
double resultPrice = p.getPrice() - (p.getPrice() * (priceRate / 100));
this.point += (int) (resultPrice * (pointRate / 100);
}
@Override
public String toString() {
return "VIPCustomer [priceRate =" + priceRate + ", id=" + id + ", point=" + point + ", pointRate=" + pointRate + "]";
}
3] 특정 고객이 특정 제품을 구매할때 고객의 포인트를 추가할 수 있도록 메인 클래스에 다음 프로그램을 넣어 완성하기.
public class Main {
public static void main(String[] args) {
Product p1 = new TV("LG0015", 100000,10,40);
Product p2 = new Computer("AMD0051", 100000, 20, 16);
Customer c1 = new Customer("hong", 0, 1);
Customer c2 = new VIPCustomer("kim",0,2,5);
c1.setPoint(p1);
c2.setPoint(p2);
System.out.println(c1);
System.out.println(c2);
}
4] 상위와 같은 형태의 관계 클래스들을 만들어 본인이 생각하는 기능을 추가하여 프로그램 구현
a) 부모: Vehicle 자식: Car, Bus
class Vehicle {
public String transport = "";
public int price = 0;
public Vehicle(String transport, int price) {
this.transport = transport;
this.price = price;
}
public void run() {
System.out.println("Vehicle이 움직이고 있습니다.");
}
}
class Car extends Vehicle {
public int speed = 0;
public Car(String transport, int price, int speed) {
super(transport, price);
this.speed = speed;
}
public void setSpeedUp() {
speed = speed + 10;
}
public void setSpeedDown() {
speed = speed - 10;
}
@Override
public void run() {
System.out.println("Car가 움직이고 있습니다");
}
}
class Bus extends Vehicle {
public double distance = 0;
public Bus(String transport, int price, double distance) {
super(transport, price);
this.distance = distance;
}
public void setDistance() {
distance = distance + 10;
}
@Override
public void run() {
System.out.println("Bus가 움직이고 있습니다");
}
}
public class Main {
public static void main(String[] args) {
Vehicle v1 = new Bus("천안버스",1500,30.0);
Vehicle v2 = new Car("소나타", 0, 100);
Vehicle v3 = new Vehicle("Vehicle",0);
v1.run();
v2.run();
v3.run();
}
}
b) 부모: Shape, 자식: Rectangle, Circle
class Shape {
public String name;
public Shape(String name) {
this.name = name;
}
public void draw() {
System.out.println("Shape를 그립니다");
}
}
class Rectangle2 extends Shape {
public Rectangle2(String name) {
super(name);
}
@Override
public void draw() {
System.out.println("사각형을 그립니다");
}
}
class Circle2 extends Shape {
public Circle2(String name) {
super(name);
}
@Override
public void draw() {
System.out.println("원을 그립니다");
}
}
public class ClassEx08 {
public static void main(String[] args) {
Shape s1 = new Rectangle2("모양");
Shape s2 = new Circle2("사각형");
Shape s3 = new Shape("원");
s1.draw();
s2.draw();
s3.draw();
}
}