Do you understand the difference between abstract classes and interfaces? Also, do you understand and master it?
Even if you ask a lot of seniors or look it up online ... ** Interface if you want to define the type as a class specification ** ** Abstract class if you have an inheritance relationship and want to reuse processing ** Will be returned. I already know it, I think I understand it, but I can't master it.
So how do you understand and master it? ** You should understand the essence (why it has such specifications?), Not the difference on the surface ** This article is a compilation of my research.
In conclusion, ** abstract classes are inherited and are used when you want to reuse processing **.
The "inheritance" relationship between an abstract class and a concrete class is said to be a ** IS A relationship **. ** Dog IS A Animal ** = ** Dog is an animal ** It is a parent-child relationship. So let's write the common actions (processes) that dogs and humans have in the animal class (abstract class)! Is said to be. Once summarized, ** write abstractly what every child can do in an abstract class, and write concrete things that only that child can do ** in a concrete class **
Let's write a sample code using the above as an example. Now, if you think abstractly about abstract classes, animals have names. And at night you can sleep, eat and talk.
Since all animals have the same sleeping behavior, they are implemented in a common abstract class. (Don't say that you sleep differently) You can eat and talk, but the specifics vary from animal to animal, so define it as an abstract method.
Animal.java
public abstract class Animal {
String name;
public Animal(String name){
this.name = name;
}
public void sleep(){
System.out.println("sleep");
}
public abstract void speak();
public abstract void eat();
}
Since the way dogs speak and eat is different, we will implement it concretely in the concrete class.
Dog.java
public class Dog extends Animal{
public Dog(String name){
super(name);
}
@Override
public void speak() {
System.out.println("my name is"+name+"Dawan! !!");
}
@Override
public void eat() {
System.out.println("Gab Gab Gab");
}
}
Humans also implement speaking and eating concretely in the concrete class.
Human.java
public class Human extends Animal{
public Human(String name) {
super(name);
}
@Override
public void speak() {
System.out.println("Nice to meet you, my name is"+name+"is.");
}
@Override
public void eat() {
System.out.println("Mogumogu");
}
}
Class to call the created class
Main.java
public class Main {
public static void main(String[] arg){
Human tarou = new Human("Taro");
Dog pochi = new Dog("Pochi");
System.out.println("****Taro's processing****");
tarou.sleep();
tarou.eat();
tarou.speak();
System.out.println("****Pochi processing****");
pochi.sleep();
pochi.eat();
pochi.speak();
}
}
/*Output result
****Taro's processing****
sleep
Mogumogu
Nice to meet you, my name is Taro.
****Pochi processing****
sleep
Gab Gab Gab
My name is Pochi One! !!
*/
In conclusion, ** interface is a type definition as a class specification **.
First of all, the meaning of the word of the interface is "standards and specifications for connecting computers and peripheral devices, or operation methods and concepts for users to use computers, etc. In hardware, standards for connectors that connect devices to each other. Refers to. " To put it more simply, it is ** a window that connects something that can be seen from the outside **.
And the relationship between the interface and the "implementation" of the implementation class is said to be the ** CAN DO relationship **. ** Cash register CAN bill Credit card ** = ** Cash register can accept credit card. It's a relationship like **. In addition, the cash register can also be used for cash accounting. Therefore, what is defined in the interface is that cash register can be done and only accounting is defined. From another point of view, it's like ** defining that you can register from the outside without being aware of it. Then, * the clerk who uses the cash register should be able to just do the accounting without thinking about what kind of accounting it is **.
Let's write a sample code using the above as an example. Only what can be done (= accounting) is defined in the cashier interface, and the clerk class who uses the cashier executes only accounting. Credit and cash accounting implement the accounting defined in the interface.
Define the accounting method in the cashier interface.
Cashier.java
public interface Cashier {
public void bill();
}
Implement the interface and implement the details of credit accounting.
CreditCard.java
public class CreditCard implements Cashier{
@Override
public void bill() {
System.out.println("We will pay by credit card.");
}
}
Implement the interface and implement the cash accounting details.
Cash.java
public class Cash implements Cashier{
@Override
public void bill() {
System.out.println("We will pay in cash.");
}
}
The clerk then pays for the cash register. Since I am calling Cashier # bill at this time, I wonder if this is cash accounting or credit accounting You can use it without being aware of it.
Staff.java
public class Staff {
public static void main(String[] arg) {
Cashier cash = new Cash();
Cashier credit = new CreditCard();
System.out.println("***Cash support***");
cash.bill();
System.out.println("***Credit support***");
credit.bill();
}
}
So far, we've outlined the abstract classes and interfaces. We will consider it in more depth from now on, but let's organize it here first. What is an abstract class? The "inheritance" relationship between the abstract class and the concrete class is the ** IS A relationship **, which summarizes what children can do abstractly in the parent class.
What is an interface? The relationship between the "implementation" of the interface and the implementation class is ** CAN DO relationship **, and only what can be defined in the interface is defined, and the specifics are left to the implementation class. So the user doesn't have to worry about the details implemented inside.
In my opinion, abstract classes and interfaces are basically used (or will be used) together. I think that I use an interface, define functions that can be used ** from outside, and use abstract classes to organize common processing inside **. This will be explained in detail later in "Access Modifiers".
To understand the essence from here ** Why is it such a specification? We will dig deeper from the perspective of **. First, let's summarize the differences between abstract classes and interfaces.
f | Abstract class | interface |
---|---|---|
Access modifier | public,protected | public only |
Variable definition | You can define instance variables, local variables, and class variables. | Only public static final constants (class variables) can be held. It cannot be overwritten by the inherited destination. |
Inheritance | Multiple inheritance not possible | Multiple inheritance possible |
Method definition | Apply specific processing | Only method types can be defined. From java8, it is also processed using the default method. |
The interface is public only. Abstract classes can only define public and protected. You can call publicly defined methods from anywhere! In that sense, Methods defined in protected can only be called from within that package! It means that.
This means that public methods are for calling from the outside → for those who use it outside → ** the interface defines methods for those who use it **.
So protected methods can only be used inside a package → for those who use it inside → ** abstract classes are for those who use it inside **.
Since the interface is for ** outside users **, only public methods can be defined. Abstract classes are for ** people who use them in **, so even protected can be defined.
Multiple inheritance is ** inheriting multiple parent classes **. Abstract classes do not allow multiple inheritance by design, but interfaces do. The diamond inheritance problem is often cited as an example of multiple inheritance.
Considering the problems caused by multiple inheritance (it seems to be called Mix-In), the following can be mentioned. -Name resolution problem due to duplicate method names Or method name of ClassB and ClassC is to have either because it is the same in ClassD? Or should it be implemented? ・ Problems caused by inheriting classes multiple times Since both ClassB and ClassC inherit ClassA, ClassD inherits ClassA twice.
Because abstract classes can be instantiated (actual, the feeling of making the methods that abstract classes have !?) This problem occurs. So it is not allowed in the specifications. Then what about the interface? There is a rule to solve these two problems. -Method call The method closest to the class is called -If the method call priority cannot be determined or becomes the same, an override is prompted as a compile error. -Interface cannot be instantiated (The method written in the interface is not instantiated because it is only linked to the actual situation.)
Abstract classes have specifications that cannot be inherited multiple times because problems such as name resolution occur when they are instantiated. Interfaces cannot be instantiated, they are only ** inside the instance as "interfaces" **, so multiple inheritance is possible. Here Was very helpful.
This is because the interface cannot be instantiated as mentioned during multiple inheritance. It just prevents you from having instance variables. To put it the other way around, having an instance variable causes problems.
Since problems occur due to multiple inheritance, the specifications are such that only ** public static final constants ** can be held.
First, let ’s talk about the default method. The default method is ** a method that implements specific processing contents that can be defined in the interface **. This eliminates the need to override and describe the method's processing in the class it implements.
I think this raises questions. The difference between an abstract class and an interface has disappeared. .. .. It seems that the background created in the first place is completely different when I investigate.
From java8, you can use Stream API.
Looking at the List interface, the default method actually existed.
default void replaceAll(UnaryOperator<E> operator) {
Objects.requireNonNull(operator);
final ListIterator<E> li = this.listIterator();
while (li.hasNext()) {
li.set(operator.apply(li.next()));
}
}
The default method of the interface is a method created for compatibility between java7 and java8. So I found out that it is completely different from the abstract class because it is not for grouping common processes.
It turns out that abstract classes and interfaces may be similar in what they can do, but the backgrounds and specifications created are quite different. The abstract class is in ** for those who use it to organize common processes **, The interface was a completely different thing in ** for external users **, defining what you can do without showing details.
As an aside, as I actually wrote the article, I deepened my understanding and realized that there were many cases where I was actually used incorrectly. If you have any questions or concerns, please comment.
Recommended Posts