一. Java抽象类
在面向对象的概念中,所有的对象都是通过类来描绘的,但是反过来,并不是所有的类都可以用来描绘对象。如果一个类中没用足够的信息用来实例化对象,那么这个类就叫做抽象类。
抽象类必须被继承才能被使用。
抽象类除了不能实例化之外,类的其他功能依然存在。
1.1 抽象类
使用abstract来定义抽象类:
[可见度] abstract class 类名{
}
1.2 继承抽象类
我们能通过一般的方法来继承抽象类,即使用extends关键字:
public class Salary extends Employee
1.3 抽象方法
- 抽象方法的实现由子类完成。
- 使用关键字abstract来声明抽象方法。
- 抽象方法没有方法体,方法名后面直接跟分号,而不是花括号。
public abstract class Employee
{
private String name;
private String address;
private int number;
public abstract double computePay();
//其余代码
}
声明抽象方法会造成以下两个结果:
- 如果一个类拥有抽象方法,那么该类必须是抽象类。
- 子类必须重写父类的抽象方法,除非子类自身也是抽象类
二. Java接口(Interface)
接口在Java中是一种抽象类型,是抽象方法的集合。
一个类通过继承接口的方式,从而来继承接口的抽象方法。
接口与类相似点:
- 一个接口可以拥有多个方法;
- 接口保存在 .java结尾的文件中,文件名使用接口名;
- 接口相应的字节码文件必须在与包名称相匹配的目录结构中。
接口与类的区别
- 接口支持多继承;
- 接口没有构造方法;
- 接口不能用于实例化对象;
- 接口中的方法全部为抽象方法;
- 接口不是被类继承了,而是要被类实现;
- 接口不能包含成员变量,除了 static 和 final 变量。
2.1 接口的声明
使用关键字interface
来声明接口:
[可见度] interface 接口名 [extends 其他接口名]{
//声明变量
//抽象方法
}
接口特性
- 接口中每一个方法也是隐式抽象的,接口中的方法会被隐式的指定为 public abstract(只能是 public abstract,其他修饰符都会报错)。
- 接口中可以含有变量,但是接口中的变量会被隐式的指定为 public static final 变量(并且只能是 public,用 private 修饰会报编译错误)。
- 接口中的方法是不能在接口中实现的,只能由实现接口的类来实现接口中的方法。
实例
interface Animal {
public void eat();
public void travel();
}
2.2 接口的实现
当类实现接口的时候,类要实现接口中所有的方法。否则,类必须声明为抽象的类。
类使用implements
关键字来实现接口,implements关键字放在类名后面。
...implements 接口名称 [,其他接口名称,...]
实例
public class ImpDemo implements Animal{
public void eat{
System.out.println("can eat");
}
public void travel{
System.out.println("can travel");
}
public static void main(String[] args){
ImpDemo imp = new ImpDemo();
imp.eat;
imp.travel;
}
}
2.3 接口的多继承
在Java中,类的多继承是不合法,但接口允许多继承。
在接口的多继承中extends关键字只需要使用一次,在其后跟着继承接口。 如下所示:
public interface Hockey extends Sports, Event
以上的程序片段是合法定义的子接口,与类不同的是,接口允许多继承,而 Sports及 Event 可能定义或是继承相同的方法
三. Java 多态
多态是同一个行为具有多个不同表现形式或形态的能力。
多态就是同一个接口,使用不同的实例而执行不同操作。
多态的优点
- 消除类型之间的耦合关系
- 可替换性
- 可扩充性
- 接口性
- 灵活性
- 简化性
多态存在的三个必要条件
- 继承
- 重写
- 父类引用指向子类对象
多态的实现方式
- 重写
- 接口
- 抽象类和抽象方法
实例
public class Test {
public static void main(String[] args) {
show(new Cat()); // 以 Cat 对象调用 show 方法
show(new Dog()); // 以 Dog 对象调用 show 方法
Animal a = new Cat(); // 向上转型
a.eat(); // 调用的是 Cat 的 eat
Cat c = (Cat)a; // 向下转型
c.work(); // 调用的是 Cat 的 work
}
public static void show(Animal a) {
a.eat();
// 类型判断
if (a instanceof Cat) { // 猫做的事情
Cat c = (Cat)a;
c.work();
} else if (a instanceof Dog) { // 狗做的事情
Dog c = (Dog)a;
c.work();
}
}
}
abstract class Animal {
abstract void eat();
}
class Cat extends Animal {
public void eat() {
System.out.println("吃鱼");
}
public void work() {
System.out.println("抓老鼠");
}
}
class Dog extends Animal {
public void eat() {
System.out.println("吃骨头");
}
public void work() {
System.out.println("看家");
}
}
运行结果
吃鱼
抓老鼠
吃骨头
看家
吃鱼
抓老鼠