Person.class
public class Person {
// 이름이 같은 greet메소드가 2개, 매개변수가 다름(같은땐 에러)
// 매개변수가 다르면 다른 메소드임
public void greet() {
System.out.println("헬로우!");
}
public void greet(String name) {
System.out.println("헬로우~" + name);
}
public void greet(int height) {
if(height > 185) {
System.out.println("키가 크군요!");
}
System.out.println("안녕~!");
}
public void greet(String name, int height) {
if(height > 185) {
System.out.println("키가 크군요!");
}
System.out.println("안녕~! " + name);
}
}
App.class
public class App {
public static void main(String[] args) {
// 메소드 오버로딩 : 메소드의 이름은 같지만 매개변수가 다를때
// 메소드는 이름과 매개변수가 모두 같아야 동일한 메소드임
Person p = new Person();
p.greet(); // 매개변수 없음
p.greet("펭수"); // 매개변수 문자열
p.greet(175); // 매개변수 정수형
p.greet("펭순이", 190); // 매개변수 문자열, 정수형
System.out.println(123); // 매개변수 정수
System.out.println(1.23); // 매개변수 실수
System.out.println("123"); // 매개변수 문자열
}
}
오버로딩 (overloading)
오버라이딩 (overriding)
이름이 클래스의 이름과 같고 리턴값이 없는 메서드.
default constructor 예제 1
package default_Constructor;
public class Person {
private String name; // 이름변수
private int age; // 나이변수
public Person() { // 나이이름을 둘 다 모를때 사용할 기본생성자
System.out.println("디폴트 생성자로 생성됨");
name = "모름";
age = 0;
}
public Person(String name) { // 생성자는 클래스 이름과 같고 리턴타입이 없음
// 이름만 알 때
System.out.println("새 person이 생성됨");
this.name = name;
age = 0;
// ㄴ앞의 name은 private name의 name, 뒤의 name은 public Person(String name) 의 name
}
public Person(String name, int age) { // 이름과 나이가 동시에 들어가는 메소드
// 둘 다 알 때
System.out.println("새 person이 생성됨");
this.name = name;
this.age = age;
}
@Override
public String toString() { // 객체의 정보를 출력한다
return "Person [이름= " + name + ", 나이= " + age + "]";
}
}
package default_Constructor;
public class App {
public static void main(String[] args) {
// 디폴트 생성자 : 생성자가 없을 때 적용됨, 생성자가 있으면 더 이상 적용안됨
Person p1 = new Person(); // p1은 기본생성자
System.out.println(p1); // toString메소드가 생략되어있음
Person p2 = new Person("펭수"); // 이름만 알 때
System.out.println(p2);
Person p3 = new Person("라이언", 5); // 둘 다 알때
System.out.println(p3);
}
}
default constructor 예제 2
class Data_1 {
int value;
}
class Data_2 {
int value;
Data_2 (int x) { // 매개변수가 있는 생성자를 만들었으므로 기본생성자는 적용되지 않음.
value = x;
}
}
public class Ex6_11 {
public static void main(String[] args) {
Data_1 d1 = new Data_1();
// Data_2 d2 = new Data_2(); // 컴파일 오류발생.
Data_2 d2 = new Data_2(10);
// 매개변수가 있는 생성자이므로 인스턴스(객체) 생성시에도 매개변수 반드시 필요.
}
}
package this_Constructor;
public class Person {
private String name;
private int age;
public Person() {
// this() 는 현재 클래스의 생성자를 가리킨다
this("익명", 0); // 이름과 나이 즉, 매개변수가 2개이므로 아래의 public Person(String name, int age)를 가리킨다
}
public Person(String name) { // 이름만 알 때
this(name, 0); // 마찬가지로 매개변수가 2개이므로 아래의 public Person(String name, int age)를 가리킨다
}
public Person(String name, int age) { // 둘 다 알 때
this.name = name;
this.age = age;
}
@Override
public String toString() { // 객체의 정보를 출력한다
return "Person [이름= " + name + ", 나이= " + age + "]";
}
}
package this_Constructor;
public class App {
public static void main(String[] args) {
// this() 생성자
Person p1 = new Person();
System.out.println(p1);
Person p2 = new Person("펭수");
System.out.println(p2);
Person p3 = new Person("라이언", 5);
System.out.println(p3);
}
}
객체 자신을 가리키는 참조변수.
현재클래스의 멤버변수를 지정할때 사용한다.
class InitTest {
// 인스턴스 변수 x 선언, y 선언 및 초기화
int x;
int y = x; // y를 선언하는데 초기화되지 않은 인스턴스 변수 x 사용가능
// 멤버변수는 초기화할 떄 초기화가 안 된 인스턴스 변수를 사용할 수 있다.
void method1() {
// 지역변수 i 선언, y 선언 및 초기화
int i;
// int j = i; // 에러 발생.
// 지역변수는 초기화를 시켜주지 않으면 사용할 수 없다.
}
}
Person.class
package super_constructor;
public class Person {
private String name;
public Person(String name) {
System.out.println("Person 생성자");
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String toString() {
return name;
}
}
Employee.class
package super_constructor;
public class Employee extends Person { // Person을 상속받음
public Employee() {
super("익명"); // 부모클래스의 생성자, 평소에는 생략되어있음
// ㄴ부모클래스의 생성자에 매개변수가 있기때문에 super에도 매개변수를 넣어줘야 오류가 안남
System.out.println("Employee 생성자");
} // 이렇게되면 부모클래스의 생성자(Person)를 먼저 실행항 후 Employee의 생성자가 실행됨
public Employee(String name) {
super(name);
System.out.println("Employee 생성자");
}
}
App.class
package super_constructor;
public class App {
public static void main(String[] args) {
// super() 생성자
Employee e1 = new Employee();
System.out.println(e1);
Employee e2 = new Employee("김펭수");
System.out.println(e2);
}
}
public class Ex7_2 {
public static void main(String[] args) {
Child c = new Child();
c.method();
}
}
class Parent {
int x = 10; // super.x
}
class Child extends Parent {
int x = 20; // this.x
void method() { // 부모클래스의 int x와 자식클래스int x의 이름이 같음
System.out.println("x = " + x);
System.out.println("this.x = " + this.x);
System.out.println("super.x = " + super.x);
}
}
App.class => 스윙 앱을 실행
public class App {
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> { // 프로그램의 안정성을 위해 권장하는 코드. 이 코드블럭안에 코드를 넣어준다.
new MainFrame("테스트 스윙 앱"); // 새 창 생성
});
}
}
MainFrame.class => 프레임을 생성
public class MainFrame extends JFrame{
public MainFrame(String title) {
super(title);
setLayout(new BorderLayout()); // 창에 컴포넌트(버튼들)을 붙이기 위함
// JPanel panel = new JPanel(); // JPanel 패널을 생성 => MainPanel으로 옮김
// panel.setBackground(Color.LIGHT_GRAY); // 패널 색 지정 => MainPanel으로 옮김
add(new MainPanel(), BorderLayout.CENTER); // 메인프레임에 붙이기 (중앙 가운데 위치)
setSize(600, 400); // 창 사이즈 설정
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // 창 닫으면 프로그램 종료
setVisible(true); // 창 보이게 설정변경
}
}
MainPanel.class => 패널을 생성
public class MainPanel extends JPanel {
private static final long serialVersionUID = 1L;
public MainPanel() {
setBackground(Color.lightGray); // 패널 색 설정
}
}
App.class
public class App {
public static void main(String[] args) {
// 추상 클래스
// GameObject obj = new GameObject(); // 추상 클래스는 객체를 만들 수 없다
GameObject[] objs = { new Player(), new Monster() };
for(GameObject ob : objs) {
System.out.println(ob); // toString()받은게 없으므로 주소값이 출력됨
ob.describe(); // 구현된 추상 메소드
// ㄴ추상 메소드로 GameObject에는 이름만 있고 자식클래스인 Monster와 Player에서 코드를 작성해줌
}
}
}
GameObject.class
public abstract class GameObject { // 추상클래스는 클래스앞에 abstract를 붙임
public abstract void describe();
// ㄴ 추상 메소드는 메소드 몸체(내부 코드)이 없다 => 상속받은 클래스에서 작성
}
Monster.class
public class Monster extends GameObject {
@Override
public void describe() {
System.out.println("몬스터입니다.");
// 부모클래스에서 미구현된 메서드를 자식클래스에서 구현
}
}
Player.class
// 추상 메소드를 상속받았을 경우 추상 메소드를 구현(만들어야)해야 함
public class Player extends GameObject {
@Override
public void describe() {
// 추상 클래스의 추상 메소드 describe()를 완성시킨다.
System.out.println("플레이어입니다.");
}
}
describe()메서드는 GameObject클래스의 추상 메서드임.
-출력결과-
abstract_Class.Player@6f75e721
=> System.out.println(new Player) 의 결과. 리턴값이 없으므로 가리키는 주소값이 출력된다.
플레이어입니다.
=> new Player.describe() 메서드의 실행결과.
abstract_Class.Monster@69222c14
=> System.out.println(new Monster) 의 결과. 리턴값이 없으므로 가리키는 주소값이 출력된다.
몬스터입니다.
=> new Monster.describe() 메서드의 실행결과.
~ 참고 ~
abstract 가 사용될 수 있는 곳: 클래스, 메서드
Describable.interface
public interface Describable { // 인터페이스 생성
String getDescription();
// 추상 메소드. 인터페이스 안의 모든 메소드는 public abstract를 생략한 주상 메소드임
}
Person.class
// 인터페이스를 구현(상속) 할 때 extends가 아닌 implement사용
// 상속한 클래스에서 추상 메소드 완성(구현)
public class Person implements Describable {
@Override
public String getDescription() {
return "사람 입니다.";
}
}
Computer.class
public class Computer implements Describable {
@Override
public String getDescription() {
return "컴퓨터 입니다.";
}
}
App.class
public class App {
public static void main(String[] args) {
// 인터페이스
// Describable ds = new Describable(); // 객체를 만들 수 없다
Describable[] objs = { new Person(), new Computer() }; // object는 모든 클래스의 부모 클래스라 주소값이 저장됨
for(Describable ob : objs) {
System.out.println(ob.getDescription());
}
}
}
DefaultRunnable.interface
// 인터페이스끼리 상속가능
public interface DefaultRunnable extends Runnable { // 기본적으로 존재하는 인터페이스인 Runnable을 상속받음
default void displayDetails() {
};
}
Machine.class
public class Machine implements DefaultRunnable {
@Override
public void run() { // DefaultRunnable 가 상속받은 Runnable 속에 있는 추상메소드라 이것도 구체화해줘야함
System.out.println("머신 러닝!");
}
@Override
public void displayDetails() {
System.out.println("표시할 디테일 없음");
}
}
App.class
public class App {
public static void main(String[] args) {
// 인터페이스는 인터페이스를 상속
DefaultRunnable m1 = new Machine(); // 인터페이스를 Machine이 구현했기때문에 객체를 만들 수 있음
m1.run();
m1.displayDetails();
}
}
-default메서드 예제-
DefaultRunnable.interface
// 인터페이스끼리 상속가능
public interface DefaultRunnable extends Runnable { // 기본적으로 존재하는 인터페이스인 Runnable을 상속받음
default void displayDetails() { // 디폴트 메소드는 구현가능
System.out.println("표시할 디테일 없 음");
};
}
Machine.class
public class Machine implements DefaultRunnable {
@Override
public void run() { // DefaultRunnable 가 상속받은 Runnable 속에 있는 추상메소드라 이것도 구체화해줘야함
System.out.println("머신 러닝!");
}
}
App.class
public class App {
public static void main(String[] args) {
// 인터페이스는 인터페이스를 상속
DefaultRunnable m1 = new Machine(); // 인터페이스를 Machine이 구현했기때문에 객체를 만들 수 있음
m1.run();
m1.displayDetails();
}
}
실행결과는 위의 예제와 동일.
Person.class
package multi_Inheritance;
public class Person implements Speaker, Greeter {
// Speaker, Greeter를 하나의 클래스에 모두 구현
@Override
public void greet() {
System.out.println("환영합니다.");
}
@Override
public void speak() {
System.out.println("나는 사람입니다.");
}
}
App.class
package multi_Inheritance;
interface Speaker {
void speak(); // 선언부만 있고 구현부가 없는 추상 메소드
}
interface Greeter {
void greet(); // 선언부만 있고 구현부가 없는 추상 메소드
}
public class App {
public static void main(String[] args) {
// 인터페이스는 다중 구현이 가능
Person p1 = new Person();
// Person은 인터페이스 Speaker와 Greeter를 모두 구현하고 있으므로
// greet()메서드와 speak()메서드를 모두 사용가능
p1.greet();
p1.speak();
Speaker p2 = new Person(); // Person이 구현한 인터페이스 Speaker로 선언
p2.speak();
// p2.greet(); // Speaker 인터페이스의 추상메소드만 사용가능, greet 사용불가
Greeter p3 = new Person(); // Person이 구현한 인터페이스 Greeter로 선언
p3.greet();
// p3.speak(); // Greeter 인터페이스의 추상메소드만 사용가능
}
}