static, 클래스들의 관계

2023. 12. 6. 23:24Daily Codig Reminder

static

 

객체 생성할 필요가 없음


public class Test {
{
//인스턴스 초기화 블럭
System.out.println("인스턴스 블럭 실행");
}
static {//static  초기화 블럭
System.out.println("static 블럭 실행");
}
public Test() {
System.out.println("기본생성자 호출됨");
}
public static void main(String[] args) {
System.out.println("main 실행");
Test t = new Test(); // 생성자 호출
Test t2= new Test();
}
}

 

8.3 싱글톤 디자인 패턴 ( Singleton Design Pattern ) ★

은행관리 시스템

은행 객체 *1 (반드시 1개의 객체만 생성 , 사용하도록 작성)

계좌 객체 * 100개

 

public class Bank {
private static Bank b = new Bank();//2. private 으로 다른클래스에서 new 객체 생성을 막음
private String name;
public static Bank getB() {
return b;
}
public static void setB(Bank b) {
Bank.b = b;
}
public void setName(String name) {
this.name = name;
}
private Bank() {} //1.  값을 다른걸 넣을 수도 없고 접근못하게 막아놓음
public static Bank getBank() { //3. bank객체를 필요한곳으로 호출
return b; // setBank 쓰면 다른함숭서 설정할 수 있기 떄문에 안됨/
}
public String getName() {
return "XX 은행";
}
public void setName(String name) {
this.name=name;
}
}

 

public class TestBank {
public static void main(String[] args) {
Bank b1 = Bank.getBank(); //4필요한 곳에서 getbank 를 통해 만들어진 bank를 받아다가 사용
System.out.println(b1);
Bank b2 = Bank.getBank();//5
System.out.println(b2);
b1.setName("kb 저축");
System.out.println(b2.getName());
}
}

  1. 외부에서 객체생성하지 못하도록 생성자의 접근 지정자를 private로 지정한다.
    private 접근 지정자는 같은 클래스에서만 접근 가능하다.

  2. 단 한번은 생성해야 되기 때문에 자신의 클래스에서 객체생성 코드를 사용한다.
    static 지정자를 사용하여 프로그램 실행시 단 한번 생성된다.

  3. 외부에서는 객체생성은 불가능하지만, 다른 클래스 멤버들의 접근은 허용해야 된다.
    따라서 2번에서 생성한 객체의 참조변수를 static 메서드를 이용해서 외부에 돌려준다.
    static 메서드를 사용해야 되는 이유는 객체생성 없이 사용할 수 있기 때문이다.

  4. 외부에서는 클래스.메서드로 참조값을 얻어서 다른 멤버들을 접근할 수 있다

6장. 클래스들의 관계

 

package com.Test;
public class Student {
//1. 멤버변수영역
String name;
int age;
String addr;
//has a 관계
private Parent parent;
public void setParent (Parent parent) {
this.parent=parent;
}
public Parent getParent(){
return this.parent;
}
//2. 생성자영역
public Student(String name, int age, String addr, Parent parent)
{
super();
this.name = name;
this.age = age;
this.addr = addr;
this.parent = parent; //멤버변수
}
public Student() {
super();
// TODO Auto-generated constructor stub
}
//3. 함수영억
public void setName(String name) {
System.out.println("setname 호출");
this.name=name;
}
public void setAge(int age){
System.out.println("setage 호출");
if (age<120) this.age=age;
else System.out.println("잘못된 나이입니다.");
}
public void setAddr(String addr){
System.out.println("setaddr 호출");
this.addr=addr;
}
//getXXX 영역
public String getName() {
System.out.println("getname 호출");
return this.name;
}
public int getAge() {
System.out.println("getage 호출");
return this.age;
}
public String getAddr() {
System.out.println("getaddr 호출");
return this.addr;
}
@Override
public String toString() {
return "Student [name=" + name + ", age=" + age + ", addr=" + addr +", parent=" + parent + "]";
}
}

 

package com.Test;
public class Parent {
String pName;
int pAge;
public String getpName() {
return pName;
}
public void setpName(String pName) {
this.pName = pName;
}
public int getpAge() {
return pAge;
}
public void setpAge(int pAge) {
this.pAge = pAge;
}
public Parent(String pName, int pAge) {
super();
this.pName = pName;
this.pAge = pAge;
}
public Parent() {
super();
// TODO Auto-generated constructor stub
}
@Override
public String toString() {
return "Parent [pName=" + pName + ", pAge=" + pAge + "]";
}
}

 

package com.Test;
public class Test {
public static void main(String[] args) {
Parent p1 = new Parent("aa", 50);
Student stu = new Student("홍길동", 10, "서울",p1 );
Student stu2 = new Student("이순신", 11, "제주",new Parent("BB", 40) );
//홍길동, 이름, 나이, 홍길동 부모의 이름과 나이를 sysout
String sname = stu.getName();
System.out.println(sname);
int sage = stu.getAge();
System.out.println(sage);
Parent parent=stu.getParent();
System.out.println(parent.getpName()+"\t"+parent.getpAge());
System.out.println("====================");
//이순신의 이름, 이순신 부모 이름, 나이
String sname2=stu2.getName();
System.out.println(sname2);
Parent parent1=stu2.getParent();
System.out.println(stu2.getParent().getpName()+"\t"+stu2.getParent().getpAge());
}
}

 

public class Test2 {
public static void main(String[] args) {
Parent p1 = new Parent("aa", 50);
Student stu = new Student("홍길동", 10, "서울",p1 );
Student stu2 = new Student("이순신", 11, "제주",new
Parent("BB", 40) );
//홍길동, 이름, 나이, 홍길동 부모의 이름과 나이를 sysout
Student [] stuarr = {stu,stu2};
for(int i = 0; i<stuarr.length; i++) {
System.out.println(stuarr[i].name);
System.out.println(stuarr[i].getParent().getpName());
System.out.println(stuarr[i].getParent().getpAge());
}System.out.println("==========");
for (Student  s : stuarr) {
System.out.println(s.getName());
System.out.println(s.getParent().getpName() + "\t" +s.getParent().getpAge());
}}

 

상속

부모 class

이름, 나이

A class 상속 부모

직업

B class 상속 부모

주소

A 클래스 객체 생성 ⇒ object 부모객체 선 생성 후 자식 객체

B 클래스 객체 생성 ⇒ object 부모객체 선 생성 후 자식 객체

객체 간에 is a 관계가 성립되어야 한다.
§ 부모클래스의 멤버(인스턴스 변수, 메서드)를 자식클래스가 선언 없이 사용 가능하다. 단 부모 멤버중에서 private로 지정한 멤버와 생성자는 상속이 불가능하다.
§ 자바는 단일 상속 (Single Inheritance) 만 지원한다.
§ 상속을 UML 표기법으로 을 이용한다. (실선을 이용한 삼각형)
§ 상속을 자바코드에서는 extends 키워드로 표현한다.
§ API 및 사용자가 만든 클래스들은 모두 상속 관계인 계층구조로 되어있다. 가장 상위에 있는 클래스는 java.lang.Object 클래스이며 최상위 클래스라고 부른다. 따라서 모든 클래스는 Object 클래스를 자연스럽게 상속받는다.

 

 

class Employee {
String name;
int salary;
public String getEmployee() {
return "Manager:  "+name + "\t"+ salary ;
}
public Employee() {
super(); //object 의 기본생성자 호출
System.out.println("Employee 의 기본생성자 호출");
}
public Employee(String name, int salary) {
super();
this.name = name;
this.salary = salary;
}}
class Manager extends Employee{
String depart;
public Manager () {
super();
System.out.println("manager 기본생성자 호출");
}
public Manager (String name, int salary, String depart) {
super();
System.out.println("manager 3개짜리 생성자 호출");
this.name=name;
this.salary=salary;
this.depart=depart;
}
public String getManager () {
return "Manager:  "+name + "\t"+ salary + "\t"+depart;
}
}
public class Ee06_1{
public void main(String[] args) {
Manager m = new Manager ();
System.out.println(m.getManager());
System.out.println(m.name);
System.out.println(m.getManager());

System.out.println(m.getEmployee());
Employee e = new Employee();
}
}

 

Employee 의 기본생성자 호출
manager 기본생성자 호출
Manager:  null 0 null
null
Manager:  null 0 null
Manager:  null 0
Employee 의 기본샌성자 호출

 

§ 자식클래스에서 명시적으로 부모 생성자를 호출하는 경우

super([인자값]) 형식으로 사용하며 인자값은 없거나 여러 개가 가능하다.

주의할 점은 반드시 자식 생성자의 첫 라인에서 호출해야 된다

 

class Employee {
String name;
int salary;
public String getEmployee() {
return name+"\t"+salary;
}//getemp
public Employee() {}
public Employee(String name, int salary) {
//super();
System.out.println("emp 2개짜리 생성자 호출");
this.name=name;
this.salary=salary;
}
@Override
public String toString() {
return "Employee [name=" + name + ", salary=" + salary + "]";
}
}//Employee
class Manager extends Employee{
String depart;
public String getManager() {
return super.getEmployee()+"\t"+depart;
}
public Manager (String name, int salary, String depart) {
super(name,salary); //부모 생성자의 명시적 호출
this.depart=depart;
}
}//end manager class
public class Ex06_3 {
public static void main(String[] args) {
Employee e = new Employee ("홍길동", 2000);
System.out.println(e.getEmployee());
Manager m = new Manager("이순신", 4000,"개발");
System.out.println(m.getManager());|
}
}

 

emp 2개짜리 생성자 호출
홍길동 2000
emp 2개짜리 생성자 호출
이순신 4000 개발

 

4. 메서드 오버라이딩 (재정의)★

 

 

일반적으로 상속 관계시 부모 클래스의 메서드를 하위 클래스에서는 조건 없이 사용 가능하다.
하지만 하위 클래스에서 부모 클래스의 메서드를 재정의해서 사용 오버라이딩

규칙
§ 상속이 전제되어야 한다.
§ 메서드 이름이 반드시 동일해야 된다.
§ 메서드 리턴타입이 반드시 동일해야 된다. 단, 상속관계인 경우에는 작은 타입으로 재정의 가능하다.
§ 메서드 인자 리스트가 반드시 동일해야 된다.
§ 접근 지정자는 부모의 레벨보다 같거나 확대만 가능하다.
§ 예외 클래스는 부모의 클래스보다 계층적으로 같거나 하위 클래스만 사용 가능하다.
§ static, final, private 지정자를 가진 메서드는 오버라이딩이 불가능하다.

 

class Employee{
String name;
int salary;
public String getEmployee() {
return name+ "\t"+salary;
}
public Employee() {}
public Employee(String name, int salary) {
this.name=name;
this.salary=salary;
}
}//employee
class Manager extends Employee{
String depart;
//재정의
@Override
public String getEmployee() {
// TODO Auto-generated method stub
return super.getEmployee()+"\t"+depart;
}
public Manager(String name, int salary, String depart) {super(name, salary);
this.depart = depart;
}
@Override
public String toString() {
return "Manager [depart=" + depart + ", name=" + name + ", salary=" + salary + "]";
}
}//end manager
public class Ex06_6 {
public static void main(String[] args) {
Employee e = new Employee ("홍길동", 2000);
Manager m = new Manager("이순신", 4000,"개발");
System.out.println(e.getEmployee());
System.out.println(m.getEmployee());
System.out.println(m.toString()); //m.toString();
System.out.println(m); //m.toString();
}
}

 

홍길동 2000
이순신 4000 개발
Manager [depart=개발, name=이순신, salary=4000]
Manager [depart=개발, name=이순신, salary=4000]

 

5.다형성★

 

부모 클랫, 타입의 변수로서 자식 클래스를 저장할 수있다.

  1. 상속관계가 아닌경우 EMP MANAGER Emp m = new Manager(); ⇒ 안됨
  2. 상속관계인경우 Manager extends emp
    -1 manager m = new Manager();
    -2 Emp m2 = new Manager(); //부모타입 변수에 자식객체 저장
    == 다형성
    주의할 점: Emp - name, age
    Manager - address
    m2. name m2.age 밖에 안됨 타입이emp라서
    address 샤용을 위해서는 자식타입으로 형변환을 해
    ((Manager)m2).address = ‘제주’

class Employee {
String name;
int salary;
public String getEmployee() {
System.out.println("부모 getEmployee");
return name +"\t"+ salary;
}//getemp
public Employee() {}
public Employee(String name, int salary) {
this.name=name;
this.salary=salary;
}
public void a () {
System.out.println("emp a 함수");
}
}//employee
class Student extends Employee {
String address;
public Student(String name, int salary, String address) {
super(name, salary);
this.address = address;
}
@Override
public String getEmployee() {
System.out.println("Student의 getEmployee  호출됨");
return super.getEmployee()+"\t"+address;
}
}
class Manager extends Employee{
String depart;
public Manager (String name, int salary, String depart) {
super(name, salary);
this.depart=depart;
}
@Override
public String getEmployee() {
System.out.println("자식 getEmployee");
return super.getEmployee()+"\t"+depart;
}
public void b() {
// TODO Auto-generated method stub
System.out.println("manager b 함수");
}
}//Manager
public class Ex06_7 {
private void name() {
// Employee e = new Employee("a",100);
// Manager m = new Manager("A",10, "서울");
// System.out.println(m.getEmployee());
//다형성
Employee m1 = new Manager ("길동",100, "영업");//저장가능하지만 접근은 부모만 됨.
//m1.depart; 없는 함수라고 호출이 안됨
//m1.b(); error
//2. 자식 타입으로 형변환 후 사용
Manager m2= (Manager)m1;
System.out.println(m2.name);
System.out.println(m2.depart);
System.out.println(m2.salary);
m2.b();
System.out.println("============");
Employee m3 = new Student ("이순신", 10,"서울");
System.out.println(m3.name);
System.out.println(m3.salary);
System.out.println(((Student)m3).address); //유일변수 형변환 후 사용
System.out.println("=============");
Object o = new Manager("AA", 100, "영업");
Manager m4 = (Manager)o;
System.out.println(m4.getEmployee());
}
}

 

class Employee {
String name;
int salary;
public String getEmployee() {
System.out.println("부모 getEmployee");
return name +"\t"+ salary;
}//getemp
public Employee() {}
public Employee(String name, int salary) {
this.name=name;
this.salary=salary;
}
public void a () {
System.out.println("emp a 함수");
}
}//employee
class Student extends Employee {
String address;
public Student(String name, int salary, String address) {
super(name, salary);
this.address = address;
}
@Override
public String getEmployee() {
System.out.println("Student의 getEmployee  호출됨");
return super.getEmployee()+"\t"+address;
}
}
class Manager extends Employee{
String depart;
public Manager (String name, int salary, String depart) {
super(name, salary);
this.depart=depart;
}
@Override
public String getEmployee() {
System.out.println("자식 getEmployee");
return super.getEmployee()+"\t"+depart;
}
public void b() {
// TODO Auto-generated method stub
System.out.println("manager b 함수");
}
}//Manager
public class Ex06_7 {
private void name() {
// Employee e = new Employee("a",100);
// Manager m = new Manager("A",10, "서울");
// System.out.println(m.getEmployee());
//다형성
Employee m1 = new Manager ("길동",100, "영업");//저장가능하지만 접근은 부모만 됨.
//m1.depart; 없는 함수라고 호출이 안됨
//m1.b(); error
//2. 자식 타입으로 형변환 후 사용
Manager m2= (Manager)m1;
System.out.println(m2.name);
System.out.println(m2.depart);
System.out.println(m2.salary);
m2.b();
System.out.println("============");
Employee m3 = new Student ("이순신", 10,"서울");
System.out.println(m3.name);
System.out.println(m3.salary);
System.out.println(((Student)m3).address); //유일변수 형변환 후 사용
System.out.println("=============");
Object o = new Manager("AA", 100, "영업");
Manager m4 = (Manager)o;
System.out.println(m4.getEmployee());
}
}

 

public class TestEmployee {
public static void main(String[] args) {
// Manager m = new Manager("A01", "홍길동", "서울", "개발");
Manager m = new Manager ("A01", "홍길동", "100", "개발");
System.out.println(m.getEmployee());
Enginner eng = new Enginner ("B01", "유관순", "200", "자바");
System.out.println(eng.getEmployee());
System.out.println("==========");
//다형성 이용 Employee 변수에 m, eng 저장
Employee e = m;
System.out.println(e.getEmployee());
e =eng;
System.out.println(e.getEmployee());
//eng 이름, salary , skill 개별 출력
Enginner eng2 = ((Enginner)e);
System.out.println(eng2.name);
System.out.println(eng2.salary);
System.out.println(eng2.skill);
}
}

 

public class Test2 {
public void change(Employee e) {
}
public static void main(String[] args) {
Employee e = new Employee();
Manager m = new Manager();
Enginner en = new Enginner();
Test2 t = new Test2();
t.change(e);
t.change(m);
t.change(en); //다형성!!! 부모타입의 변수로 자식을 저장할 수 있음
// 따라서 다 가능
}
}

'Daily Codig Reminder' 카테고리의 다른 글

핵심클래스  (0) 2023.12.09
다형성  (1) 2023.12.07
메소드  (1) 2023.12.06
클래스(객체), 메소드  (1) 2023.12.05
배열  (0) 2023.12.04