Java 7일차 : 생성자, 상속

Call by Value

  • 값이 전달되는것 ( 기본형 - int, double, String … )

Call by Reference

  • 주소가 전달되는것 (클래스, 배열)

예시

package test.day0411;

class Test1{
  String name = "lee";
  String addr = "seoul";
}

public class CallByEx1 {
  public static void changeInt(int n) {
    n = n*2;
  }
  public static void changeArr(int arr[]) {
    arr[0] = 100;
    //배열은 객체로 인식되므로 주소값이 전달됨. 이곳에서 변경하면 호출한곳의 배열값도 같이 변경됨.
  }
  public static void changeTest(Test1 t1) {
    t1. name ="kim";
  }
  public static void changeString(String str) {
    str += "!!!!!";
  }
  public static void main(String []arg) {
    //call by value - 기본형일 
    int x = 20;
    System.out.println(x);
    changeInt(x); //기본형은 값만 전달된다. 
    System.out.println("changed? : " + x); //값만 전달된거지 주소가 전달된게 아니므로 x는 바뀌지 않았다.
    //call by reference - 배열일 때 
    int arr[] = {0, 1, 2};
    changeArr(arr);
    System.out.println("changed? : " + arr[0]); //값이 변했다! 
    //call by reference - 클래스일 때 
    Test1 t1 = new Test1();
    changeTest(t1);
    System.out.println("changed?: " + t1.name);

    //문자열일 때 - call by value
    String str = "Hello";
    changeString(str);
    System.out.println("changed?: " + str);
  }
}

생성자

  • 객체 생성시 자동호출되는 메서드
  • 일반 메서드와의 차이점 : 리턴형이 없다
  • 메서드명은 반드시 클래스명과 같아야한다(대소문자까지!)
  • 오버로딩이 가능하다 => 즉 여러개의 생성자를 만들 수 있다
  • 생성자가 없을 경우 기본 생성자로 생성이 가능하다.
  • 생성자에서는 주로 멤버변수의 초기화를 담당한다.
  • 같은 생성자끼리의 호출은 this()로 한다. (this.와는 다르다)
  • 만약 인자를 받는 생성자라면, 클래스 생성시 new 클래스명(인자값); 으로 주면 된다.

생성자 생성시 주의점

  1. class와 접근 지정자 통일
  2. 반환 유형은 적지 않는다
package test.day0411;

class Apple{

  Apple(){
    System.out.println("디폴트 생성자 호출");
  }
}

class Banana{

  Banana(String str){
    System.out.println("Banana의 생성자: " + str);
  }
}

class Orange{
  //생성자는 오버로딩이 가능하다 => 인자별로 실행된다 
  Orange(){
    System.out.println("오렌지 디폴트 생성자 호출");
  }

  Orange(String str){
    System.out.println("오랜지 두번째 생성자 호출: " + str);
  }

  Orange(int n){
    this(); //기본 디폴트 생성자 호출, 반드시 첫줄에 줘야한다 

    System.out.println("오랜지 세번째 생성자 호출: " + n);
  }

  Orange(int a, int b){
    System.out.println("오랜지 네번째 생성자 호출: " + a + ", " + b);
  }
}

public class ConstrEx2 {

  public static void main(String[] args) {
    // TODO Auto-generated method stub
    Apple ap = new Apple();
    Banana bn = new Banana("디폴트생성자메시지");
    Orange or1 = new Orange();
    Orange or2 = new Orange("얌얌");
    Orange or3 = new Orange(33);
    Orange or4 = new Orange(1,2);
  }
}
package test.day0411;

class Person{
  String name;
  int age;
  //생성자 overloading, this() 활용하기  
  Person(){
    this("아무개", 0); //4번째 생성자 호출됨 
  }
  Person(String name){
    this(name, 0);
  }
  Person(int age){
    this("아무개", age);
  }
  Person(String name, int age){
    this.name = name;
    this.age = age;
  }
  //이렇게 주면 오브젝트 생성시 인자를 어떻게 줘도 name과 age가 들어간다 
}

public class ConstrEx3 {

  public static void main(String[] args) {
    // TODO Auto-generated method stub
    Person p1 = new Person();
    Person p2 = new Person("김기동");
    Person p3 = new Person(99);
    Person p4 = new Person("홍길동",99);
    System.out.println(p1.name + p1.age);
    System.out.println(p2.name + p2.age);
    System.out.println(p3.name + p3.age);
    System.out.println(p4.name + p4.age);

  }
}

실습문제

  1. 다른 패키지에서 생성자를 포함한 클래스를 만들어보자

    접근지정자에 따라 어떤 오류가 나는지 확인한다

    패키지가 다를 경우 생성자 앞에 반드시 public이 있어야 접근 가능

    만약 protected나 private으로 만들 경우에는 객체의 인스턴스를 얻을 수 있는 static메소드를 구현해야 한다.

  2. Calendar클래스를 이용해 현재 시간을 출력해보자

package exam;

public class Test {
  private Test() {
    System.out.println("private생성자");
  }
  public void writeMsg() {
    System.out.println("안녕하세요.");
  }
  //생성자 대신 인스턴스를 반환해주는 메서드 
  public static Test getInstance() {
    return new Test(); 
  }
}
package test.day0411;
import java.util.Calendar;
import exam.Test;

public class ConstrEx4 {

  public static void main(String[] args) {
    // TODO Auto-generated method stub
    // Test t1 = new Test(); 생성자가 private이라 타 패키지에서는 생성 자체가 안됨 
    Test t1 = Test.getInstance();
    t1.writeMsg();

    //calendar클래스 역시 new로 생성이 안되는 private생성자를 갖는다. 따라서 아래처럼 생성해야 한다.
    Calendar cd = Calendar.getInstance();
    System.out.println(cd.getTime());
  }
}

클래스 배열

package test.day0411;

class Info{
  String name;
  char blood;
  int age;
  Info(){
    this("아무개",'X',99);
  }
  Info(String name, char blood){
    this(name,blood,99);
  }
  Info(String name, char blood, int age){
    this.name = name;
    this.blood = blood;
    this.age = age;
  }
  public static void showTitle() {
    System.out.println("상품명\t혈액형\t나이");
    System.out.println("---------------------");
  }
  public void showInfo() {
    System.out.println(name + "님\t" + blood +"형\t" + age + "세");
  }
}

public class ClassArrayEx6 {

  public static void main(String[] args) {
    // TODO Auto-generated method stub
    Info my[] = {
      new Info(),
      new Info("김기동",'A'),
      new Info("이기동", 'B', 20)
    };
    Info.showTitle();
    for(int i = 0 ; i < my.length ; i++) {
      my[i].showInfo();
    }
  }
}

상속

  • 부모가 가진 멤버들을 물려받는것을 말한다.

  • 이때 private으로 지정된 속성이나 메소드는 상속되지 않는다.
  • 자바에서는 상속이 하나의 클래스로부터만 가능하다. 즉, 다중상속은 지원하지 않는다.
  • 형식
class 자식클래스명 extends 부모클래스명{
...
}
  • 같은 패키지인 경우는 private을 제외한 모든 속성과 메소드를 상속받는다

  • 다른 패키지인 경우 public, protected만 상속을 받는다

오버라이드 메서드

  • 부모가 가진 메서드를 재구현한 것을 오버라이드라고 한다. (미완성의 메서드를 완성할 목적으로 주로 사용한다)
  • 형식
부모클래스명 변수명 = new 자식클래스명();
  • 이때 만들어진 인스턴스는 부모가 가진 메소드만 호출이 가능하다. 자식만 갖고 있는 메소드는 호출이 불가능함

  • 만일 호출이 가능하게 만들고 싶다면 부모에 같은 메서드를 만들어야 한다. (부모에선 내용은 없어도 됨. 선언만 해줘도 ok)

예시

package test.day0411;

class SuperObj{
  int n = 99;
  public void disp1() {
    System.out.println("public method");
  }
  protected void disp2() {
    System.out.println("protected method");
  }
  void disp3() {
    System.out.println("default method");
  }
  private void disp4() {
    System.out.println("private method");
  }
}

//서브클래스 생성 
class SubObj extends SuperObj{
  SubObj(){
    this.n = 100;
  }
  public void write() {
    System.out.println("This is subObj!" + this.n);
  }
}

public class InheriEx8 {

  public static void main(String[] args) {
    // TODO Auto-generated method stub
    SubObj sb = new SubObj();
    sb.disp1();
    sb.disp2();
    sb.disp3();
    //sb.disp4();
    sb.write();
    //다형성처리 - 선언은 부모클래스, 생성은 sub클래스인 경우 
    SuperObj super1 = new SubObj();
    //이경우 부모가 가진건 private제외하고 다 되지만, 자식이 가진 메서드는 호출이 안됨 
    //super1.write();
  }
}
package test.day0411;

class Number{
  String str = "일을하자!!";
  public void hello() {
    System.out.println("super-hello");
  }
  public void play() {
    //여기는 비어도 괜찮다. 선언만...오버라이딩 선언시 어차피 이건 실행안됨ㅇㅇ 
    System.out.println("여긴 내가 할게 ");
  }
}

class One extends Number{
  @Override
  public void play() {
    super.play(); //부모가 먼저 처리할 일 
    System.out.println(super.str + "산불을 끈다."); //부모에서 선언된 메서드이므로, 오버라이딩시 실행 가
  }
}

class Two extends Number{
  @Override
  public void play() {
    System.out.println(super.str + "집을 짓는다.");
  }
}

public class InheriEx9 {

  public static void main(String[] args) {
    // TODO Auto-generated method stub
    Number num = new One();
    num.hello();
    num.play();//자식의 play가 호출됨.
    num = new Two();
    num.play();
  }
}
package test.day0411;

import java.util.Scanner;

class 소장{
  public void process() {
    System.out.println("나는 소장!");
  }
}
class 도배팀 extends 소장{
  @Override
  public void process() {
    // TODO Auto-generated method stub
    super.process();
    System.out.println("도배를해요!");
  }
}

class 전선팀 extends 소장{
  @Override
  public void process() {
    // TODO Auto-generated method stub
    super.process();
    System.out.println("전선을깔자!");
  }
}

class 설비팀 extends 소장{
  @Override
  public void process() {
    // TODO Auto-generated method stub
    super.process();
    System.out.println("설비팀입니당");
  }
}

public class InheritEx10 {

  public static void main(String[] args) {
    // TODO Auto-generated method stub
    Scanner sc = new Scanner(System.in);
    System.out.println("입력하세요");
    int n = sc.nextInt();
    소장 s = new 소장();
    switch(n) {
      case 1:
        s = new 도배팀();
        break;
      case 2:
        s = new 전선팀();
        break;
      case 3:
        s = new 설비팀();
        break;
    }
    s.process();
  }
}

실습문제

클래스명 Sawon

멤버변수 : static int cnt;//생성되는 인원수, String name; , int pay; int family;

생성자 : 이름,급여,가족수를 전달받을수 있는 생성자 1개

멤버메소드 :

​ getFamilySudang() : 가족수 *80000 원을 리턴받는 메소드

​ write() : 이름,급여,가족수,가족수당,총급여 출력

​ showTitle() : static 메소드 : 제목 나오도록

[ 메인]

총 몇명의 직원을 입력할까요? 3

1번 직원

​ 이름:

​ 급여

​ 가족수 입력받음

=> 인원수만큼

[출력]

총 입력값 : cnt 출력하기

이름 급여 가족수 가족수당 총급여

-—————————————————–

영희 670000 3 240000 ……….

**클래스 배열을 이용하세요

package test.day0411;

import java.util.Scanner;

class Sawon{
  static int cnt = 0;
  String name;
  int pay;
  int family;

  Sawon(){
  }

  Sawon(String name, int pay, int family){
    this.name = name;
    this.pay = pay;
    this.family = family;
  }

  int getFamily() {
    return family*80000;
  }

  void write() {
    System.out.println(name + "\t" + pay + "\t" + family +"\t"+ this.getFamily() + "\t" + (pay+this.getFamily()));
  }

  static void showTitle() {
    System.out.println("이름 \t 급여 \t 가족수 \t 가족수당 \t 총급여");
    System.out.println("=======================================");
  }
}

public class TestEx11 {

  public static void main(String[] args) {
    // TODO Auto-generated method stub
    Scanner sc = new Scanner(System.in);
    int empNum = 0;
    System.out.println("총 몇명의 직원을 입력할까요?");
    empNum = sc.nextInt();
    Sawon sw[] = new Sawon[empNum];


    for(int i = 0 ; i < empNum ; i++ ) {

      String name;
      int pay;
      int family;
      sc.nextLine();

      System.out.print("이름>");
      name = sc.nextLine();
      System.out.print("급여>");
      pay = sc.nextInt();
      System.out.println("가족수>");
      family = sc.nextInt();

      sw[i] = new Sawon(name,pay,family);
    }

    for(int i = 0 ; i < empNum ; i++) {
      if(i==0)
        Sawon.showTitle();
      sw[i].write();
    }
  }
}

Categories:

Updated:

Comments