6. 클래스
public private 등 접근제한자 다른데에도 사용할 수 있다.
생성자에도 쓸수있다.
6.13 생성자 접근제한자
public class C03AccessModifier {
public static void main(String[] args) {
MyClass03 o1 = new MyClass03();
// private이어서 접근 안됨
MyClass03 o2 = new MyClass03(6);
// package private 이어서 접근 안됨
MyClass03 o3 = new MyClass03("hello");
}
}6.14 싱글톤
어플을만들다보면 클래스로 만들어진 인스턴스가 하나이면 좋겠다
그런데 그걸 제한하고 싶을때가 있다. 생성자에 접근제한자를 붙여서 적절하게 사용할 수 있다.
생성자를 private으로 만든다. 하지만 내부에선 사용가능하다.
인스턴스를 리턴해주는 것을 만든다.
public static MyClass05 getInstance() {
return new MyClass05();
}메소드는 public이니까 사용이 가능하다.
이 방법으로 몇번이고 얻어낼 수있다.
private static MyClass05 ins;
public static MyClass05 getInstance() {
if (ins == null) {
ins = new MyClass05();
}
return ins;
}이렇게 ins가 null일때만 새로만드니 한번만들어지면 같은 인스턴스가 계속 리턴된다.
public class C04Singleton {
public static void main(String[] args) {
//인스턴스 여러개 만들기 가능
//각각의 참조값을 가짐.
MyClass04 o1 = new MyClass04();
MyClass04 o2 = new MyClass04();
System.out.println(System.identityHashCode(o1)); //617901222
System.out.println(System.identityHashCode(o2)); //1159190947
MyClass05 o3 = MyClass05.getInstance();
MyClass05 o4 = MyClass05.getInstance();
System.out.println(System.identityHashCode(o3)); //798154996
System.out.println(System.identityHashCode(o4)); //798154996
}
}어플리케이션에서 하나만 인스턴스를 만드는 방법이 있다.
책에서 방법과 유사하다.
싱글톤객체를 하나의 라는 뜻임. 하나의 인스턴스만 존재하도록 하는 것이다.
여러방법이 있고 방법들 중하나이다.
책은 다음과 같다.
public class Singleton {
// private 접근 권한을 갖는 정적필드 선언과 초기화
private static Singleton singleton = new Singleton();
// private 접근권한을 갖는 생성자 선언
private Singleton() {
}
//public 접근 권한을 갖는 정적 메소드 선언
public static Singleton getInstance() {
return singleton;
}
}public class SingletonExample {
public static void main(String[] args) {
/*
Singleton obj1 = new Singleton(); 컴파일에런
Singleton obj2 = new Singleton(); 컴파일에러
*/
//정적 메소드를 호출해서 싱글톤 객체를 얻음
Singleton obj1 = Singleton.getInstance();
Singleton obj2 = Singleton.getInstance();
if (obj1 == obj2) {
System.out.println("같은 Singleton객체입니다.");
} else {
System.out.println("다른 Singleton객체입니다.");
}
//같은 Singleton객체입니다.
}
}6.14.1 확인문제 18번
싱글톤 만들기
public class ShopService {
private static ShopService ins = new ShopService();
private ShopService() {
}
public static ShopService getInstance() {
return ins;
}
}public class App {
public static void main(String[] args) {
ShopService o1 = ShopService.getInstance();
ShopService o2 = ShopService.getInstance();
System.out.println(System.identityHashCode(o1));
System.out.println(System.identityHashCode(o2));
if (o1 == o2) {
System.out.println("같은 ShopService 객체 입니다.");
} else {
System.out.println("다른 ShopService 객체 입니다.");
}
}
}6.15 클래스 접근제한자
클래스에도 접근제한자를 붙일 수 있다.
public 어디서든지 접근 가능하다.
package private은 같은패키지만 가능하다.
class MyClass07 {
}public class C06AccessModifier {
public static void main(String[] args) {
MyClass06 o1 = new MyClass06();
// 안됨 (MyClass07은 package private)
//ch06.lecture.p10access.package1.MyClass07 o2;
}
}하나의 파일에 여러 클래스 작성 할 경우
public 클래스는 하나이어야 한다. public 클래스와 파일명이 같아야 한다.
6.16 확인문제 20번
account가 여러개 만들어질수 있으니 배열에 저장
public class Bank {
public static void main(String[] args) {
AccountT[] accounts = new AccountT[100];
int numOfAccounts = 0;
Scanner scanner = new Scanner(System.in);
boolean run = true;
while (run) {
System.out.println("--------------------------");
System.out.println("1.계좌생성|2.계좌목록|3.예금|4.출금|5.종료");
System.out.println("--------------------------");
System.out.print("선택>");
int menu = scanner.nextInt();
switch (menu) {
case 1 -> {
// 계좌생성
System.out.println("-----------");
System.out.println("계좌생성");
System.out.println("-----------");
System.out.print("계좌번호:");
String number = scanner.next();
System.out.print("계좌주:");
String name = scanner.next();
System.out.print("초기입금액:");
int money = scanner.nextInt();
AccountT account = new AccountT();
account.setNumber(number);
account.setName(name);
account.setMoney(money);
accounts[numOfAccounts] = account;
numOfAccounts++;
System.out.println("결과: 계좌가 생성되었습니다.");
}
case 2 -> {
// 목록 보여주기
System.out.println("-----------");
System.out.println("계좌목록");
System.out.println("-----------");
for (int i = 0; i < numOfAccounts; i++) {
System.out.printf("%7s%10s%10d%n", accounts[i].getNumber(), accounts[i].getName(),
accounts[i].getMoney());
}
}
case 3 -> {
// 예금
System.out.println("-----------");
System.out.println("예금");
System.out.println("-----------");
System.out.print("계좌번호: ");
String number = scanner.next();
System.out.print("예금액: ");
int inputMoney = scanner.nextInt();
// 입력된 계좌번호를 가진 Account 객체 찾아서
for (int i = 0; i < numOfAccounts; i++) {
AccountT cur = accounts[i];
if (cur.getNumber().equals(number)) {
// 입력 받은 금액을 더해서 다시 넣어준다(set)
int money = cur.getMoney() + inputMoney;
cur.setMoney(money);
}
}
}
case 4 -> {
// 출금
System.out.println("-----------");
System.out.println("출금");
System.out.println("-----------");
System.out.print("계좌번호: ");
String number = scanner.next();
System.out.print("출금액: ");
int inputMoney = scanner.nextInt();
// 입력된 계좌번호를 가진 Account 객체 찾아서
for (int i = 0; i < numOfAccounts; i++) {
AccountT cur = accounts[i];
if (cur.getNumber().equals(number)) {
// 입력 받은 금액을 빼서 다시 넣어준다(set)
int money = cur.getMoney() - inputMoney;
cur.setMoney(money);
}
}
}
case 5 -> {
// 종료
run = false;
}
}
}
System.out.println("프로그램 종료");
}
}내가 풀엇던거랑 전혀 다르게 풀었다.
그냥 숫자를 증가시켜서 현재 배열의 크기를 알게되니 더 쉽다.
7. 상속
자바가 진화하면서 상속과 인터페이스가 모호하게 되었다.
만약 선택해야한다면 별일없으면 인터페이스를 사용하는게 낫다.
6장은 하나 클래스의 상태
7장은 여러 클래스들의 관계
다른 클래스를 물려받는다. 그런 코드가 상속이다.
나중에 깨닫는게 많다.
7.1 상속이란
public class MyClass02 extends MyClass01 {}
하면 MyClass01의 멤버(필드, 메소드)를 MyClass02를 상속받는다
그렇지만 필드는 대부분 private니까 대부분 메소드만 상속받는다.
public class C01Inheritance {
public static void main(String[] args) {
MyClass02 o1 = new MyClass02();
o1.field1 = "aaa";
o1.field2 = 99;
MyClass01 o2 = new MyClass01();
o2.method1();
o2.method2();
MyClass02 o3 = new MyClass02();
o3.method1();
o3.method2();
}
}다 사용이 가능하다.
그래서 이들의 관계를
자식클래스(SubClass, 하위클래스) : 상속받은 클래스
부모클래스(Super Class, 상위클래스) : 상속해주는 클래스라고한다.
7.2 override
sub클래스도 필요하면 메소드를 가질 수 있다.
또한 필요하면 재정의해서 사용할 수 있다.
public class SubClass03 extends SuperClass03 {
// method1, method2 상속받음
// 상속받은 메소드는 재정의(Override) 가능
// method2 재정의
public void method2() {
System.out.println("서브클래스 메소드2");
}
public void method3() {
System.out.println("서브클래스 메소드3");
}public class C03Override {
public static void main(String[] args) {
SubClass03 o1 = new SubClass03();
o1.method1();
o1.method2(); // 재정의한 메소드 실행됨
o1.method3();
}
}7.2.2 override - 2
재정의하려는데 실수할 수도 있다.
어노테이션 (annotation) @Override를 사용해서 컴파일러에게 검사받을 수 있다.
public class SubClass04 extends SuperClass04 {
// SuperClass04 method1 재정의
@Override
public void method1() {
System.out.println("sub method1");
}
@Override
public void method2() {
System.out.println("sub method2");
}
}7.3 타입변환(다형성)
SuperSuper05를만들고 Super05가 이것을 상속받고 Sub05가 위를 상속받는다.
다형성 : 하나의 객체가 다양한 타입을 가질 수 있는 것을 의미한다.
재규어가 잇다고 해보자.
밝은 무늬 재규어 어두운무늬 재규어 모두 재규어의 기능을 사용할 수 있다.
밝은 무늬 재규어 is a 재규어이다.
이게 is a 상속관계이다.
public class Super06{
}public class Sub06 extends Super06 {
}이관계이면 Sub06이 Super06이다 할 수 있다.
그래서 부모객체 타입에 자식객체를 담을 수 있다.
public class C06Polymorphism {
public static void main(String[] args) {
Sub06 o1 = new Sub06();
Super06 o2 = o1; // ok
Super06 o3 = new Sub06(); // ok
Super06 o4 = new Super06(); // ok
// Sub06 o5 = o4;//불가능
}
}재규어는 밝은무늬 재규어다 할 수 없듯이 자식객체타입에 부모를 담을 수 없다.
자식타입으로 만들어진 참조값을 부모타입 객체에 넣는게 가능하다.
이것이 다형성의 시작이다.
7.4 다형성
밝은무늬 재규어, 어두운무늬 재규어에 기능이있다고 해봊자.
실제 인스턴스의 메소드가 기능한다는 점이 중요하다.
재규어의 기능을 실행하면 실제 인스턴스가 실행된다.
동물 - 호흡하다
말 -폐 호흡하다 물고기 - 아가미 호흡하다.
실제 기능하는 것은 상속받은 클래스들이 기능하는 것이다.
실제 인스턴스가 작동이된다.
class Animal {
public void breath() {
System.out.println("호흡한다.");
}
}
class Horse extends Animal {
@Override
public void breath() {
System.out.println("폐로 호흡한다.");
}
}
class Fish extends Animal {
@Override
public void breath() {
System.out.println("아가미로 호흡한다.");
}
}public class C07Polymorphism {
public static void main(String[] args) {
Animal a1 = new Horse();
Animal a2 = new Fish();
a1.breath(); //폐로 호흡한다.
a2.breath(); //아가미로 호흡한다.
}
}2023.03.06 후기
예제와 같은 경우 내가 공부한 방식과 다른 것을 배움으로써 도움이 되었다.
'국비 > Java' 카테고리의 다른 글
| 2023.03.08 29일차 Java (0) | 2023.03.08 |
|---|---|
| 2023.03.06 27일차 Java (0) | 2023.03.06 |
| 2023.03.02 25일차 Java (0) | 2023.03.02 |
| 2023.02.28 24일차 Java (0) | 2023.02.28 |
| 2023.02.27 23일차 Java (0) | 2023.02.27 |