Lab5 프로젝트 디렉토리 안에 모든 파일(src/*.java & bin/*.class)와 보고서 (2~3장)를 넣고 Lab5_학번_이름.zip 압축한 후 e-learning으로 제출 (due by 5/7)
Lab5 Inheritance (추상클래스, 추상메소드 활용)
본인이 작성한 Lab4를 상속관계를 갖는 객체지향적인 프로그램으로 바꾼다.
java1-lab5
Just another Kyoung Shin Park’s Lectures Sites site
Lab5 프로젝트 디렉토리 안에 모든 파일(src/*.java & bin/*.class)와 보고서 (2~3장)를 넣고 Lab5_학번_이름.zip 압축한 후 e-learning으로 제출 (due by 5/7)
Lab5 Inheritance (추상클래스, 추상메소드 활용)
본인이 작성한 Lab4를 상속관계를 갖는 객체지향적인 프로그램으로 바꾼다.
java1-lab5
모두들 수고하셨습니다.
중간고사 답안지 입니다.
java19-1-midterm-answer
Abstract Class (추상 클래스)는 하나 이상의 abstract method(추상메소드)를 가지거나, 추상메소드가 없지만 abstract으로 선언한 클래스. 추상클래스는 객체를 생성할 수 없다.
Abstract Method (추상 메소드)는 선언은 되어 있으나 구현 내용이 없는 메소드이다.
추상클래스를 상속받은 하위클래스는 반드시 추상 메소드를 재정의(method override) 구현해야한다.
Polymorphism (다형성)은 프로그램 실행(run-time execution)시 형(type)이 변화되는 객체.
다형성에 따라서, 클래스 상속관계(Inheritance)에서 메소드 재정의(Method overriding)된 것이 동적 바인딩(dynamic binding)으로 호출되었을 시, 해당 객체에 맞는 재정의된 메소드가 호출되는 것이다.
Shape 추상클래스 has-a ShapeType, ShapeColor, ShapeRect
Shape 추상클래스를 상속받은 Triangle, Rectangle, Square, Circle 클래스는 추상메소드인 area()를 반드시 구현해야한다.
https://www.cs.usfca.edu/~wolber/SoftwareDev/OO/abstractInterfacesIntro.htm
Static Initializer Block
public class StaticIntializerBlockTest {
private static int id = 5;
static {
if (id <10) id = 20;
else id = 100;
}
public static int getId() {
return id;
}
public static void print() {
System.out.println("StaticIntializerBlockTest.id=" + getId());
}
}
public class StaticInstanceInitializerBlockTest {
public static void main(String[] args) {
StaticIntializerBlockTest.print();
}
}
StaticIntializerBlockTest.id=20 // static block 이 호출되면서 20으로 셋팅
Instance Initializer Block
class InstanceInitializerBlockSuper {
public InstanceInitializerBlockSuper() {
System.out.println("InstanceInitializerBlockSuper");
}
}
public class InstanceInitializerBlockTest extends InstanceInitializerBlockSuper {
private int id = 5;
{
if (id <10) id = 20;
else id = 100;
}
public InstanceInitializerBlockTest() {
System.out.println("InstanceInitializerBlockTest.id=" + this.id);
}
public InstanceInitializerBlockTest(int id) {
System.out.println(“InstanceInitializerBlockTest.id=" + this.id);
this.id = id;
}
public int getId() {
return id;
}
public void print() {
System.out.println("StaticIntializerBlockTest.id=" + getId());
}
}
public class StaticInstanceInitializerBlockTest {
public static void main(String[] args) {
InstanceInitializerBlockTest i = new InstanceInitializerBlockTest();
i.print();
i = new InstanceInitializerBlockTest(30);
i.print();
}
}
InstanceInitializerBlockSuper // super 생성자 이후에 실행
InstanceInitializerBlockTest.id=20 // instance block 호출되면서 20으로 셋팅
id=20
InstanceInitializerBlockSuper // super 생성자 이후에 실행
InstanceInitializerBlockTest.id=20 // instance block 호출되면서 20으로 셋팅된후 this.id = id를 통해서 30으로 셋팅
id=30
https://stackoverflow.com/questions/12550135/static-block-vs-initializer-block-in-java
PersonStudent-MethodOverriding2
/// Person
class Person {
private static int count = 0; // static (class) field
protected String name; // instance field
protected int age; // instance field
public Person() {
//System.out.println("Person Constructor"); // this("", 0); error: call to this must be first statemenht in constructor
this("", 0);
}
public Person(String name, int age) {
this.name = name;
this.age = age;
count++;
}
public static void printCount() { // static (class) method
System.out.println("Person Count: " + count);
}
public static int getCount() { // static (class) method
return count;
}
public String toString() { // Object.toString() overriding
return "Person Name: " + name + " Age: " + age;
}
public void print() { // instance method
System.out.println("Person Name: " + name + " Age: " + age);
}
}
/// Student
class Student extends Person {
private static int scount = 0; // static (class) variables
protected int id;
public Student() {
this("", 0, 5208);
}
public Student(String name, int age, int id) {
super(name, age);
this.id = id;
scount++;
}
public static void printCount() { // static (class) method overriding
System.out.println("Student Count: " + scount);
}
public String toString() { // Object.toString() overriding
return "Student Name: " + name + " Age: " + age + " ID: " + id;
}
public void print() { // Person.print() method overriding
System.out.println("Student Name: " + name + " Age: " + age + " ID: " + id);
}
}
class PersonStudentTest {
public static void main(String[] args) {
Person p1 = new Student("K", 20, 2018); // upcasting 1번째 Student 객체 생성
p1.print(); // dynamic binding Student Name: K Age: 20 ID: 2018
p1.name = "JAVA";
p1.age = 1;
//p1.id = 2017; // cannnot call id because p1 is Person type
System.out.println(p1); // dynamic binding p1.toString() Student Name: JAVA Age: 1 ID: 1208
p1.printCount(); // p1 is Person, Person.printCount() Person.count=1
Person.printCount(); // Person.printCount() Person.count=1
Student.printCount(); // Student.printCount() Student.scount=1
System.out.println();
Student s1 = (Student)p1; // downcasting
s1.name = "JAVA2";
s1.age = 2;
s1.id = 2017; // can call id, because s1 is Student type
s1.print(); // Student Name: JAVA2 Age: 2 ID: 2017
s1.printCount(); // s1 is Student, Student.printCount() scount=1
Person.printCount(); // Person.printCount() count=1
Student.printCount(); // Student.printCount() scount=1
System.out.println();
Student s2 = new Student("S", 30, 1207); // 2번째 Student 객체 생성
s2.print(); // Student Name: S Age: 30 ID: 1217
s2.printCount(); // s2 is Student, Student.printCount() scount=2
Person.printCount(); // Person.printCount() count=2
Student.printCount(); // Student.printCount() count=2
System.out.println();
Person p2 = new Person("Park", 1); // 1번째 Person 객체 생성
System.out.println(p2); // Person Name: Park Age: 1
p2.printCount(); // p2 is Person, Person.printCount() count=3
Person.printCount(); // Person.printCount() count=3
Student.printCount(); // Student.printCount() scount=2
System.out.println();
Person p3 = new Person(); // 2번째 Person 객체 생성
System.out.println(p3); // Person Name: Age: 0
p3.printCount(); // p3 is Person, Person.printCount() count=4
Person.printCount(); // Person.printCount() count=4
Student.printCount(); // Student.printCount() scount=2
System.out.println();
System.out.println("Number of Person: " + Person.getCount()); // Person.getCount() count=4
}
}
CarSedan-PublicProtectedPrivate
public class Car {
// member field
private boolean disel; // private은 파생 클래스에서 사용하지 못함
protected boolean gasoline; // protected은 파생 클래스에서 사용 가능하나 외부(다른 패키지)에서는 호출하지 못함
protected int wheel = 4;
// constructor
protected Car() {
disel = true;
gasoline = true;
}
protected Car(int wheel) {
this.wheel = wheel;
disel = false;
gasoline = false;
}
// method
protected void move() {
if (disel) System.out.println("Disel Car");
System.out.println("Move wheel=" + wheel);
}
}
public class Sedan extends Car {
// member field
private boolean gasoline; // 파생 클래스에서 기반클래스에 멤버필드명이 같다면 default는 자신의 멤버부터 호출, 즉, this.gasoline 부터 사용
// constructor
public Sedan() { // 내부적으로 super() 호출, 즉 super.gasoline=true
gasoline = false;
}
public Sedan(int wheel) { // super(int wheel)를 호출, 즉 super.gasoline=false (protected 생성자는 파생클래스에서 호출 가능)
super(wheel);
gasoline = true;
}
// method
public void sedanMove() {
// base의 gasoline과 this의 gasoline을 구분해야하는 경우
if (super.gasoline) System.out.print("Gasoline Car ");
if (this.gasoline) System.out.print("Gasoline SedanCar ");
System.out.println("move wheel=" + wheel);
}
public static void main(String[] args) {
Car myCar = new Car(); // protected 생성자 같은 패키지 내에 사용가능.
myCar.move(); // protected 메소드 호출 가능
System.out.println("myCar wheel=" + myCar.wheel); // protected 필드 호출 가능
// 바퀴 4개 디젤 자동차
Sedan myCar1 = new Sedan(); // public 생성자 호출 가능
myCar1.move(); // protected 메소드 호출 가능
myCar1.sedanMove(); // public 메소드 호출가능
// 바퀴 6개 가솔린 자동차
Sedan myCar2 = new Sedan(6); // public 생성자 호출 가능
myCar2.move(); // protected 메소드 호출 가능
myCar2.sedanMove(); // public 메소드 호출가능
}
}
BankAccount-InstanceStatic – instance vs static member field & method
BankAccount
public class BankAccount {
protected String name; // instance field
protected double balance; // instance field
protected static double interestRate; // static field
public BankAccount() { // default constructor
this(1000, "JAVA17");
}
public BankAccount(String name, double balance) {
this.name = name;
this.balance = balance;
BankAccount.interestRate = 1.0;
}
public void deposit(double amount) { // instance method
balance += amount;
}
public void withdraw(double amount) { // instance method
balance -= amount;
}
public void transfer(double amount, BankAccount other) { // instance method
withdraw(amount);
other.deposit(amount);
}
public double getBalance() { // instance method
return balance + balance * interestRate * 0.01;
}
public void print() { // instance method
System.out.println(name + " balance=" + getBalance());
}
@Override // Object.toString() method override
public String toString() { // instance method
return name + " balance=" + getBalance();
}
public static void setInterestRate(double interestRate) { // static method
BankAccount.interestRate = interestRate;
}
}
public class CheckingAccount extends BankAccount {
private double overdraftLimit;
public CheckingAccount(String name, double balance, double overdraftLimit) {
super(name, balance);
interestRate = 2.0;
setOverdraftLimit(overdraftLimit);
}
public void setOverdraftLimit(double overdraftLimit) {
this.overdraftLimit = overdraftLimit;
}
public double getOverdraftLimit() {
return overdraftLimit;
}
@Override // BankAccount.withdraw(double amount) method override
public void withdraw(double amount) {
if(getBalance() - overdraftLimit < amount)
System.out.println("CheckingAccount::withdraw Cannot be withdrawn due to overdraftLimit");
else
super.withdraw(amount);
}
@Override // BankAccount.print() method override
public void print() {
System.out.println("CheckingAccount: " + name + " balance=" + getBalance());
}
}
public class SavingAccount extends BankAccount {
public SavingAccount(String name, double balance) {
super(name, balance);
interestRate = 5.0;
}
@Override // BankAccount.withdraw(double amount) method override
public void withdraw(double amount) {
if (getBalance() < amount)
System.out.println("SavingAccount::withdraw Amount is larger than current balance.");
else
super.withdraw(amount);
}
@Override // BankAccount.print() method override
public void print() {
System.out.println("SavingAccount: " + name + " balance=" + getBalance());
}
}
public class BankAccountTest {
public static void main(String[] args) {
BankAccount b1 = new BankAccount("P", 0);
b1.deposit(3000);
b1.withdraw(1000);
b1.print(); // P balance=2020.0
BankAccount b2 = new BankAccount("K", 0);
b1.print(); // K balance=0.0
System.out.println("transfer 1000 money from b1 to b2");
b1.transfer(1000, b2);
System.out.println("b1: " + b1); // b1: P balance=1010.0
System.out.println("b2: " + b2); // b2: K balance=1010.0
BankAccount c1 = new CheckingAccount("Checking1", 1000, 500);
BankAccount c2 = new CheckingAccount("Checking2", 1000, 500);
c1.withdraw(700); // CheckingAccount::withdraw Cannot be withdrawn due to overdraftLimit
c2.withdraw(800); // CheckingAccount::withdraw Cannot be withdrawn due to overdraftLimit
c1.print(); // CheckingAccount: Checking1 balance=1020.0
c2.print(); // CheckingAccount: Checking1 balance=1020.0
BankAccount s1 = new SavingAccount("Saving1", 1000);
s1.deposit(5000);
s1.withdraw(1000);
s1.print(); // SavingAccount: Saving1 balance=5250.0
BankAccount s2 = new SavingAccount("Saving2", 1000);
s2.withdraw(2000); // SavingAccount::withdraw Amount is larger than current balance.
s2.print(); // SavingAccount: Saving2 balance=1050.0
}
}
lecture5
java1-lecture5
중간고사
시험범위: 처음부터 – 배운데까지 (강의노트, 실습, 수업블로그)
주요내용: 기본문법, exception, enum, array, method, parameter passing, class, instance vs static, private/public/protected/default, inheritance, dynamic binding, abstract class, polymorphism, method overloading vs method overriding
일시 및 장소: 2019년 4월 24일 (수) 오전 9:00 – 10:30 (2공 105호)
Lab4 프로젝트 디렉토리 안에 모든 파일(src/*.java & bin/*.class)와 보고서 (2~3장)를 넣고 Lab4_학번_이름.zip 압축한 후 e-learning(http://lms.dankook.ac.kr/index.jsp)으로 제출 (due by 4/16)
Lab4 OOP (class 활용)
수업블로그에 클래스 OOP 참고하여, 본인이 작성한 Lab3를 객체지향적인 프로그램으로 바꾼다.
각 도형의 면적(area)과 둘레(perimeter)를 계산하는 클래스를 작성한다.
그리고 본인이 원하는 도형 클래스를 하나 더 추가 작성한다.
보고서는 출력해서 수업시작 전에 제출한다.
보고서의 내용은 기존 코드 분석과 이해한 내용 그리고 본인이 추가한 코드내용을 적는다.