Before explaining the interface, the abstract class is a concept that cannot be bypassed. The interface can be considered as a class that is more abstract than the abstract class.
What is an abstract class? "A class that contains one or more abstract methods is an abstract class, and an abstract method is a method without a method body." , both abstract methods and abstract classes must be declared as abstract
. For example:
<code>// 抽象类<br>public abstract class Person {<br> // 抽象方法<br> public abstract String getDescription();<br>}</code>
Remember! "In addition to abstract methods, abstract classes can also contain concrete data and concrete methods". For example, the abstract class Person
also saves the name and a specific method that returns the name:
<code>public abstract class Person{<br> private String name;<br> public Person(String name){<br> this.name = name ;<br> }<br> public abstract String getDescription();<br> public String getName(){<br> return name;<br> }<br>}</code>
❝Many programmers will "wrongly" think that, Concrete methods cannot be included in abstract classes. In fact, this is also the difference between interfaces and abstract classes. Interfaces cannot contain specific methods.
❞
「Abstract class cannot be instantiated」. In other words, if a class is declared as abstract
, objects of this class cannot be created.
<code>new Person("Jack"); // Error</code>
You can define an object variable of an abstract class, but it can only refer to objects of non-abstract subclasses. Assume that the Student
class is a non-abstract subclass of Person
:
<code>Person p = new Student("Jack"); // Right</code>
The so-called non-abstract subclass means that if you create a subclass that inherits the abstract class and Create an object, then"Must provide method definitions for all abstract methods of the parent class". If you don't do this (you can choose not to do it), the subclass will still be an abstract class, and the compiler will force us to add the abstract
keyword to the new class.
The following defines the specific subclass of the extended abstract class Person
Student
:
<code>public class Student extends Person { <br> private String major; <br> public Student(String name, String major) { <br> super(name); <br> this.major = major; <br> } <br> @Override<br> public String getDescription(){ // 实现父类抽象方法<br> return "a student majoring in " + major; <br> } <br>} </code>
implements the parent class in the Student
class Abstract method getDescription
in the class. Therefore, "All methods in the Student
class are non-abstract, and this class is no longer an abstract class".
???? The call is as follows:
<code>Person p = new Student("Jack","Computer Science");<br>p.getDescription();<br></code>
Since the object of the abstract class Person
cannot be constructed, the variable p
will never be referenced Person
object, but refers to specific subclass objects such as Student
, and the getDescription
method is overridden in these objects.
The essence of an interface is actually a class, and it is a class that is more abstract than an abstract class. how to say? Abstract classes can contain specific methods, but interfaces eliminate this possibility. "Before Java 8, interfaces were very pure and could only contain abstract methods, that is, methods without method bodies". There have been some changes in the interface in Java 8, and the interface has begun to be allowed to contain default methods and static methods, which will be explained below.
Java uses the keyword interface
instead of class
to create interfaces. Like classes, we usually add the public
keyword before the keyword interface
, otherwise the interface only has package access rights, and it can only be used under the package with the same interface.
<code>public interface Concept {<br> void idea1();<br> void idea2();<br>}</code>
Similarly, since there is an abstract method in the interface, it needs to be extended (inherited). Use the implements
keyword to make a class extend a specific interface (or a group of interfaces). In layman's terms: the interface is just the appearance. Now this extended subclass needs to explain how it works.
<code>class Implementation implements Concept {<br> @Override<br> public void idea1() {<br> System.out.println("idea1");<br> }<br> <br> @Override<br> public void idea2() {<br> System.out.println("idea2");<br> }<br>}<br></code>
It should be noted here that you can choose to explicitly declare the methods in the interface as public
, but even if you don’t do this, they are public
of". So when implementing an interface, methods from the interface must be defined as public
. Otherwise, they only have package access, so when inherited, their accessibility is reduced, which is not allowed by the Java compiler.
In addition, constants are allowed in the interface. Just like the methods in the interface are automatically set to public
, the fields in the interface will be automatically set. It is a public static final
type", for example:
<code>public interface Concept {<br> void idea1(); // public void idea1();<br> // 静态属性<br> double item = 95; // a public static final constant<br>}</code>
❝You can mark the interface method as
❞public
and the field aspublic static final
. Some programmers are willing to do this out of habit or to improve clarity. However, the Java language specification "recommends not to write these redundant keywords".
The difference between interfaces and classes is that we cannot use the new
operator like a class Instantiate an interface" :
<code>x = new Concept(. . .); // ERROR</code>
The reason is also very simple. The interface does not even have a specific construction method, so it must not be instantiated.
Of course, although the object of the interface cannot be constructed, it is still possible to declare the variables of the interface:
<code>Concept x; // OK</code>
接口变量必须引用实现了接口的类对象:
<code>x = new Implementation(. . .); // OK provided Implementation implements Concept</code>
接下来, 如同使用 instanceof
检查一个对象是否属于某个特定类一样, 也可以使用 instanceof
检查一个对象是否实现了某个特定的接口:
<code>if(x instanceof Concept){<br> ...<br>}</code>
另外,与可以建立类的继承关系一样,「接口也可以被继承」:
<code>public interface Concept1 {<br> void idea1();<br> void idea2();<br>}<br><br>-------------------------------------------<br> <br>public interface Concept2 extends Concept1{<br> double idea3();<br>}</code>
当然,读到这里大家可能依然无法理解,既然有了抽象类,为什么 Java 程序设计语言还要不辞辛苦地引入接口这个概念?
很重磅!因为「一个类可以实现多个接口,但是一个类只能继承一个父类」。正是接口的出现打破了 Java 这种单继承的局限,为定义类的行为提供了极大的灵活性。
<code>class Implementation implements Concept1, Concept2 // OK</code>
有一条实际经验:在合理的范围内尽可能地抽象。显然,接口比抽象类还要抽象。因此,一般更倾向使用接口而不是抽象类。
上文提过一嘴,「在 Java 8 中,允许在接口中增加静态方法和默认方法」。理论上讲,没有任何理由认为这是不合法的,只是这有违于将接口作为抽象规范的初衷。举个例子:
<code>public interface Concept {<br> // 静态方法<br> public static void get(String name){<br> System.out.println("hello " + name);<br> }<br> // 默认方法<br> default void idea1(){<br> System.out.println("this is idea1");<br> };<br>}</code>
用 default
修饰符标记的方法就是默认方法,这样子类就不需要去实现这个方法了。
不过,引入默认方法后,就出现了一个「默认方法冲突」的问题。如果先在一个接口 A 中将一个方法 idea
定义为默认方法, 然后又在另一个接口 B 或者超类 C 中定义了同样的方法 idea
,然后类 D 实现了这两个接口 A 和 B(或超类 C)。于是类 D 中就有了方法 idea
的两个默认实现,出现了冲突,为此,Java 制定了一套规则来解决这个二义性问题:
1 ) 「超类优先」。如果超类提供了一个具体方法,接口中的同名且有相同参数类型的默认方法会被忽略。
2 ) 「接口冲突」。如果一个父类接口提供了一个默认方法,另一个父类接口也提供了一个同名而且参数类型相同的方法,子类必须覆盖这个方法来解决冲突。例如:
<code>interface A {<br> default void idea(){<br> System.out.println("this is A");<br> }<br>}<br><br>interface B {<br> default void idea(){<br> System.out.println("this is B");<br> }<br>}<br><br>// 需要在 D 类中覆盖 idea 方法<br>class D implements A, B{<br> public void getName(){<br> System.out.println("this is D");<br> }<br>}</code>
现在假设 B
接口没有为 idea
提供默认实现:
<code>interface B {<br> void idea();<br>}</code>
那么 D 类会直接从 A 接口继承默认方法吗?这好像挺有道理, 不过,Java 设计者更强调一致性。两个接口如何冲突并不重要,「只要有一个接口提供了一个默认实现,编译器就会报告错误, 我们就必须解决这个二义性」。
当然,如果两个接口都没有为共享方法提供默认实现, 那么就与 Java 8 之前的情况一样,这里不存在冲突。
在我自己早期学习编程的时候,对接口存在的意义实在困惑,我自己乱写代码的时候基本上不可能意识到需要去写接口,不知道接口到底有什么用,为什么要定义接口,感觉定义接口只是提前做了个多余的工作。
其实不是,定义接口并非多余,「接口是用来提供公用的方法,规定子类的行为的」。举个例子,让大家直观的感受下接口的作用:
比如有个网站, 需要保存不同客户的信息, 有些客户从 Web 网站来, 有些客户从手机客户端来, 有些客户直接从后台管理系统录入。假设不同来源的客户有不同的处理业务流程, 这个时候我们定义接口来提供一个保存客户信息的方法,然后不同的平台实现我们这个保存客户信息的接口,以后保存客户信息的话, 我们只需要知道这个接口就可以了,具体调用的方法被封装成了黑盒子,这也就是 Java 的多态的体现,「接口帮助我们对这些有相同功能的方法做了统一管理」。
The above is the detailed content of What is the role of interfaces in Java?. For more information, please follow other related articles on the PHP Chinese website!