생성자
-> opp.basic.constructor 패키지
: 생성자는 객체가 생성될 때 한 번!! 호출되는 메소드
▶ 클래스타입 변수 = new 생성자메소드()
----------------------
ㄴ클래스 내부
- new연산자가 생성자 메소드를 보고 메모리에 할당할 클래스가 무엇인지 파악하고 생성자메소드를 호출해야 하므로 지켜야 하는 규칙이 존재한다.
▶ 규칙
1) 생성자를 정의하지 않으면 컴파일러가 자동으로 매개변수가 없는 생성자를 추가한다.
=> 매개변수가 없는 생성자를 기본생성자라 한다.
2) 생성자메소드는 항상 반환값이 없기 때문에 리턴타입을 명시하지 않는다.(void조차 명시하지 않음)
3) 생성자메소드명은 클래스명과 대소문자까지 동일하게 정의한다.
4) 생성자메소드에 매개변수를 추가할 수 있다.
5) 생성자메소드도 오버로딩이 가능하다.
=> 일반메소드처럼 매개변수 갯수나 타입을 다르게 해서 여러 개 정의하여 쓸 수 있다.
6) 생성자를 정의하면 컴파일러는 기본생성자를 정의하지 않는다.
=> 기본생성자는 자바 프레임워크에서 기본으로 호툴되는 경우가 많으므로 작업할 내용이 없어도 기본생성자는 항상 정의해야 한다.
7) 모드 생성자의 천 번째 문장은 super()가 생략되어 있다.
8) 생성자가 오버로딩이 되어 있으므로 생성자 안에서 자신의 생성자를 호출할 수 있다.
▶ 문법
this(호출하고 싶은 생성자의 매개변수 스펙에 맞게 값을 전달)
=> 반드시 생성자를 호출하는 명령문은 생성자의 첫 번째 문장에 정의해야 한다.
=> this(.....)를 호출해서 사용하는 경우는 super(.....)를 같이 호출할 수 없다.
- 인스턴스가 생성될 때 호출되는 '인스턴스 초기화 메소드'이다.
- 인스턴스 변수(iv)를 초기화하기 편하게 하려고 사용한다.
- 기본생성자는 꼭 만들어줘야 한다.
- 모든 클래스는 반드시 생성자를 가져야 한다(한 개 이상).
- 멤버변수(클래스의 선언부에 정의된 변수)가 private상태이기 때문에 자손 클래스에서 상속된 조상 클래스의 멤버변수를 사용하지 못할 때에는 조상클래스의 생성자를 만들어서 'super(멤버변수)'의 형태로 사용해줘야 한다.
오버라이딩
- 조상클래스로부터 상속받은 메소드의 내용을 변경하는 것.
- 선언부는 조상의 선언부와 완전히 일치해야 함.
- 접근제어자는 조상클래스의 메소드보다 좁은 범위로 변경할 수 없다.
- 조상클래스의 메소드보다 많은 수의 예외를 선언할 수 없다.
- 조건
1) 이름이 같아야 한다.
2) 매개변수가 같아야 한다.
3) 반환타입이 같아야 한다.
< 예제 >
public class BirdPlay {
public static void main(String s[]){
Duck duck = new Duck();
duck.setName("꽥꽥이");
duck.fly();
duck.sing();
System.out.println(duck.toString());
Sparrow sparrow = new Sparrow();
sparrow.setName("짹짹");
sparrow.fly();
sparrow.sing();
System.out.println(sparrow.toString());
//= String result = sparrow.toString();
// System.out.println(result);
}
}
: 위의 기준을 만족하기 위한 클래스, 생성자 작성하기
1. 필요한 멤버변수 선언
2. get, set 메소드 정의
2. 객체가 만들어진 Duck, Sparrow 클래스 작성
3. 각 클래스에 fly(), sing(), toString() 메소드 정의
public class Duck {
String name;
int legs;
int length;
public void fly() {
System.out.println("오리("+name+")는 날지 않습니다.");
}
public void sing() {
System.out.println("오리("+name+")가 소리내어 웁니다.");
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String toString() {
String result = "오리의 이름은 "+name+" 입니다.";
return result;
}
}
public class Sparrow {
String name;
int legs;
int length;
public void fly() {
System.out.println("참새("+name+")가 날아다닙니다.");
}
public void sing() {
System.out.println("참새("+name+")가 소리내어 웁니다.");
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String toString() {
String result = "참새의 이름은 "+name+" 입니다.";
return result;
}
}
상속
: 기존의 클래스를 재사용하여 새로운 클래스를 작성하는 것
class child extends parent {
}
- 자손 클래스에 새로운 코드가 추가되어도 조상 클래스는 아무런 영향을 받지 않는다.
- 생성자와 초기화블럭은 상속되지 않는다. 멤버만 상속된다.
- 자손 클래스의 멤버 개수는 조상 클래스보다 항상 같거나 많다.
상속을 들어가기 전에 확실하게 알아야 할 개념정리
* 객체
: 값을 저장하기 위한 변수 묶음
* 인스턴스
: 클래스로부터 객체를 만드는 과정을 '인스턴스화'라고 하며, 어떤 클래스로부터 만들어진 객체를 인스턴스라고 한다.
* 생성자
: 생성자는 인스턴스가 생성될 때 호출되는 '인스턴스 초기화 메소드'이다.
<예제>
public class Prob2 {
public static void main(String[] args){
Drink coffee = new Drink("커피",1500,4);
Drink tea = new Drink("녹차",1100,7);
Alcohol wine = new Alcohol("와인", 5000, 3, 15.1);
System.out.println("***** 매 출 전 표 ***** ");
coffee.printTitle();
coffee.printData();
tea.printData();
System.out.println();
wine.printTitle();
wine.printData();
int sum = coffee.getTotalPrice()
+ tea.getTotalPrice()
+ wine.getTotalPrice();
System.out.println();
System.out.println("*** 총금액 " + sum + "원 ***");
}
}
위의 조건을 만족하는 상속 클래스 작성하기
public class Drink {
private String name;//삼풍명
private int price; //단가
private int count;//수량
public Drink() {
}
public Drink(String name, int price, int count) {
this.name = name;
this.price = price;
this.count = count;
}
public int getTotalPrice() { //금액(단가*수량)
int sum = 0;
sum = (price*count);
return sum;
}
public void setTotalPrice(int price) {
this.price = price;
}
public void printTitle() {//타이틀을 출력
System.out.println("상품명 단가 수량 금액");
}
public void printData() {//상품의 정보를 출력
System.out.println(name+" "+price+" "+count+" "+getTotalPrice());
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getPrice() {
return price;
}
public void setPrice(int price) {
this.price = price;
}
public int getCount() {
return count;
}
public void setCount(int count) {
this.count = count;
}
}
public class Alcohol extends Drink{
private double alcper;
public Alcohol() {
}
public Alcohol(String name, int price, int count, double alcper) {
super(name, price, count);
this.alcper = alcper;
}
public double getAlcper() {
return alcper;
}
public void printTitle() {//타이틀을 출력
System.out.println("삼풍명(도수[%]) 단가 수량 금액");
}
public void printData() { // private이기 때문에 메소드로 접근해야 함. Drink클래스에서도 get메소드 만들어주기
System.out.println(getName()+"("+alcper+")"+" "+getPrice()+" "+getCount()+" "+getTotalPrice());
}
}
* printTitle(), printData() 메소드 오버라이딩하기(재정의하기).
'JAVA' 카테고리의 다른 글
2022-10-18 객체지향언어 - 인터페이스, 예외처리방법 1. try-catch / 2. 예외선언하기(throw, throws) (0) | 2022.10.22 |
---|---|
2022-10-17 객체지향언어 - 다형성. 추상클래스, 제어자 fanal (0) | 2022.10.18 |
2022-10-13 객체지향언어 - 배열, 클래스 메소드(static메소드)와 인스턴스 메소드 (0) | 2022.10.13 |
2022-10-11~12 객체지향언어 - 메소드 작성방법, 호출, 오버로딩, 캡슐화, 생성자 +활용 (0) | 2022.10.12 |
2022-10-07 if, for, while,/do~while, break/continue, Frame, 객체지향언어, 지역변수/전역변수 (0) | 2022.10.08 |
댓글