접근 제어자 복습
package com.poseidon.access;
public class Test02 {
public static void main(String[] args) {
A a = new A();
A.number = 10;
System.out.println(A.number); // 클래스명.static 필드명, static 은 객체 없이도 사용 가능
a.number = 100;
System.out.println(a.number); // 100 출력
System.out.println(A.number); // 100 출력, static 필드는 한개만 존재
// B b = new B(); // 생성 불가
B b = B.getInstance();
B b2 = B.getInstance();
B b3 = B.getInstance();
B b4 = B.getInstance();
b.setNum(1);
b2.setNum(2);
b3.setNum(3);
b4.setNum(4);
System.out.println(b.getNum()); // 4
System.out.println(b2.getNum()); // 4
System.out.println(b3.getNum()); // 4
System.out.println(b4.getNum()); // 4
// 객체를 여러 개 생성하여도 static 으로 인해 객체는 1 개만 존재
}
}
class A {
// final static int number1 = 0; // 미리 값 설정
// final int number1; // 초기에 값 세팅
static int number; // 기울어지는 것
int num;
// public A(int number1) { // static 이 아닌 final 객체는 생성자를 통해 초기 값 설정
// this.number1 = number1;
// }
}
class B {
static B b = null;
private int num;
public int getNum() {
return num;
}
public void setNum(int num) {
this.num = num;
}
private B() {
System.out.println("생성자 입니다.");
}
public static B getInstance() {
if (b == null) { // b 가 null 이면 새로운 객체 생성
return b = new B();
} else { // b 가 null 이 아니면 기존 객체 반환
return b;
}
}
}
접근제한자, 오버라이딩 등
package com.poseidon.inheritance;
import dec19.Test03;
// 상속 + 접근 제어자 protected
class Animal extends Test03 {
protected String name;
int age;
public void sleep() {
testNumber = 10; // protected 는 상속으로 엮인 클래스 내부에서만 사용 가능
// 객체 생성 시에는 사용 불가
}
}
class Cat extends Animal {
protected int catNumber;
public void change() {
testNumber = 10;
}
@Override // 어노테이션 = 표시 기능
public void sleep() {
// super.sleep();
System.out.println("고양이가 침대에서 잠을 잡니다.");
}
}
class Dog extends Animal {
@Override
public void sleep() {
System.out.println(name + "이(가) 집에서 잠을 잡니다.");
}
}
public class Inheritance extends Test03{ // 상속
public static void main(String[] args) {
Cat cat = new Cat();
Dog dog = new Dog();
cat.sleep();
cat.name = "야옹";
cat.catNumber = 1; // 호출 가능
dog.age = 3;
dog.sleep(); // 부모 클래스 필드 및 메소드 사용 가능
// cat.testNumber = 10; // testNumber 필드에서는 default
// cat.testMethod(); // Test03 클래스와 패키지가 달라 사용 어려움
Inheritance inheritance = new Inheritance();
System.out.println(inheritance.testNumber); // 상속받은 클래스에서만 사용 가능
}
}
이해가 안가지만.. 다형성..
package polymorphism;
// 다형성 Polymorphism
/*
* 다형성은 동적 바인딩이 지원되는 프로그램 언어에서 사용할 수 있음
* 런타임 때 최종 타입이 결정
* 하나의 객체가 여러가지 형태를 가질 수 있는 것
*
* 다형성을 활용하면 부모 클래스가 자식 클래스의 동작 방식을 알 수 없어도
* 오버라이딩을 통해 자식 클래스에 접근할 수 있음
*
* 장점
* 유지보수 : 여러 객체를 하나의 타입으로 관리할 수 있음
* 재사용성 : 객체의 재사용이 쉬움
* 느슨한 결합 : 클래스 간의 의존성을 줄여 확장성은 높아지고 결합도는 낮아짐
*
* 다형성의 조건
* 상위 클래스와 하위 클래스는 상속 관계여야 함
* 다형성이 보장되기 위해서 오버라이딩이 반드시 필요
* 자식 클래스의 객체가 부모 클래스의 타입으로 형 변환 해야 함
*/
public class Polymorphism {
public static void main(String[] args) {
Ironman ironman = new Ironman();
Hero h = new Ironman(); // 반드시 부모 클래스가 앞에 나와야 함
ironman.makeSuit();
// h.makeSuit(); // Hero 에는 해당 메소드가 없기 때문에 사용 불가, Hero 에 있는 것만 사용 가능
h.attack(); // Ironman 클래스의 attack 메소드 실행, "레이저 공격" 출력
Ironman mark2 = (Ironman) h;
mark2.makeSuit(); // Ironman 클래스의 메소드를 사용할 수 있는 첫 번째 방법
((Ironman)h).makeSuit(); // 두 번째 방법
Hulk hulk = new Hulk();
hulk.attack(); // "주먹 공격" 출력
// ((Ironman)hulk).makeSuit(); // 불가능
// ((Ironman)((Hero)hulk)).makeSuit(); // 불가능
System.out.println("-----------------");
Hero[] avangers = new Hero[5];
avangers[0] = new Ironman();
avangers[1] = new Hulk();
avangers[2] = new Superman();
avangers[3] = new Xman();
avangers[4] = new Ironman();
for (Hero hero : avangers) {
hero.attack();
}
Hero hero = new Hero(); // 이런 일을 방지하고자 추상화가 나옴
}
}
class Hero {
String name;
void attack() {
System.out.println("공격");
}
}
class Ironman extends Hero {
public void makeSuit() {
System.out.println("자비스, 슈트 만들어");
}
@Override
void attack () {
System.out.println("레이저 공격");
}
}
class Hulk extends Hero {
@Override
void attack() {
System.out.println("주먹 공격");
}
}
class Superman extends Hero {
}
class Xman extends Hero {
}
추상화
package abstractEx;
// 추상화
/*
* 자바에는 추상화라는 개념이 있음
* 추상 : 현실화 될 필요가 없는, 인스턴스화 할 필요가 없는 클래스
* -> 인스턴스화 할 필요가 없는 성질의 클래스
* 추상화 된 클래스나 메소드는 상속 받은 클래스에서 완성 시켜야 함
*
* 자바에서는 객체지향을 통해 프로그램이 실행되는데
* 추상이라는 개념을 클래스에 적용시키면 자신의 인스턴스를 발생할 수 없는 형태로 지정됨
* 이렇게 인스턴스화 할 필요가 없지만 상속 개념에서 중요한 위치를 가지는 클래스를 보통 추상 클래스로 정의
*
* 선언 규칙
* 1. 클래스에 정의된 메소드 중 추상 메소드가 하나라도 있다면 해당 클래스는 무조건 추상 클래스가 됨
* 추상 클래스는 class 앞에 absract 라고 적음
* 2. 추상 메소드는 메소드 바디가 없는 형태, 추상 메소드는 abstract 라는 키워드를
* 리턴 타입 앞에 선언, 파라미터 괄호() 뒤에 세미콜론(;) 을 붙여 명령을 종료시킴
* 3. 추상 클래스는 자신의 인스턴스를 발생시키지 못함
* 하지만 생성자, 메소드, 필드는 모두 선언 및 정의 가능
* 상속도 가능, 또한 Super type 으로 존재 가능하므로 다형성도 적용
* 4. 추상 클래스가 되고 싶다면 class 앞에 abstract 를 붙이면 됨
*/
abstract class Hero { // 추상 클래스
String name;
int age;
abstract void attack(); // 추상 메소드
abstract void sleep();
abstract void eat();
}
class Ironman extends Hero{
@Override
void attack() {
System.out.println("레이저 공격");
}
@Override
void sleep() { }
@Override
void eat() { }
}
class Hulk extends Hero {
@Override
void attack() {
System.out.println("근육 공격");
}
@Override
void sleep() { }
@Override
void eat() { }
}
class SpiderMan extends Hero{
void attack () { // 미구현 된 메소드를 자식 클래스에서 구현
System.out.println("거미줄 공격");
}
@Override
void sleep() { }
@Override
void eat() { }
}
class Hawk_eye extends Hero {
@Override
void attack() {} // 바디 ({}) 만 열리면 구현한 것으로 인정됨
@Override
void sleep() { }
@Override
void eat() { }
}
public class AbstractEx {
public static void main(String[] args) {
// Hero hero = new Hero(); // 추상 클래스는 인스턴스 생성 불가
Hero hero = new Ironman(); // 추상 클래스를 자식 클래스로 완성
SpiderMan spiderMan = new SpiderMan();
spiderMan.attack();
}
}
추상화 두번째
package abstractEx;
/* 추상 클래스 : 인터페이스의 역할도 하면서 클래스 같은 돌연변이 클래스
* 추상 클래스를 만들기 위해서 class 앞에 abstract 를 붙임
* 내부 메소드에도 abstract 를 붙이고 바디를 제거
* 인터페이스와 동일하게 메소드 바디 {} 가 없음
* -> 상속받는 자식 클래스에서 미구현된 메소드를 구현해야 함
*
* 추상 클래스 : 객체를 만들 수 없는 클래스 = 미완성된 기능이 있기 때문에 만들 수 없음
* 추상 메소드 : 바디가 없는 메소드 (내용이 없음)
* 미완성된, 구현이 없는, 바디가 없는 메소드 = 하위 클래스에서 구현 (오버라이드)
* 하위 클래스에서 구현을 강제로 하게 함 = 프로그램 구조가 확실해 짐
*/
public class abstractEx2 {
}
클래스 이동 확인
package test;
public class Test01 {
public static void main(String[] args) {
A b = new B(); // B 클래스를 갖는 객체 생성
b.paint(); // B 클래스의 paint 로 이동
System.out.println("-");
b.draw(); // BDCD - D 출력
}
}
class A {
public void paint() {
System.out.println("A");
draw();
}
public void draw() {
System.out.println("B");
draw(); // 객체 생성 시 참고한 클래스의 draw 메소드로 이동
}
}
class B extends A {
@Override
public void paint () {
super.draw(); // 부모 클래스의 draw 메소드 실행
System.out.println("C");
this.draw(); // 객체 생성 시 참고한 클래스의 draw 메소드로 이동
}
@Override
public void draw() {
System.out.println("D"); // D 출력하고 종료
}
}
'JAVA' 카테고리의 다른 글
231221 Java (2) | 2023.12.21 |
---|---|
231220 Java (0) | 2023.12.20 |
231218 Java (0) | 2023.12.18 |
231215 Java 객체지향 (0) | 2023.12.15 |
231214 Java 객체지향 (2) | 2023.12.14 |