Java面试题
郭旭升 Lv6

继承

  • 访问权限
  • 接口与抽象类
  • super
  • 重写与重载

抽象类

抽象类 和抽象方法 需要用abstract 关键字声明。 抽象类一般包含抽象方法。
抽象类和一般类的区别在于抽象类不能被实例化。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public abstract class AbstractClassExample {

protected int x;
private int y;

public abstract void func1();

public void func2() {
System.out.println("func2");
}
}

public class AbstractExtendClassExample extends AbstractClassExample {
@Override
public void func1() {
System.out.println("func1");
}
}

// AbstractClassExample ac1 = new AbstractClassExample(); // 'AbstractClassExample' is abstract; cannot be instantiated
AbstractClassExample ac2 = new AbstractExtendClassExample();
ac2.func1();

使用抽象类:

  1. 需要多个相关的类中共享代码。
  2. 需要能控制继承来的成员的访问权限,并不都是public。
  3. 需要继承非静态和非常量字段。

接口

接口是完全抽象的类,在 Java8之前, 就是不能有任何的方法实现
在Java 8开始,接口可以拥有默认的方法实现,因为不支持默认方法的接口维护成本太高了。

接口的成员(字段+方法)都是默认public,并且不允许定义为Private 或 protected。

接口的字段默认都是 static 和 final 的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
public interface InterfaceExample {
void func1();

default void func2(){
System.out.println("func2");
}

int x = 123;
// int y; // Variable 'y' might not have been initialized
public int z = 0; // Modifier 'public' is redundant for interface fields
// private int k = 0; // Modifier 'private' not allowed here
// protected int l = 0; // Modifier 'protected' not allowed here
// private void fun3(); // Modifier 'private' not allowed here
}

public class InterfaceImplementExample implements InterfaceExample {
@Override
public void func1() {
System.out.println("func1");
}
}

// InterfaceExample ie1 = new InterfaceExample(); // 'InterfaceExample' is abstract; cannot be instantiated
InterfaceExample ie2 = new InterfaceImplementExample();
ie2.func1();
System.out.println(InterfaceExample.x);

使用接口

  1. 需要让不相关的类都实现一个方法,例如不相关的类都实现Comparable接口中的compareTo();
  2. 想要确定特定数据类型的行为,但是不关心谁实现这个行为。
  3. 需要使用多重继承。

抽象类与接口区别

使用上来说,一个类可以实现多个接口,但是不能继承多个抽象类。
接口的字段 只能是static 和final类型,抽象类没有限制。
接口成员只能是public,抽象类成员可以有多种访问权限。

选择:
很多时候,接口优于抽象类,因为接口没有抽象类严格的类层级结构要求,可以灵活为一个类添加行为。 并且从Java8开始,接口也可以有默认的方法实现,使得修改接口的成本很低。

重载和重写

重写(override)
发生在继承关系中,子类实现父类方法声明完全相同的方法。
为了满足里氏替换原则有两个限制:

  • 子类方法的访问权限必须大于等于父类方法。
  • 子类方法的返回类型必须是父类返回类型或者其子类型。

使用@Override注解,可以让编译器帮忙检查是否满足以上两个条件。

重载(overload)
存在于同一个类中, 一个方法与已经存在的方法名称上相同,但是参数类型、个数和顺序至少有一个不同。
但是 返回值不同,其他都相同不算重载。

 Comments