iTranslated by AI
Understanding Object-Oriented Programming: A Supplementary Guide
The following is a supplement to the parts of What Object-Oriented Programming Is, Or The Single Thing You Should Be Careful About in Programming that could not be detailed due to space constraints.
Interface
An interface is a type of abstracted class that defines only "what functions it should have."
For example, suppose you decide to manage data for coworkers in addition to friends. If you feel that both should have a contact output method, you should create an interface like the following:
public interface Human {
/** Output contact information */
public void outputContact();
}
This means that "a Human should have a contact output method." Since an interface only defines what methods should exist, the implementation is done in the class that inherits (implements) it using the implements keyword.
public class Friend implements Human{
...// (Omitted)
@Override
public void outputContact(){
System.out.println(name);
System.out.println("Phone number: "+phoneNumber);
System.out.println("Email: "+mailAddress);
}
}
/** Coworker */
public class Colleague implements Human{
...// (Omitted)
@Override
public void outputContact(){
// (Processing content)
}
}
Inheriting and overriding a method is called Overriding.
final modifier
In Java, final is a modifier that means "this is the end, it's decided." Once a value is assigned to a variable with this modifier, it cannot be changed.
final int constVariable = 100;
constVariable = 50;// Error because you tried to change the value despite it being final
A variable whose value cannot be changed in this way is called a "constant." By convention, they are named using uppercase letters and "_" (underscores).
Why should we create "variables" whose values cannot be changed? It is to make the code easier to understand. For example, suppose you have the following code:
double price = 100 * 1.08;
As of November 2017, you might understand that "it's multiplying by the consumption tax rate," but someone reading this code after the consumption tax rate has changed in the future might not understand why 1.08 is being multiplied.
However, what about the code below?
final double counsumptionTaxRate = 0.08;// Consumption tax rate
double price = 100 * (1 + counsumptionTaxRate);
With this, it's clear that the ".08" part represents the consumption tax rate, making it code that future developers can understand and modify even if the consumption tax rate changes.
static modifier
In Java, static means "static." Unlike fields like name in the Friend class, which are generated "dynamically" (the opposite of "static") for each instance using new, it means the member is common to the class.
For example, if you had the following code in the Friend class,
public class Friend {
public static int hoge = 10;
public static int fuga(){
return 20;
}
// (The rest is omitted)
}
It can be used as common to the class, without needing new (instantiation), as shown below:
Friend yamada = new Friend("Taro Yamada", "03-555-555", "yamada@qmail.com");
Friend suzuki = new Friend("Hanako Suzuki", "03-666-666", "suzuki@qmail.com");
// Common even if the instances are different
yamada.hoge = 30;
System.out.println(yamada.hoge);// 30
System.out.println(suzuki.hoge);// 30
// Can be used without even creating an instance
System.out.println(Friend.hoge);// 30
System.out.println(Friend.fuga());// 20
However... you should avoid using static fields without the final modifier mentioned above. As written in the main article, the advantage of object-oriented programming is that it can be used without knowing the inside of the class. For example, if you write Friend tanaka = new Friend("Ichiro Tanaka", "03-444-444", "tanaka@qmail.com");, you write the code under the assumption that it only holds the data explicitly provided ("Ichiro Tanaka", "03-444-444", "tanaka@qmail.com") and the data processed based on it. However, if a static field exists, it could be rewritten in a completely different place, leading to behavior different from what was assumed, and you would not be able to leverage the advantages of object-oriented programming.
On the other hand, methods should be made static whenever possible. For example, if there is a method to check whether a phone number is in the correct format ("xxx-xxxx-xxxx" (sequence of numbers and hyphens)) using regular expressions, making it static informs the reader that it "does not depend on a specific person (instance)," which avoids unnecessary confusion.
public class Friend {
...// (Omitted)
public static boolean isValidPhoneNumber(String phoneNumber){
Pattern p = Pattern.compile("^[0-9]+-[0-9]+-[0-9]+$");
Matcher m = p.matcher(phoneNumber);
return m.matches();
}
}
System.out.println(Friend.isValidPhoneNumber("03-444-444"));// true because the format is correct
System.out.println(Friend.isValidPhoneNumber("03-44a-444"));// false because it's a typo
Although I wrote above that static fields that are not final should not be used, defining common constants for the class as static final is recommended because it improves readability.
public class Friend {
...// (Omitted)
/** Phone number format */
private static final Pattern PHONE_NUMBER_PATTERN = Pattern.compile("^[0-9]+-[0-9]+-[0-9]+$");
public static boolean isValidPhoneNumber(String phoneNumber){
Matcher m = PHONE_NUMBER_PATTERN.matcher(phoneNumber);
return m.matches();
}
}
Discussion