Before we started today's lesson we did a short excercise based on what we have learn so far in class.
We created a small program using different classes that prints out the interaction between an apple buyer and seller.
Here is the AppleSeller class:
package apple;
public class AppleSeller {
final static int APPLE_PRICE = 1000; // we used final static to turn the price of the apples into a constant
// 사과 수
int appleCount = 50;
// 보유 금액
int sellerMoney;
// 사과를 파는 행동
public int saleApple(int money) { < this is a method we created to output money received, apples that we can sell and how much we earned.
int num = money / APPLE_PRICE;
sellerMoney += money;
appleCount -= num;
return num;
}
// 자신의 정보를 말하는 행동
public void tellSeller() { < this is the method we use to alert how many apples there are left and the earnings so far
System.out.printf("남은 사과는 %d개입니다. \n", appleCount);
System.out.printf("수익은 %d입니다. \n", sellerMoney);
}
}
Here is the customer:
package apple;
public class AppleBuyer {
// 돈
int buyerMoney = 6000;
// 사과 개수
int appleCount;
we actually called the saleApple method from the AppleSeller class by first calling the instance, then applying it directly into our buyApple method itself.
public void buyApple(AppleSeller seller, int money) {
appleCount += seller.saleApple(money);
buyerMoney -= money;
}
// 결과 말하기
public void tellBuyer() {
System.out.printf("남은 돈은 %d입니다, 구매한 사과는 %d개 입니다.\n", buyerMoney, appleCount);
}
}
then we called all the appropriate methods in our main thread:
public class AppleMain {
public static void main(String[] args) {
AppleSeller appleSeller = new AppleSeller();
AppleBuyer appleBuyer = new AppleBuyer();
//메소드
appleBuyer.buyApple(appleSeller, 3000);
//결과 메소드 호출
appleSeller.tellSeller();
appleBuyer.tellBuyer();
}
}
The other four pillars of OOP: encapsulation, Inheritance, Abstraction, Polymorphism
last week we focused quite a bit on encapsulation, touching upon access modifiers and static methods. Today we focused more on getting to know about the other three.
Inheritance
If there are two members set as a Super Class (parent) and Sub Class (child), inheritance is the act of the child having free utilisation of the parent's members (except for very specific instances,but more on that later).
As we've seen before, it looks something like this on our initial set-up:
sub class name extends super class {}
The great thing about inheritance is that it reduces the time to maintain and edit certain parts of the program using inheritance as alterations of super classes also effect the sub class.
HOWEVER!! there are some rules to inheritance:
1.) You can have members trickle down from parent to multiple children however the flow cannot be reversed.
For example there is class Human that has class Animal as it's super class. Then there is class AAA that has Human as it's super class!!

2.) A child can only have one parent!! only one super class name after the extend keyword.
3.) Sub classes cannot inherit anything that has the private access modifier attached. (as well as static because static has no instances, it's activated by calling the parent class directly!)
https://www.prepbytes.com/blog/java/can-we-override-static-method-in-java/
When forming a sub class in Java, the parent class is always formed first, before the child class.
The highest class of all is the object class but this is usually omitted, think of window in terms of javascript :3
object > super class > sub class
We use the super( ) keyword to call the default constructor for the parent class!
public Human(String name) {
super(); // 부모의 생성자 호출후 자식 생성자가 이용
this.name = name;
};this will then let us use the this keyword :3
Something to keep in mind while using super ():
public Human(String name) {
super(); // 부모의 생성자 호출후 자식 생성자가 이용
this.name = name;
};
class AAA extends Human{
public AAA(String name) {
super(name);
}
}
when inheriting from a super class that has a parameter it is crucial that we enter said parameter in our super() keyword as well, like above. If the parent class has no parameters then we leave it blank but if it's not we write it to avoid errors.
Also it only moves one level, so if the super class has another super that has a parameter, we don't need to include that in our own methods.
Override, Overriding
This is something we use often in OOP. It basically means that we are redefining the members that we have inherited from our parent class to make it our own. Like always there are some rules to follow:
1.) The method format must be same as the one that was inherited.
2.) The access modifier should be the same or wider than of the super class. (if it's protected, it should be either protected or public)
3.) The redefined method's original super class method will be hidden so there is no way to call it directly.
4.) to call said hidden method you will have to use the super keyword to call the parent class itself.
Real life example 1:
Super class: Animal
public void sleep() {
System.out.println(name + "이 잠을 잡니다.");
};
sub class: Human
we summon this method by ctrl + space and selecting it and it will appear with the @Override annotation <3
@Override < this is called annotation
public void sleep() {
// super.sleep();
System.out.println("침대에서 잡니다");
}
Real life example 2: overriding to only print the first 6 digits of ssn
Human:
public void myInfo() {
System.out.printf("내 이름은 %s \n", name);
System.out.printf("내 나이는 %d \n", age);
System.out.printf("내 ssn은 %s \n", ssn);
}
New Human:
public class NewHuman extends Human {
public NewHuman(String name, int age, String ssn) {
super(name, age, ssn);
}
@Override
public void myInfo() {
System.out.printf("내 이름은 %s \n", name);
System.out.printf("내 나이는 %d \n", age);
System.out.printf("내 ssn은 %s \n", ssn.substring(0, 6));
}
}
As you may have guessed, when overriding we need to define all of the original members in the method, we cannot just change one part, we need to reset all values.
A useful tip!
when creating a class, we can set the super class right away by browsing and editing the super class menu.

Abstraction
Abstraction is another part of OOP in Java. In a nutshell, abstraction means a class that doesn't need to be turned into an instance.
When Java processes programs through OOP, sometimes it can use this concept to a class to prevent it from creating its own instance. This is usually the case when we want to preserve a class that is super important! (the highest super class)
Here are some rules to declaring an abstract class:
1.) There should always be at least one method present that is abstract. (abstract methods don't have brackets { })
how to declare an abstract method:
-apply the abstract keyword by the method. Make sure to declare it before the return type and add a semi-colon behind the parameter to mark the end of the declaration:
public abstract void sleep();
-Once there is an abstract method present, add the keyword infront of the class name as well.
2.) Abstract classes cannot produce their own instances. However they can declare constructors, methods and fields. It can also be inherited and polymorphed as they can exist as super types.
3.) If you wish to create an abstract class without an abstract method, you can by simply adding the abstract keyword.
abstract class Apple{
int age;
String name;
public abstract void sleep();
}
Abstract classes exist solely for inheritance
In order to inherit an abstract class, the @Override annotation is always used as they don't have commands or parameters of their own to abide.
package abstraction;
public abstract class Animal {
int age;
String name;
public abstract void sleep();
public abstract void eat();
}
public class Human extends Animal {
@Override
public void sleep() {
// TODO Auto-generated method stub
}
@Override
public void eat() {
// TODO Auto-generated method stub
}
}
Utilising arrays, for loops with abstraction and inheritance:
here is a great example of how it can all come together :3
package avengers;
public abstract class Hero {
String name;
int age;
public abstract void attack();
public abstract void defense();
public abstract void sleep();
}
pretend there are other classes that inherit the hero class but has their own attack( ) methods.
package avengers;
public class Avengers {
public static void main(String[] args) {
Hero[] h2 = new Hero[5];
h2[0] = hulk;
h2[1] = ironman;
h2[2] = captainamerica;
h2[3] = blackwidow;
h2[4] = hawkeye;
for (Hero hero : h2) {
hero.attack();
}
}
}
after assigning each hero to the h2 hero class, we can use the forEach( ) statement to call the attack methods of each hero one by one.
Polymorphism
Polymorphism in a nutshell is the concept where members transform themselves to suit the needs of each occasion.
There are two types of polymorphism: Compile-time and Runtime.
Compile-time Polymorphism
also known as static polymorphism: achieved by Overloading (function or operator)
We are talking about overloading from before where different functions share the same names but have different paramenters!! It is actually a type of polymorphism( so cool!!)
One of the key things to consider for polymorphism is reference variables!
For the sake of polymorphism Java let's the parent class create reference variables using child class type's instances.
However the reference variables being created must consider that the size of the member is the same or smaller than those of the actual instance's.
class Parent { ... }
class Child extends Parent { ... }
...
Parent pa = new Parent(); // allowed
Child ch = new Child(); // allowed
Parent pc = new Child(); // allowed
Child cp = new Parent(); // error
If we see the example above, we can see that containing a new Parent() within variable cp will result in an error.
We cannot hold parents within childs.
Therefore it is really useful to use the instanceof operator to figure out the instance type the reference variable is referncing. It returns a boolean value, if the instance type is the class type passed on the right is true, else false.
you can use it like this: reference variable instanceof class name
class Parent { }
class Child extends Parent { }
class Brother extends Parent { }
public class Polymorphism01 {
public static void main(String[] args) {
Parent p = new Parent();
System.out.println(p instanceof Object); // true
System.out.println(p instanceof Parent); // true
System.out.println(p instanceof Child); // false
System.out.println();
Parent c = new Child();
System.out.println(c instanceof Object); // true
System.out.println(c instanceof Parent); // true
System.out.println(c instanceof Child); // true
}
}
Runtime polymorphism
also known as Dynamic Method Dispatch. A process in which a call to the overridden method is resolved at Runtime and is achieved by Overriding. It is when a child class has a new definition or command for one of the member functions inherited from the parent class. The changed function is said to be overridden.
'JAVA' 카테고리의 다른 글
| Importing data into JSP, Java Collection Framework: Lists (0) | 2024.07.03 |
|---|---|
| Interface and Exceptions (0) | 2024.07.02 |
| OOP continued: Static, access modifiers, Singleton pattern (0) | 2024.06.29 |
| Object Oriented Programming: Fields, Constructors and methods (0) | 2024.06.27 |
| JAVA: Deep and Shallow Copying, String Class Methods (0) | 2024.06.26 |