import java.util.*;
class Person implements Comparable<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) {
count++;
this.name = name;
this.age = age;
}
public Person(Person other) {
this(other.name, other.age);
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
public void set(String name, int age) {
this.name = name;
this.age = age;
}
public void set(Person other) {
this.name = other.name;
this.age = other.age;
}
public Person clone() {
Person p = new Person(this.name, this.age);
return p;
}
@Override
public boolean equals(Object other) { // Object.equals overriding
if (other instanceof Person) {
Person that = (Person) other;
return that.canEqual(this) && this.getName().equals(that.getName()) && this.getAge() == that.getAge();
}
return false;
}
@Override
public int hashCode() {
return (41 * getName().hashCode() + getAge());
}
public boolean canEqual(Object other) {
return (other instanceof Person);
}
@Override
public String toString() { // Object.toString() overriding
return "Person Name: " + name + " Age: " + age;
}
public void print() { // instance methods
System.out.println("Person Name: " + name + " Age: " + age);
}
public static void printCount() { // static (class) methods
System.out.println("Person Count: " + count);
}
public static int getCount() { // static (class) methods
return count;
}
public static void setCount(int value) { // static (class) methods
count = value;
}
public int compareTo(Person other) {
String thisName = this.getName().toUpperCase();
String otherName = ((Person)other).getName().toUpperCase();
//ascending order
return thisName.compareTo(otherName);
//descending order
//return otherName.compareTo(thisName);
}
public static Comparator<Person> AgeComparator = new Comparator<Person>() {
public int compare(Person p1, Person p2) {
int age1 = p1.getAge();
int age2 = p2.getAge();
//ascending order
return age1 – age2;
//descending order
//return age2 – age1;
}
};
}
///////////////////////////////////////////////////////////////////////////////////////
class Student extends Person {
private static int count = 0; // static (class) field
protected int id;
public Student() {
id = 5208;
}
public Student(String name, int age, int id) {
super(name, age);
this.id = id;
count++;
}
public int getID() {
return id;
}
public void setID(int id) {
this.id = id;
}
public void set(String name, int age, int id) {
super.set(name, age);
this.id = id;
}
public void set(String name, int age) {
super.set(name, age);
}
public void set(Student other) {
this.set(other.name, other.age, other.id);
}
public void set(Person other) {
if (other instanceof Person)
super.set(other);
else
this.set((Student)other);
}
public Student clone() {
Student s = new Student(this.name, this.age, this.id);
return s;
}
@Override
public boolean equals(Object other) { // Object.equals overriding
if (other instanceof Student) {
Student that = (Student) other;
return that.canEqual(this) && this.getName().equals(that.getName()) && this.getAge() == that.getAge() && this.getID() == that.getID();
}
return false;
}
@Override
public int hashCode() {
return (41 * super.hashCode() + getID());
}
public boolean canEqual(Object other) {
return (other instanceof Student);
}
@Override
public String toString() { // Object.toString() overriding
return "Student Name: " + name + " Age: " + age + " ID: " + id;
}
public void superPrint() {
super.print();
}
public void print() { // Person.print() method overriding
System.out.println("Student Name: " + name + " Age: " + age + " ID: " + id);
}
public static void printCount() { // static (class) methods
System.out.println("Student Count: " + count);
}
public static int getCount() { // static (class) methods
return count;
}
public static void setCount(int value) { // static (class) methods
count = value;
}
public int compareTo(Student other) {
String thisName = this.getName().toUpperCase();
String otherName = ((Student)other).getName().toUpperCase();
//ascending order
return thisName.compareTo(otherName);
//descending order
//return otherName.compareTo(thisName);
}
public static Comparator<Student> AgeComparator = new Comparator<Student>() {
public int compare(Student p1, Student p2) {
int age1 = p1.getAge();
int age2 = p2.getAge();
//ascending order
return age1 – age2;
//descending order
//return age2 – age1;
}
};
public static Comparator<Student> IDComparator = new Comparator<Student>() {
public int compare(Student p1, Student p2) {
int id1 = p1.getID();
int id2 = p2.getID();
//ascending order
return id1 – id2;
//descending order
//return id2 – id1;
}
};
}
class PersonStudentTest {
public static void print(Object[] array) {
for(Object o : array) {
System.out.println(o);
}
}
public static void main(String[] args) {
///////////////////////////////////////////////////////////////////////
Student[] sList = new Student[3];
sList[0] = new Student("Kevin", 0, 222);
sList[1] = new Student("Jason", 1, 333);
sList[2] = new Student("John", 2, 111);
System.out.println("STUDENT SORT BY NAME (DEFAULT)!!!");
Arrays.sort(sList);
print(sList);
System.out.println("STUDENT SORT by AGE!!!");
Arrays.sort(sList, Student.AgeComparator);
print(sList);
System.out.println("STUDENT SORT by ID!!!");
Arrays.sort(sList, Student.IDComparator);
print(sList);
///////////////////////////////////////////////////////////////////////
Student[] sList2 = new Student[3];
sList2[0] = new Student("Kevin", 0, 222);
sList2[1] = new Student("Jason", 1, 333);
sList2[2] = new Student("John", 2, 111);
System.out.println("STUDENT SORT BY NAME (anonymous method)!!!");
Arrays.sort(sList2, new Comparator<Student>() {
public int compare(Student s1, Student s2) {
return s1.getName().toUpperCase().compareTo(s2.getName().toUpperCase());
}
});
print(sList2);
System.out.println("STUDENT SORT by AGE (anonymous method)!!!");
Arrays.sort(sList2, new Comparator<Student>() {
public int compare(Student s1, Student s2) {
return s1.getAge() – s2.getAge();
}
});
print(sList2);
System.out.println("STUDENT SORT by ID (anonymous method)!!!");
Arrays.sort(sList2, new Comparator<Student>() {
public int compare(Student s1, Student s2) {
return s1.getID() – s2.getID();
}
});
print(sList2);
///////////////////////////////////////////////////////////////////////
Student[] sList3 = sList2;
System.out.println("STUDENT SORT BY NAME (lambda)!!!");
Arrays.sort(sList3, (Student ss1, Student ss2) ->
ss1.getName().compareTo(ss2.getName())
);
Arrays.stream(sList3).forEach((s) -> System.out.println(s));
System.out.println("STUDENT SORT by AGE (lambda)!!!");
Arrays.sort(sList3, (Student ss1, Student ss2) ->
Integer.compare(ss1.getAge(), ss2.getAge())
);
Arrays.stream(sList3).forEach((s) -> System.out.println(s));
System.out.println("STUDENT SORT by ID (lambda)!!!");
Arrays.sort(sList3, (Student ss1, Student ss2) ->
Integer.compare(ss1.getID(), ss2.getID())
);
Arrays.stream(sList3).forEach((s) -> System.out.println(s));
///////////////////////////////////////////////////////////////////////
List<Student> sList4 = new ArrayList<Student>();
sList4.add(new Student("Kevin", 0, 222));
sList4.add(new Student("Jason", 1, 333));
sList4.add(new Student("John", 2, 111));
System.out.println("STUDENTLIST SORT BY NAME (lambda)!!!");
sList4.sort((Student ss1, Student ss2) ->
ss1.getName().compareTo(ss2.getName())
);
sList4.forEach((s) -> System.out.println(s));
System.out.println("STUDENTLIST SORT by AGE (lambda)!!!");
sList4.sort((Student ss1, Student ss2) ->
ss1.getAge() – ss2.getAge()
);
sList4.forEach((s) -> System.out.println(s));
System.out.println("STUDENTLIST SORT by ID (lambda)!!!");
sList4.sort((Student ss1, Student ss2) ->
ss1.getID() – ss2.getID()
);
sList4.forEach((s) -> System.out.println(s));
}
}
lecture6
lecture6
java1-lecture6
Midterm Extra +10
중간고사 문제를 다시 풀어본다. (Due 5/1 12:00pm)
중간고사 예제 + 본인 예제 프로그램 (문제 하나당 비슷한 예제) + 문제풀이 보고서 제출 (제출하면 +10점. 중간점수 없음)
Midterm_학번_이름.zip 압축한 후 e-learning으로 제출
보고서는 출력해서 수업시간에 제출한다.
Lab5
Lab5 프로젝트 디렉토리 안에 모든 파일(src/*.java & bin/*.class)와 보고서 (2~3장)를 넣고 Lab5_학번_이름.zip 압축한 후 e-learning으로 제출 (due by 5/7)
Lab5 Inheritance (추상클래스, 추상메소드 활용)
본인이 작성한 Lab4를 상속관계를 갖는 객체지향적인 프로그램으로 바꾼다.
java1-lab5
Midterm Answer
모두들 수고하셨습니다.
중간고사 답안지 입니다.
java19-1-midterm-answer
Abstract Class & Abstract Method & Polymorphism
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 vs Instance Initializer Block
Static Initializer Block
- class 로딩 시 호출
- instance variable이나 method에 접근 못함
- static variable 초기화에 사용
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
- 객체 생성시 호출
- super 생성자 이후에 실행하고, 생성자보다 먼저 실행
- instance variable이나 method에 접근 가능
- 모든 생성자의 공통 부분을 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
Person Student Class Instance vs Static Method Overriding
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
}
}
Car Sedan Class
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 CheckingAccount SavingAccount Class
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
}
}