抽象类
为什么要有抽象类?
我曾经也想过为什么要有抽象类,普通的类和子类不就能够完成任务了吗,但是后来明白,父类里面的方法实现很多都没有用,都在子类里面重写了,那父类里面的代码岂不是冗余了。
反过来思考,抽象类把一些具有相同属性和方法的组件进行抽象,这样更有利于代码和程序的维护。
规矩点说就是:抽象类为所有子类提供了一个通用模板,子类可以在这个模板基础上进行扩展。通过抽象类,可以避免子类设计的随意性;通过抽象类,我们就可以做到严格限制子类的设计,使子类之间更加通用。
- 关键字:abstract
例如以下的形式
public abstract class Person
{
}
抽象类具有以下特点
- 抽象方法只有声明,没有定义体,只能被继承
- 包含了抽象方法的类一定是抽象类
- 抽象类也可以有普通方法,可以没有抽象方法
- 抽象类不能被实例化
- 它的子类要么写为抽象类,要么实现抽象类中所有的抽象方法
- 它可以有属性,方法,构造器(构造器不能是抽象)
有如下简单的例子
/**
* 抽象类测试
*
*/
public abstract class Animal { //抽象类
String str;
public Animal() { //抽象类可以有构造器
System.out.println("创建一个动物");
}
public abstract void run(); //抽象方法不能有方法体
public void breath() { //一般方法
System.out.println("呼吸");
run();
}
}
/*子类*/
class Cat extends Animal{
public Cat(){
System.out.println("创建一只猫");
}
@Override
public void run(){
System.out.println("猫步小跑");
}
}
class Dog extends Animal{
@Override
public void run(){
System.out.println("快步跑");
}
}
/*测试*/
public class Test {
public static void main(String[] args) {
Animal a = new Cat(); //new后边不能是抽象类,但可以作为一个类型
a.breath(); //对象类的方法优先级大于父类
a.run();
}
}
输出结果:
创建一个动物
创建一只猫
呼吸
猫步小跑
猫步小跑
接口(interface)
- 简单明了地说一下接口,就是比抽象类还抽象的类
- 注意:接口里面的方法声明时可以不用加public,因为它是多余的; java中接口的方法默认是 public abstract
- 关键字:interface,替代class,但编译时生成的还是class文件
接口的特点
- 不能有非抽象的方法
- 接口不能有构造器
- 接口默认声明为public,不能加其他的
- 接口不能运行,没有main
- 接口可以集成一个或多个其他接口
- 接口速度比抽象类慢,因为需要时间去寻找在类中实现的方法
- 往接口中添加新方法时,必须改变实现该接口的类(该类必须实现接口中所有的抽象方法)
- 一个类可以实现多个接口
- 接口支持多继承
- 实现接口的关键字:implements
有如下例子:
interface Flyable { //接口1
int MAX_SPEED = 11000;
int MIN_HEIGHT = 1;
void fly();
}
interface Attack{ //接口2
void attack();
}
class Plane implements Flyable{ //继承接口1
@Override
public void fly() { //实现抽象方法,下同
System.out.println("飞机依靠发动机在飞");
}
}
class Man implements Flyable{ //继承接口1
@Override
public void fly() {
System.out.println("跳起来,飞");
}
}
class Stone implements Flyable,Attack{ //多继承,继承接口1,2
@Override
public void fly() {
System.out.println("被人扔出去,飞");
}
@Override
public void attack() {
System.out.println("石头,攻击");
}
/*测试*/
public class Test {
public static void main(String[] args) {
Flyable f = new Stone(); //虽然接口1Flyable不能被实现,但仍可以做对象f的类型
//构造属于子类Stone的对象f
f.fly(); //此处直接调用的是Stone中的fly()
}
}
运行结果:
被人扔出去,飞