抽象类
“作为派生其它类的基类,而不是用来构造特定的实例。在抽象类中可以定义抽象方法(没有{}具体的实现)和具体的方法(有{}具体的实现),只要包含抽象方法的类,必须被声明为抽象类。如果父类是抽象类,那么子类必须覆盖所有在父类中的抽象方法,否则子类也将成为一个抽象类”
建议:尽量将通用的字段和方法(不管是否抽象的)放在超类(不管是否抽象类)中
//声明抽象类
public abstract class 类名 {
[public] [abstract] [返回类型] 方法名();
}
//继承抽象类覆写抽象方法
public class 抽象类名 extends 类名 {
[public] [返回类型] [抽象方法名]() {
//具体实现
}
}
interface接口
“这种技术主要用来描述类具有什么功能,而并不给出每个功能的具体实现。一个类可以实现( implement)—个或多个接口,并在需要接口的地方, 随时使用实现了相应接口的对象。在 Java 程序设计语言中, 接口不是类,而是对类的一组需求描述,这些类要遵从接口描述的统一格式进行定义”
接口定义:
[修饰符] interface 接口名 [extends 父接口名列表]{
[public] [static] [final] 常量; //全局常量
[public] [abstract] 方法; //抽象方法
}
/*接口中不能包含实例域或静态方法,接口中的域将被自动设置为public static final
*可以将接口方法标记为public,将域标记为public static final,java规范建议不必书写
*多余的关键字
*/
例:
public interface Comparable
{
int compareTo(Object other);
}
//任何实现Comparable接口的类都需要包含compareTo方法
//并且此方法参数必须是一个Object对象
为了让类实现一个接口, 通常需要下面两个步骤:
1 ) 将类声明为实现给定的接口。
2 ) 对接口中的所有方法进行定义。
要将类声明为实现某个接口, 需要使用关键字 implements:
class Employee iipleients Comparable
接口中的所有方法都自动地是 public
API | 方法 | 描述 |
---|---|---|
java.lang.Comparable |
int compareTo(T other) | 用这个对象与 other 进行比较。如果这个对象小于 other 则返回负值; 如果相等则返回0;否则返回正值 |
java.util.Arrays 1.2 | static void sort( Object[] a ) | 使用 mergesort 算法对数组 a 中的元素进行排序。要求数组中的元素必须属于实现了Comparable 接口的类, 并且元素之间必须是可比较的 |
java.lang.lnteger 1.0 | static int comparednt x , int y) | 如果 x < y 返回一个负整数;如果 x 和 y 相等,则返回 0; 否则返回一个负整数 |
java.lang.Double 1.0 | static int compare(double x , double y) | 如果 x < y 返回一个负数;如果 x 和 y 相等则返回 0; 否则返回一个负数 |
“每个类只能够拥有一个超类,但却可以实现多个接口”
class Employee implements Cloneable, Comparable {}
静态方法:在 Java SE 8 中,允许在接口中增加静态方法。
默认方法:可以为接口方法提供一个默认实现。 必须用 default 修饰符标记这样一个方法
解决默认方法冲突:
如果先在一个接口中将一个方法定义为默认方法, 然后又在超类或另一个接口中定义了同样的方法,优先级是怎样?
1. 超类优先。如果超类提供了一个具体方法,同名而且有相同参数类型的默认方法会被忽略
2.接口冲突。 如果一个超接口提供了一个默认方法,另一个接口提供了一个同名而且参数类型(不论是否是默认参数)相同的方法, 必须覆盖这个方法来解决冲突
//接口冲突 例:
interface Named
{
default String getName() { return getClass() .getName() + "_" + hashCodeO ; }
}
如果有一个类同时实现了这两个接口会怎么样呢?
class Student implements Person, Named {}
/*类会继承 Person 和 Named 接口提供的两个不一致的 getName 方法。并不是从中选择一
*个,Java 编译器会报告一个错误,让程序员来解决这个二义性。只需要在 Student 类中提供
*一个 getName 方法。在这个方法中,可以选择两个冲突方法中的一个,如下所示:
*/
class Student implements Person, Named
{
public String getName () { return Person.super.getName(); }
}
现在假设 Named 接口没有为 getName 提供默认实现:
interface Named
{
String getNameO;
}
/*注释:如果两个接口都没有为共享方法提供默认实现那么就与 Java SE 8之前的情况一样,这里不存在冲突
*实现类可以有两个选择:实现这个方法,或者干脆不实现。如果是后一种情况,这个类本身就是抽象的
*/
超类与接口中的方法冲突优先级(类优先):只会考虑超类方法,接口所有默认方法都会被忽略
**