[JAVA] What is object-oriented after all or just one thing to watch out for in programming

Introduction

If you're studying programming, you've probably heard the term object-oriented once. But this object-oriented, old-fashioned and still used by a lot of people, I don't know what it means. Looking at a certain page, it says that it has elements of "encapsulation," "inheritance," and "polymorphism." But object-oriented advocates say messaging. [Wikipedia](https://ja.wikipedia.org/wiki/%E3%82%AA%E3%83%96%E3%82%B8%E3%82%A7%E3%82%AF%E3%83 % 88% E6% 8C% 87% E5% 90% 91% E3% 83% 97% E3% 83% AD% E3% 82% B0% E3% 83% A9% E3% 83% 9F% E3% 83% B3 Even if you look at% E3% 82% B0), it is not clear that the background continues for a long time and there are many types.

After all, I think that many people have a vague understanding that the following variables and methods are solidified (for those who are completely new to it, Supplement) Please read first).

public class SandBox {
    int hoge = 10;
    int fuga = 20;
    
    int foo(){
        return hoge;
    }
    int bar(){
        return fuga;
    }
}

However, after continuing programming for both hobbies and business, I realized that object-oriented programming, or "programming should be XX", exists for ** one purpose **. If you know that, programming techniques such as object-oriented programming and "let's give a descriptive variable name" will be introduced immediately.

Readable code

When I started programming as a hobby, I didn't understand why I needed to make object-oriented programming. I also understood the notes such as "Let's give a variable name that is easy to understand", but I didn't think it was important. In fact, you don't need these if they are short and your own programs. For example, if you want to rename files in a folder at once (add [read] at the beginning), this code is sufficient.

File a = new File("C:\\Users\\admin\\Documents\\ss");
for(File f : a.listFiles()){
    File b = new File(a, "[Already read]"+f.getName());
    f.renameTo(b);
}

You don't have to bother to create an object. You don't even have to give it a descriptive variable name. It's just a hassle to do that because you only have to use it once and know yourself.

The reason why object-oriented programming and variable naming are so controversial is that it targets programs that are developed by a large number of people for a long period of time. Business-developed programs are created by a large number of people in a large company and can be adjusted over the years. That's why the code needs to be loosely coupled (discussed below) so that other people can read and understand the code so that changes don't affect the unexpected. If you think "I'm just making it by myself as a hobby, it doesn't matter", that's a mistake, and after half a year I'll forget the meaning of the code I wrote in the past, so I need to write it in an easy-to-understand and loosely coupled manner. there is.

In short, programming techniques such as object-oriented and "let's name variables that are easy to understand" are for ** "writing code that is easy for others (including myself in the future) to read and write" **.

So what is object-oriented?

To explain in my own way, what is object-oriented? ** Create a group (class) of data and functions while observing rules such as encapsulation in order to "write code that is easy for others (including yourself in the future) to read and write". That is **. I don't think this is all, so let's take a look at Java's ArrayList class as an example.

List<String> list = new ArrayList<String>();
list.add("C");
list.add("A");
System.out.println(list.get(0));//C

Even if you don't know Java (if you understand English), you can read this code and you will understand that "I added" C "and" A "to the list to get the 0th element." It's important to know what the code means without looking at the contents of the class like this **, and that's why everything I'll explain below. Because a program made by a large company can have millions of lines in some cases, so it is impossible to grasp all the code (and of course, it is desirable that even a small program has less code to grasp). )is.

Encapsulation

The most important object-oriented feature is encapsulation. This means "visualize only the parts that the user needs to use and hide the rest." In terms of programming language, it is to set ** public ** and ** private ** appropriately. For example, the ArrayList class actually has methods such as ensureCapacityInternal () and grow () inside and performs complicated processing, but since it is not related to the side that uses the list, it is private (private) and add ( ) And get () are only public methods used by users. This makes ArrayList a safe class that you can easily use without knowing the inside.

To put it more simply, for example, a calculator. Do you know what the electronics inside the calculator look like? Most people don't know that. But anyone can use the calculator. This is because the internal electronic circuits are private and the buttons and display screens are public. What if the calculator wasn't covered by a case and the electronics were exposed? If you are extremely familiar with electronic circuits, you may be able to modify it to make it your own special calculator. However, it is incomprehensible to most people, and it is Sekiyama that can cause problems by accidentally touching it. Therefore, only the part that accepts external operations is made public (public), and the parts that should not be touched, such as electronic circuits, are made private (private). This is ** encapsulation **. If you dare to write a calculator like a program, it will look like this.

public class Calculator{
    /**Button "1" is public*/
    public void button1(){
        //processing
    }
    /**Button "2" is public*/
    public void button2(){
        //processing
    }
    
    ...//Continued below
    
    /**Internal calculation processing is private (private)*/
    private double calculate(){
        //processing
    }
    
    /**Display of results is public*/
    public double showResult(){
        //processing
    }
}

Thinking this way, we can see that "encapsulation" is universally present in our daily lives. You can operate the TV without knowing what kind of signal the TV remote control is sending. You can drive a car without knowing the blueprint of the engine. Even if you do not know the details of the year-end adjustment, you can get the year-end adjustment by submitting the documents to the accounting department. By creating a black box like this, "You can know what to do and what kind of result will be returned without knowing the inside", you can live in a complicated society, and even a large-scale program can be easily understood. It becomes. At the beginning, I mentioned that object-oriented advocates say "messaging", but outsiders just send "messages" and receive the returned "messages" ** without knowing the inside. ** It's important to be able to program.

Tight and loosely coupled

The strong connection between each element is the tight connection, and the weak connection is the loose connection. In general, it is better to group tightly coupled items into classes and loosely connect them. For example, what if the calculator class had a code for date calculation? Some people may think, "It's better to have a class that can do anything!", But date calculation is quite different from normal numerical calculation, such as calculating the date separately and considering the leap year. I will. Therefore, if there is a code for date calculation in the calculator class, methods and variables unrelated to each other will appear when editing the inside of the class, which will be confusing. The same applies to the user. It's better to divide it into a calculator class and a date calculation class. And make the classes loosely coupled. For example, if the state of the calculator class affects the behavior of the date calculation class, it may affect the date calculation class even though you just intended to fix the calculator class, and an unexpected bug may appear. .. If you really want to change the behavior of the date calculation class depending on the state of the calculator class, create a method to get the necessary parameters from the calculator class, and create a method to receive it in the date calculation class to "visualize" the cooperation.

Polymorphism (polymorphism)

Polymorphism is that the outer surface is the same and the internal processing can be changed in various ways. For example, consider a TV remote control. Various companies such as Sharp and Panasonic make TVs, and the remote control has different internal electronic circuits, but they have the same channel switching button and volume up / down button, and the operation is the same. In this way, it is ** polymorphism ** that the external aspect of "what kind of function it has" can be shared even if the internal implementation is different. If you write the remote control like a program, the following [interface](https://qiita.com/lamrongol/items/74f62fcbea9cf7e96c4d#%E3%82%A4%E3%83%B3%E3%82% BF% E3% 83% BC% E3% 83% 95% E3% 82% A7% E3% 83% BC% E3% 82% B9 interface).

public interface RemoteController{
    public void channel1();
    public void channel2();
    ...//Continued below
    public void volumeUp();
    public void volumeDown();
    ...//Continued below
}

If you do this, the writer will be told, "You can change the internal implementation, but promise to have such a function," and the user can use it as a remote control regardless of which manufacturer it is. In a concrete program, for example, Java's ArrayList class and HashSet class have quite different elements, but since they both inherit the Collection interface, ** the iterator () method regardless of the internal implementation. You can see that you can get the elements in order with.

By the way, if you are doing object-oriented programming, you may think "I understand interface inheritance, but what about class inheritance?", But class inheritance behaves unexpectedly without knowing the details of the parent class. As the hierarchy gets deeper, variables are scattered in multiple layers and it becomes difficult to follow them, and variables with the same name are duplicated and confused, so it is better not to use it much. In fact, Java creators also say that class inheritance (extends) should be avoided as much as possible ).

Practical edition

Now let's do some simple object-oriented programming based on the above. The language is Java, but I will write it so that even those who do not know Java can understand it. What we make is a program that calculates the "period". For example, if you work "2 months 18 days" and then "1 month 4 days", you will get a total of "3 months 22 days". However, 30 days is converted to 1 month. In other words, if you work "1 month 24 days" and "3 months 15 days", the total is "4 months 39 days", but 30 days is converted to 1 month, so subtract 30 from the number of days and add 1 to the month. , "5 months 9 days" is output.

If you write a program without object orientation, it will be as follows.

int monthNum = 0;
int dayNum = 0;

//Work 24 days a month
monthNum = monthNum + 1;
dayNum = dayNum + 24;
////Convert 30 days to 1 month
monthNum = monthNum + dayNum/30;
dayNum = dayNum%30;

//Work 3 months 15 days
monthNum = monthNum + 3;
dayNum = dayNum + 15;
////Convert 30 days to 1 month
monthNum = monthNum + dayNum/30;
dayNum = dayNum%30;

System.out.println((monthNum/12)+"Year"+(monthNum%12)+"months"+dayNum+"Day");//0Year5months9Day          

You can still do the math, but the code is cluttered and you may get bugs with copypemis. So let's use the Duration (meaning "duration") class and make the following code.

Duration durationSum = new Duration(0, 0);

//Work 24 days a month
Duration duration1 = new Duration(1, 24);
durationSum.add(duration1);

//Work 3 months 15 days
Duration duration2 = new Duration(3, 15);
durationSum.add(duration2);

//Automatically toString()Is called
System.out.println(durationSum);//0 years 5 months 9 days

How about that. I think it's a neat code that you can understand just by reading (if you understand English). The Duration class itself looks like this:

Duration.java


/**"Period" class. DAY_OF_MONTH days are automatically converted to 1 month*/
public class Duration {
  /**Number of days to consider as one month*/
  public static final int DAY_OF_MONTH = 30;  
  
  //Make it private so that users cannot change it without permission
  private int monthNum;//Number of months
  private int dayNum;//Days
  
  /**monthNum month dayNum day*/
  public Duration(int monthNum, int dayNum){
	//DAY_OF_MONTH day is converted to 1 month
	this.monthNum = monthNum + dayNum/DAY_OF_MONTH;
	this.dayNum = dayNum % DAY_OF_MONTH;
  }

  public void add(Duration duration){
	this.monthNum = this.monthNum + duration.getMonthNum();
	this.dayNum = this.dayNum + duration.getDayNum();

	//DAY_OF_MONTH day is converted to 1 month
	this.monthNum = this.monthNum + this.dayNum/DAY_OF_MONTH;
	this.dayNum = this.dayNum % DAY_OF_MONTH;
  }

  //Make it public so that users can not set it but can get it
  public int getMonthNum(){
	return monthNum;
  }
  public int getDayNum(){
	return dayNum;
  }
  
  @Override
  public String toString(){
	  return (monthNum/12)+"Year"+(monthNum%12)+"months"+dayNum+"Day";
  }
}

I wrote it in the code, but I will add explanations. First of all, since it is a class that represents the period, it holds the monthNum, dayNum fields to hold months and days, but in the constructor and ʻadd ()method, even ifdayNumexceeds 30, it is held. It is controlled to automatically convert to one month. Therefore, it is private (private) so that the user does not break this control and arbitrarily put more than 30 numbers indayNum. On the other hand, the getMonthNum ()andgetDayNum ()methods are public (** encapsulation **) because the acquisition itself can be free. Next, since "the number of days considered to be one month" is fixed at 30 days regardless of the period,DAY_OF_MONTHis [final](https://qiita.com/lamrongol/items/74f62fcbea9cf7e96c4d#final%E4%BF % AE% E9% A3% BE% E5% AD% 90) in [static](https://qiita.com/lamrongol/items/74f62fcbea9cf7e96c4d#static%E4%BF%AE%E9%A3% BE% E5% AD% 90). And I want to let users know how many days are converted to one month, so I make it public. Finally, it implements thetoString ()method. In Java, every class inherits from the Object class, andtoString ()is the method it has. By implementing this, even the class you created will be displayed in ** debug mode ** orSystem.out.println (obj);so that it is easy for humans to see. The methodtoString ()` is a kind of ** polymorphism ** because the implementation is different depending on the class because it is common and how to display it.

Finally

As I wrote at the beginning, the important thing in programming is ** "write code that is easy for others (including myself in the future) to read and write" **. When learning programming techniques or writing programs, not limited to object-oriented programming, think "Is it really easy for others (including yourself in the future) to read and modify?"

Recommended Posts

What is object-oriented after all or just one thing to watch out for in programming
What is object-oriented after all?
What is object-oriented after all?
Things to watch out for in Java equals
What is object-oriented programming? ~ Beginners ~
Gradle settings memo (multi-project to all in one) for myself
An introduction to functional programming for object-oriented programmers in Elm
What happened to the typical changes in Apache Wicket 8 after all?
What is a snippet in programming?
[For programming beginners] What is a method?
Watch out for embedded variables in S2Dao
Eclipse Pleiades All in One for Mac released
After all, what is [rails db: migrate] doing?
What to do when Address already in use is displayed after executing rails s